Implement step A
[jackhill/mal.git] / matlab / step3_env.m
CommitLineData
ab6e6fae
JM
1function step3_env(varargin), main(varargin), end
2
3% read
4function ret = READ(str)
5 ret = reader.read_str(str);
6end
7
8% eval
9function ret = eval_ast(ast, env)
10 switch class(ast)
11 case 'types.Symbol'
12 ret = env.get(ast);
6a572dff
JM
13 case 'types.List'
14 ret = types.List();
ab6e6fae 15 for i=1:length(ast)
6a572dff
JM
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));
ab6e6fae
JM
29 end
30 otherwise
31 ret = ast;
32 end
33end
34
35function ret = EVAL(ast, env)
0b234e13 36 %fprintf('EVAL: %s\n', printer.pr_str(ast, true));
47699629 37 if ~type_utils.list_Q(ast)
ab6e6fae
JM
38 ret = eval_ast(ast, env);
39 return;
40 end
41
42 % apply
9870acb6
JM
43 if length(ast) == 0
44 ret = ast;
45 return;
46 end
6a572dff
JM
47 if isa(ast.get(1),'types.Symbol')
48 a1sym = ast.get(1).name;
ab6e6fae
JM
49 else
50 a1sym = '_@$fn$@_';
51 end
52 switch (a1sym)
53 case 'def!'
6a572dff 54 ret = env.set(ast.get(2), EVAL(ast.get(3), env));
ab6e6fae 55 case 'let*'
47699629 56 let_env = Env({env});
6a572dff
JM
57 for i=1:2:length(ast.get(2))
58 let_env.set(ast.get(2).get(i), EVAL(ast.get(2).get(i+1), let_env));
ab6e6fae 59 end
6a572dff 60 ret = EVAL(ast.get(3), let_env);
ab6e6fae
JM
61 otherwise
62 el = eval_ast(ast, env);
6a572dff
JM
63 f = el.get(1);
64 args = el.data(2:end);
ab6e6fae
JM
65 ret = f(args{:});
66 end
67end
68
69% print
70function ret = PRINT(ast)
71 ret = printer.pr_str(ast, true);
72end
73
74% REPL
75function ret = rep(str, env)
76 ret = PRINT(EVAL(READ(str), env));
77end
78
79function main(args)
47699629 80 repl_env = Env();
ab6e6fae
JM
81 repl_env.set(types.Symbol('+'), @(a,b) a+b);
82 repl_env.set(types.Symbol('-'), @(a,b) a-b);
83 repl_env.set(types.Symbol('*'), @(a,b) a*b);
84 repl_env.set(types.Symbol('/'), @(a,b) floor(a/b));
85
86 %cleanObj = onCleanup(@() disp('*** here1 ***'));
87 while (true)
47699629
JM
88 try
89 line = input('user> ', 's');
90 catch err
91 return
92 end
ab6e6fae
JM
93 if strcmp(strtrim(line),''), continue, end
94 try
95 fprintf('%s\n', rep(line, repl_env));
96 catch err
97 fprintf('Error: %s\n', err.message);
47699629 98 type_utils.print_stack(err);
ab6e6fae
JM
99 end
100 end
101end