1 import types
.Types
.MalType
;
9 static function READ(str
:String
):MalType
{
10 return Reader
.read_str(str
);
14 static function eval_ast(ast
:MalType
, env
:Env
) {
16 case MalSymbol(s
): env
.get(ast
);
18 MalList(l
.map(function(x
) { return EVAL(x
, env
); }));
20 MalVector(l
.map(function(x
) { return EVAL(x
, env
); }));
22 var new_map
= new Map
<String
,MalType
>();
24 new_map
[k
] = EVAL(m
[k
], env
);
31 static function EVAL(ast
:MalType
, env
:Env
):MalType
{
32 if (!list_Q(ast
)) { return eval_ast(ast
, env
); }
35 var alst
= switch (ast
) { case MalList(lst
): lst
; case _
: []; }
38 case MalSymbol("def!"):
39 return env
.set(alst
[1], EVAL(alst
[2], env
));
40 case MalSymbol("let*"):
41 var let_env
= new Env(env
);
43 case MalList(l
) |
MalVector(l
):
44 for (i
in 0...l
.length
) {
45 if ((i
%2) > 0) { continue; }
46 let_env
.set(l
[i
], EVAL(l
[i
+1], let_env
));
48 case _
: throw "Invalid let*";
50 return EVAL(alst
[2], let_env
);
52 var el
= eval_ast(ast
, env
);
55 case MalFunc(f
,_
,_
,_
,_
,_
): return f(_list(el
).slice(1));
56 case _
: throw "Call of non-function";
62 static function PRINT(exp
:MalType
):String
{
63 return Printer
.pr_str(exp
, true);
67 static function NumOp(op
):MalType
{
68 return MalFunc(function(args
:Array
<MalType
>) {
69 return switch (args
) {
70 case [MalInt(a
), MalInt(b
)]: MalInt(op(a
,b
));
71 case _
: throw "Invalid numeric op call";
74 },null,null,null,false,nil
);
76 static var repl_env
= new Env(null);
78 static function rep(line
:String
):String
{
79 return PRINT(EVAL(READ(line
), repl_env
));
82 public static function main() {
84 #error
"JS not supported yet"
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 a
*b
;}));
89 repl_env
.set(MalSymbol("/"), NumOp(function(a
,b
) {return Std
.int(a
/b
);}));
93 var line
= Sys
.stdin().readLine();
94 if (line
== "") { continue; }
95 Sys
.println(rep(line
));
96 } catch (exc
:BlankLine
) {
98 } catch (exc
:haxe
.io
.Eof
) {
100 } catch (exc
:Dynamic) {