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