matlab: add keyword, vector, hash-map support.
[jackhill/mal.git] / matlab / step2_eval.m
1 function step2_eval(varargin), main(varargin), end
2
3 % read
4 function ret = READ(str)
5 ret = reader.read_str(str);
6 end
7
8 % eval
9 function ret = eval_ast(ast, env)
10 switch class(ast)
11 case 'types.Symbol'
12 ret = env(ast.name);
13 case 'types.List'
14 ret = types.List();
15 for i=1:length(ast)
16 ret.append(EVAL(ast.get(i), env));
17 end
18 case 'types.Vector'
19 ret = types.Vector();
20 for i=1:length(ast)
21 ret.append(EVAL(ast.get(i), env));
22 end
23 case 'types.HashMap'
24 ret = types.HashMap();
25 ks = ast.keys();
26 for i=1:length(ks)
27 k = ks{i};
28 ret.set(EVAL(k, env), EVAL(ast.get(k), env));
29 end
30 otherwise
31 ret = ast;
32 end
33 end
34
35 function ret = EVAL(ast, env)
36 if ~types.list_Q(ast)
37 ret = eval_ast(ast, env);
38 return;
39 end
40
41 % apply
42 el = eval_ast(ast, env);
43 f = el.get(1);
44 args = el.data(2:end);
45 ret = f(args{:});
46 end
47
48 % print
49 function ret = PRINT(ast)
50 ret = printer.pr_str(ast, true);
51 end
52
53 % REPL
54 function ret = rep(str, env)
55 ret = PRINT(EVAL(READ(str), env));
56 end
57
58 function main(args)
59 repl_env = containers.Map();
60 repl_env('+') = @(a,b) a+b;
61 repl_env('-') = @(a,b) a-b;
62 repl_env('*') = @(a,b) a*b;
63 repl_env('/') = @(a,b) floor(a/b);
64
65 %cleanObj = onCleanup(@() disp('*** here1 ***'));
66 while (true)
67 line = input('user> ', 's');
68 if strcmp(strtrim(line),''), continue, end
69 try
70 fprintf('%s\n', rep(line, repl_env));
71 catch err
72 fprintf('Error: %s\n', err.message);
73 fprintf('%s\n', getReport(err, 'extended'));
74 end
75 end
76 end