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 }
45 return [eval_ast
$ast $env]
47 lassign
[obj_val
$ast] a0 a1 a2 a3
48 switch [obj_val
$a0] {
50 set varname
[obj_val
$a1]
51 set value
[EVAL
$a2 $env]
52 return [$env set $varname $value]
55 set letenv
[Env new
$env]
56 set bindings_list
[obj_val
$a1]
57 foreach {varnameobj varvalobj
} $bindings_list {
58 $letenv set [obj_val
$varnameobj] [EVAL
$varvalobj $letenv]
60 return [EVAL
$a2 $letenv]
63 set el
[list_new
[lrange [obj_val
$ast] 1 end-1
]]
65 return [EVAL
[lindex [obj_val
$ast] end
] $env]
68 set condval
[EVAL
$a1 $env]
69 if {[false_q
$condval] ||
[nil_q
$condval]} {
73 return [EVAL
$a3 $env]
75 return [EVAL
$a2 $env]
79 foreach v
[obj_val
$a1] {
80 lappend binds
[obj_val
$v]
82 return [function_new
$a2 $env $binds]
85 set lst_obj
[eval_ast
$ast $env]
86 set lst
[obj_val
$lst_obj]
88 set call_args
[lrange $lst 1 end
]
89 switch [obj_type
$f] {
91 set funcdict
[obj_val
$f]
92 set body
[dict get
$funcdict body
]
93 set env
[dict get
$funcdict env
]
94 set binds
[dict get
$funcdict binds
]
95 set funcenv
[Env new
$env $binds $call_args]
96 return [EVAL
$body $funcenv]
99 set body
[concat [list [obj_val
$f]] {$a}]
100 set lambda
[list {a
} $body]
101 return [apply
$lambda $call_args]
104 error "Not a function"
116 PRINT
[EVAL
[READ
$str] $env]
120 EVAL
[READ
$str] $env
123 set repl_env
[Env new
]
124 dict
for {k v
} $core_ns {
128 # core.mal: defined using the language itself
129 RE
"(def! not (fn* (a) (if a false true)))" $repl_env
131 fconfigure stdout
-translation binary
134 if { [array names env DEBUG
] != "" && $env(DEBUG
) != "0" } {
140 set res
[_readline
"user> "]
141 if {[lindex $res 0] == "EOF"} {
144 set line
[lindex $res 1]
148 if { [catch { puts [REP
$line $repl_env] } exception
] } {
149 puts "Error: $exception"