-
Notifications
You must be signed in to change notification settings - Fork 0
/
l4u_obj.gleam
91 lines (88 loc) · 2.95 KB
/
l4u_obj.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import gleam/io
import gleam/list
import gleam/dict
import gleam/string
import gleam/regex
import gleam/result
import gleam/int
import gleam/float
import gleam/option
import gleam/order
import l4u/sys_bridge.{
type Pid, catch_ex, console_readline, console_writeln, dbgout1, dbgout2,
dbgout3, deref, do_async, exec, internal_form, load_file, make_ref,
new_process, reset_ref, throw_err, throw_expr, unique_pdic,
}
@target(javascript)
import gleam/javascript/promise
import l4u/l4u_core as l4u
import l4u/l4u_core.{
description, dump_env, env_set_global, env_set_local, eval, inspect,
main as do_repl, make_new_l4u_core_env, print, pstr, read, rep, repl, show,
to_l4u_bool, tokenize, trace_set_last_funcall, uneval,
}
import l4u/l4u_type.{
type Env, type Expr, LIST, UNDEFINED, WithEnv, native_false, native_nil,
native_true, native_undefined, to_native_dictionary, unsafe_corece,
}
import gleam_bridge
/// L4uobj is a type that can operate an object that keeps the condition like the so called object oriented language.
pub type L4uObj {
L4uObj(
/// Name of this L4uObj.
name: String,
/// PID of the process where EVAL is executed.
pid: Pid,
/// Get the current environment of the L4uObj.
get_env: fn() -> Env,
/// Evaluate the given list of s-expressions in the environment
eval: fn(List(Expr)) -> Result(Expr, String),
/// Read the given string and return the list of s-expressions.
read: fn(String) -> Result(List(Expr), String),
/// Print the given s-expression and return the string representation.
print: fn(Expr) -> String,
)
}
@external(erlang, "l4u@process", "get_env")
@external(javascript, "../l4u_sys_bridge_ffi.mjs", "process_get_env")
pub fn process_get_env(pid: Pid) -> Env
pub fn generate_new_l4u_obj(name: String, initializer: fn() -> Env) -> L4uObj {
let assert Ok(pid) = new_process(initializer)
L4uObj(
name: name,
pid: pid,
get_env: fn() -> Env { process_get_env(pid) },
eval: fn(exprs: List(Expr)) -> Result(Expr, String) {
//dbgout2("### l4u_obj: eval", exprs)
let f = fn(env: Env) {
//dbgout2("####### l4u_obj: eval: env", env)
let assert WithEnv(rexpr, new_env) = eval(exprs, UNDEFINED, env)
}
case exec(pid, f) {
Ok(expr) -> Ok(expr)
//Error(err) -> Error("???err")
Error(err) -> {
//dbgout2("l4u_obj: eval: error", err)
Error(err)
}
}
},
read: fn(s: String) -> Result(List(Expr), String) {
let f = fn(env: Env) {
//dbgout2("####### l4u_obj: read: ", s)
let exprs = read(s, env)
//dbgout2("####### l4u_obj: read: -> ", exprs)
WithEnv(LIST(exprs), env)
}
case exec(pid, f) {
Ok(LIST(rexprs)) -> Ok(rexprs)
Error(err) -> Error(err)
unhandable -> {
throw_err("unhandable exec error in l4u_obj: read")
Error("unhandable")
}
}
},
print: fn(expr: Expr) -> String { print(expr) },
)
}