Commit | Line | Data |
---|---|---|
50a964ce DM |
1 | source readline.vim |
2 | source types.vim | |
3 | source reader.vim | |
4 | source printer.vim | |
5 | ||
6 | function READ(str) | |
7 | return ReadStr(a:str) | |
8 | endfunction | |
9 | ||
10 | function EvalAst(ast, env) | |
11 | if SymbolQ(a:ast) | |
82641edb | 12 | let varname = a:ast.val |
50a964ce DM |
13 | if !has_key(a:env, varname) |
14 | throw "'" . varname . "' not found" | |
15 | end | |
16 | return a:env[varname] | |
17 | elseif ListQ(a:ast) | |
18 | let ret = [] | |
82641edb | 19 | for e in a:ast.val |
50a964ce DM |
20 | call add(ret, EVAL(e, a:env)) |
21 | endfor | |
22 | return ListNew(ret) | |
23 | elseif VectorQ(a:ast) | |
24 | let ret = [] | |
82641edb | 25 | for e in a:ast.val |
50a964ce DM |
26 | call add(ret, EVAL(e, a:env)) |
27 | endfor | |
28 | return VectorNew(ret) | |
29 | elseif HashQ(a:ast) | |
30 | let ret = {} | |
82641edb | 31 | for [k,v] in items(a:ast.val) |
50a964ce DM |
32 | let keyobj = HashParseKey(k) |
33 | let newkey = EVAL(keyobj, a:env) | |
34 | let newval = EVAL(v, a:env) | |
35 | let keystring = HashMakeKey(newkey) | |
36 | let ret[keystring] = newval | |
37 | endfor | |
38 | return HashNew(ret) | |
39 | else | |
40 | return a:ast | |
41 | end | |
42 | endfunction | |
43 | ||
44 | function EVAL(ast, env) | |
45 | if !ListQ(a:ast) | |
46 | return EvalAst(a:ast, a:env) | |
47 | end | |
efa2daef JM |
48 | if EmptyQ(a:ast) |
49 | return a:ast | |
50 | endif | |
50a964ce DM |
51 | |
52 | " apply list | |
53 | let el = EvalAst(a:ast, a:env) | |
54 | ||
82641edb DM |
55 | let Fn = el.val[0] |
56 | return Fn(el.val[1:-1]) | |
50a964ce DM |
57 | endfunction |
58 | ||
59 | function PRINT(exp) | |
60 | return PrStr(a:exp, 1) | |
61 | endfunction | |
62 | ||
63 | function REP(str, env) | |
64 | return PRINT(EVAL(READ(a:str), a:env)) | |
65 | endfunction | |
66 | ||
50a964ce | 67 | let repl_env = {} |
aa62cbda DM |
68 | let repl_env["+"] = {a -> IntegerNew(a[0].val + a[1].val)} |
69 | let repl_env["-"] = {a -> IntegerNew(a[0].val - a[1].val)} | |
70 | let repl_env["*"] = {a -> IntegerNew(a[0].val * a[1].val)} | |
71 | let repl_env["/"] = {a -> IntegerNew(a[0].val / a[1].val)} | |
50a964ce DM |
72 | |
73 | while 1 | |
74 | let [eof, line] = Readline("user> ") | |
75 | if eof | |
76 | break | |
77 | endif | |
78 | if line == "" | |
79 | continue | |
80 | endif | |
81 | try | |
82 | call PrintLn(REP(line, repl_env)) | |
83 | catch | |
84 | call PrintLn("ERROR: " . v:exception) | |
85 | endtry | |
86 | endwhile | |
87 | qall! |