Fix unescaping in matlab, miniMAL and rpython.
[jackhill/mal.git] / vimscript / step3_env.vim
1 source readline.vim
2 source types.vim
3 source reader.vim
4 source printer.vim
5 source env.vim
6
7 function READ(str)
8 return ReadStr(a:str)
9 endfunction
10
11 function EvalAst(ast, env)
12 if SymbolQ(a:ast)
13 let varname = a:ast.val
14 return a:env.get(varname)
15 elseif ListQ(a:ast)
16 return ListNew(map(copy(a:ast.val), {_, e -> EVAL(e, a:env)}))
17 elseif VectorQ(a:ast)
18 return VectorNew(map(copy(a:ast.val), {_, e -> EVAL(e, a:env)}))
19 elseif HashQ(a:ast)
20 let ret = {}
21 for [k,v] in items(a:ast.val)
22 let keyobj = HashParseKey(k)
23 let newkey = EVAL(keyobj, a:env)
24 let newval = EVAL(v, a:env)
25 let keystring = HashMakeKey(newkey)
26 let ret[keystring] = newval
27 endfor
28 return HashNew(ret)
29 else
30 return a:ast
31 end
32 endfunction
33
34 function EVAL(ast, env)
35 if !ListQ(a:ast)
36 return EvalAst(a:ast, a:env)
37 end
38 if EmptyQ(a:ast)
39 return a:ast
40 endif
41
42 let first_symbol = a:ast.val[0].val
43 if first_symbol == "def!"
44 let a1 = a:ast.val[1]
45 let a2 = a:ast.val[2]
46 return a:env.set(a1.val, EVAL(a2, a:env))
47 elseif first_symbol == "let*"
48 let a1 = a:ast.val[1]
49 let a2 = a:ast.val[2]
50 let let_env = NewEnv(a:env)
51 let let_binds = a1.val
52 let i = 0
53 while i < len(let_binds)
54 call let_env.set(let_binds[i].val, EVAL(let_binds[i+1], let_env))
55 let i = i + 2
56 endwhile
57 return EVAL(a2, let_env)
58 else
59 " apply list
60 let el = EvalAst(a:ast, a:env)
61 let Fn = el.val[0]
62 return Fn(el.val[1:-1])
63 endif
64
65 endfunction
66
67 function PRINT(exp)
68 return PrStr(a:exp, 1)
69 endfunction
70
71 function REP(str, env)
72 return PRINT(EVAL(READ(a:str), a:env))
73 endfunction
74
75 let repl_env = NewEnv("")
76 call repl_env.set("+", {a -> IntegerNew(a[0].val + a[1].val)})
77 call repl_env.set("-", {a -> IntegerNew(a[0].val - a[1].val)})
78 call repl_env.set("*", {a -> IntegerNew(a[0].val * a[1].val)})
79 call repl_env.set("/", {a -> IntegerNew(a[0].val / a[1].val)})
80
81 while 1
82 let [eof, line] = Readline("user> ")
83 if eof
84 break
85 endif
86 if line == ""
87 continue
88 endif
89 try
90 call PrintLn(REP(line, repl_env))
91 catch
92 call PrintLn("Error: " . v:exception)
93 endtry
94 endwhile
95 qall!