DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / pike / step2_eval.pike
CommitLineData
a04e7a78
DM
1import .Printer;
2import .Reader;
3import .Readline;
4import .Types;
5
6Val READ(string str)
7{
8 return read_str(str);
9}
10
11Val eval_ast(Val ast, mapping(string:function) env)
12{
13 switch(ast.mal_type)
14 {
15 case MALTYPE_SYMBOL:
16 function f = env[ast.value];
17 if(!f) throw("'" + ast.value + "' not found");
18 return f;
19 case MALTYPE_LIST:
20 return List(map(ast.data, lambda(Val e) { return EVAL(e, env); }));
21 case MALTYPE_VECTOR:
22 return Vector(map(ast.data, lambda(Val e) { return EVAL(e, env); }));
23 case MALTYPE_MAP:
24 array(Val) elements = ({ });
25 foreach(ast.data; Val k; Val v)
26 {
27 elements += ({ k, EVAL(v, env) });
28 }
29 return Map(elements);
30 default:
31 return ast;
32 }
33}
34
35Val EVAL(Val ast, mapping(string:function) env)
36{
37 if(ast.mal_type != MALTYPE_LIST) return eval_ast(ast, env);
38 if(ast.emptyp()) return ast;
39 Val evaled_ast = eval_ast(ast, env);
40 function f = evaled_ast.data[0];
41 return f(@evaled_ast.data[1..]);
42}
43
44string PRINT(Val exp)
45{
46 return pr_str(exp, true);
47}
48
49string rep(string str, mapping(string:function) env)
50{
51 return PRINT(EVAL(READ(str), env));
52}
53
54int main()
55{
56 mapping(string:function) repl_env = ([
57 "+": lambda(Val a, Val b) { return Number(a.value + b.value); },
58 "-": lambda(Val a, Val b) { return Number(a.value - b.value); },
59 "*": lambda(Val a, Val b) { return Number(a.value * b.value); },
60 "/": lambda(Val a, Val b) { return Number(a.value / b.value); }
61 ]);
62 while(1)
63 {
64 string line = readline("user> ");
65 if(!line) break;
66 if(strlen(line) == 0) continue;
67 if(mixed err = catch { write(({ rep(line, repl_env), "\n" })); } )
68 {
69 if(arrayp(err)) err = err[0];
70 write(({ "Error: ", err, "\n" }));
71 }
72 }
73 write("\n");
74 return 0;
75}