2 // @import types/boxed/*.ck
3 // @import types/MalObject.ck
4 // @import types/mal/MalAtom.ck
5 // @import types/mal/MalError.ck
6 // @import types/mal/MalNil.ck
7 // @import types/mal/MalFalse.ck
8 // @import types/mal/MalTrue.ck
9 // @import types/mal/MalInt.ck
10 // @import types/mal/MalString.ck
11 // @import types/mal/MalSymbol.ck
12 // @import types/mal/MalKeyword.ck
13 // @import types/mal/MalList.ck
14 // @import types/mal/MalVector.ck
15 // @import types/mal/MalHashMap.ck
20 // @import types/MalSubr.ck
21 // @import types/subr/*.ck
23 fun MalObject READ(string input)
25 return Reader.read_str(input);
28 fun MalObject EVAL(MalObject m, MalSubr env[])
30 if( m.type == "list" )
32 if( (m$MalList).value().size() == 0 )
37 eval_ast(m, env) @=> MalObject result;
38 if( result.type == "error" )
43 (result$MalList).value() @=> MalObject values[];
44 values[0]$MalSubr @=> MalSubr subr;
45 MalObject.slice(values, 1) @=> MalObject args[];
47 return subr.call(args);
51 return eval_ast(m, env);
55 fun MalObject eval_ast(MalObject m, MalSubr env[])
57 m.type => string type;
59 if( type == "symbol" )
61 (m$MalSymbol).value() => string symbol;
62 env[symbol] @=> MalSubr subr;
66 return MalError.create(MalString.create("'" + symbol + "' not found"));
73 else if( type == "list" || type == "vector" || type == "hashmap" )
75 (m$MalList).value() @=> MalObject values[];
76 MalObject results[values.size()];
78 if( type != "hashmap" )
80 for( 0 => int i; i < values.size(); i++ )
82 EVAL(values[i], env) @=> MalObject result;
84 if( result.type == "error" )
89 result @=> results[i];
94 for( 0 => int i; i < values.size(); i++ )
98 values[i] @=> results[i];
102 EVAL(values[i], env) @=> results[i];
109 return MalList.create(results);
111 else if( type == "vector" )
113 return MalVector.create(results);
115 else if( type == "hashmap" )
117 return MalHashMap.create(results);
126 fun string PRINT(MalObject m)
128 return Printer.pr_str(m, true);
132 new MalAdd @=> repl_env["+"];
133 new MalSub @=> repl_env["-"];
134 new MalMul @=> repl_env["*"];
135 new MalDiv @=> repl_env["/"];
137 fun string errorMessage(MalObject m)
139 (m$MalError).value() @=> MalObject value;
141 if( value.type == "string" )
143 return Printer.pr_str(value, false);
147 return "exception: " + Printer.pr_str(value, true);
151 fun string rep(string input)
153 READ(input) @=> MalObject m;
155 if( m.type == "error" )
157 return errorMessage(m);
160 EVAL(m, repl_env) @=> MalObject result;
161 if( result.type == "error" )
163 return errorMessage(result);
166 return PRINT(result);
175 Readline.readline("user> ") => string input;
179 rep(input) => string output;
181 if( output == "empty input" )
183 // proceed immediately with prompt
187 Util.println(output);