1 source mal_readline.tcl
12 proc eval_ast
{ast env
} {
13 switch [obj_type
$ast] {
15 set varname
[obj_val
$ast]
16 return [$env get
$varname]
20 foreach element
[obj_val
$ast] {
21 lappend res
[EVAL
$element $env]
23 return [list_new
$res]
27 foreach element
[obj_val
$ast] {
28 lappend res
[EVAL
$element $env]
30 return [vector_new
$res]
34 dict
for {k v
} [obj_val
$ast] {
35 dict
set res
$k [EVAL
$v $env]
37 return [hashmap_new
$res]
39 default { return $ast }
46 return [eval_ast
$ast $env]
48 lassign
[obj_val
$ast] a0 a1 a2 a3
52 switch [obj_val
$a0] {
54 set varname
[obj_val
$a1]
55 set value
[EVAL
$a2 $env]
56 return [$env set $varname $value]
59 set letenv
[Env new
$env]
60 set bindings_list
[obj_val
$a1]
61 foreach {varnameobj varvalobj
} $bindings_list {
62 $letenv set [obj_val
$varnameobj] [EVAL
$varvalobj $letenv]
69 set el
[list_new
[lrange [obj_val
$ast] 1 end-1
]]
71 set ast
[lindex [obj_val
$ast] end
]
75 set condval
[EVAL
$a1 $env]
76 if {[false_q
$condval] ||
[nil_q
$condval]} {
88 foreach v
[obj_val
$a1] {
89 lappend binds
[obj_val
$v]
91 return [function_new
$a2 $env $binds]
94 set lst_obj
[eval_ast
$ast $env]
95 set lst
[obj_val
$lst_obj]
97 set call_args
[lrange $lst 1 end
]
98 switch [obj_type
$f] {
101 set ast
[dict get
$fn body
]
102 set env
[Env new
[dict get
$fn env
] [dict get
$fn binds
] $call_args]
106 set body
[concat [list [obj_val
$f]] {$a}]
107 set lambda
[list {a
} $body]
108 return [apply
$lambda $call_args]
111 error "Not a function"
124 PRINT
[EVAL
[READ
$str] $env]
128 EVAL
[READ
$str] $env
131 set repl_env
[Env new
]
132 dict
for {k v
} $core_ns {
136 # core.mal: defined using the language itself
137 RE
"(def! not (fn* (a) (if a false true)))" $repl_env
139 fconfigure stdout
-translation binary
142 if { [array names env DEBUG
] != "" && $env(DEBUG
) != "0" } {
148 set res
[_readline
"user> "]
149 if {[lindex $res 0] == "EOF"} {
152 set line
[lindex $res 1]
156 if { [catch { puts [REP
$line $repl_env] } exception
] } {
157 puts "Error: $exception"