2 import types
.Types
.MalType
;
10 static function READ(str
:String
):MalType
{
11 return Reader
.read_str(str
);
15 static function eval_ast(ast
:MalType
, env
:Env
) {
17 case MalSymbol(s
): env
.get(ast
);
19 MalList(l
.map(function(x
) { return EVAL(x
, env
); }));
21 MalVector(l
.map(function(x
) { return EVAL(x
, env
); }));
23 var new_map
= new Map
<String
,MalType
>();
25 new_map
[k
] = EVAL(m
[k
], env
);
32 static function EVAL(ast
:MalType
, env
:Env
):MalType
{
33 if (!list_Q(ast
)) { return eval_ast(ast
, env
); }
36 var alst
= switch (ast
) { case MalList(lst
): lst
; case _
: []; }
37 if (alst
.length
== 0) { return ast
; }
40 case MalSymbol("def!"):
41 return env
.set(alst
[1], EVAL(alst
[2], env
));
42 case MalSymbol("let*"):
43 var let_env
= new Env(env
);
45 case MalList(l
) |
MalVector(l
):
46 for (i
in 0...l
.length
) {
47 if ((i
%2) > 0) { continue; }
48 let_env
.set(l
[i
], EVAL(l
[i
+1], let_env
));
50 case _
: throw "Invalid let*";
52 return EVAL(alst
[2], let_env
);
54 var el
= eval_ast(ast
, env
);
57 case MalFunc(f
,_
,_
,_
,_
,_
): return f(_list(el
).slice(1));
58 case _
: throw "Call of non-function";
64 static function PRINT(exp
:MalType
):String
{
65 return Printer
.pr_str(exp
, true);
69 static function NumOp(op
):MalType
{
70 return MalFunc(function(args
:Array
<MalType
>) {
71 return switch (args
) {
72 case [MalInt(a
), MalInt(b
)]: MalInt(op(a
,b
));
73 case _
: throw "Invalid numeric op call";
76 },null,null,null,false,nil
);
78 static var repl_env
= new Env(null);
80 static function rep(line
:String
):String
{
81 return PRINT(EVAL(READ(line
), repl_env
));
84 public static function main() {
85 repl_env
.set(MalSymbol("+"), NumOp(function(a
,b
) {return a
+b
;}));
86 repl_env
.set(MalSymbol("-"), NumOp(function(a
,b
) {return a
-b
;}));
87 repl_env
.set(MalSymbol("*"), NumOp(function(a
,b
) {return a
*b
;}));
88 repl_env
.set(MalSymbol("/"), NumOp(function(a
,b
) {return Std
.int(a
/b
);}));
91 var line
= Compat
.readline("user> ");
92 if (line
== "") { continue; }
93 Compat
.println(rep(line
));
94 } catch (exc
:BlankLine
) {
96 } catch (exc
:haxe
.io
.Eof
) {
98 } catch (exc
:Dynamic) {
99 Compat
.println("Error: " + exc
);