4 READ
:= method(str
, MalReader
read_str(str
))
6 eval_ast
:= method(ast
, env
,
8 "MalSymbol", env
get(ast
),
9 "MalList", MalList
with(ast
map(a
, EVAL(a
, env
))),
10 "MalVector", MalVector
with(ast
map(a
, EVAL(a
, env
))),
14 keyObj
:= MalMap
keyToObj(k
)
15 m
atPut(MalMap
objToKey(EVAL(keyObj
, env
)), EVAL(v
, env
))
22 EVAL
:= method(ast
, env
,
23 if(ast
type != "MalList", return(eval_ast(ast
, env
)))
24 if(ast isEmpty
, return ast
)
25 if(ast
at(0) type == "MalSymbol",
28 return(env
set(ast
at(1), EVAL(ast
at(2), env
))),
30 return(eval_ast(ast rest
, env
) last
),
32 return(EVAL(if(EVAL(ast
at(1), env
), ast
at(2), ast
at(3)), env
)),
34 return(block(a
, EVAL(ast
at(2), Env
with(env
, ast
at(1), a
)))),
36 letEnv
:= Env
with(env
)
38 ast
at(1) foreach(i
, e
,
41 letEnv
set(varName
, EVAL(e
, letEnv
))
44 return(EVAL(ast
at(2), letEnv
))
49 el
:= eval_ast(ast
, env
)
55 PRINT
:= method(exp
, exp
malPrint(true
))
57 RE
:= method(str
, EVAL(READ(str
), repl_env
))
59 REP
:= method(str
, PRINT(RE(str
)))
61 repl_env
:= Env
with(nil
)
62 MalCore NS
foreach(k
, v
, repl_env
set(MalSymbol
with(k
), v
))
64 // core
.mal
: defined using the language itself
65 RE("(def! not (fn* (a) (if a false true)))")
68 line
:= MalReadline
readLine("user> ")
70 if(line isEmpty
, continue)
71 e
:= try(REP(line
) println
)
73 ("Error: " .. (e error
)) println