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) | |
4fbbe571 | 18 | return ListNew(map(copy(a:ast.val), {_, e -> EVAL(e, a:env)})) |
50a964ce | 19 | elseif VectorQ(a:ast) |
4fbbe571 | 20 | return VectorNew(map(copy(a:ast.val), {_, e -> EVAL(e, a:env)})) |
50a964ce DM |
21 | elseif HashQ(a:ast) |
22 | let ret = {} | |
82641edb | 23 | for [k,v] in items(a:ast.val) |
50a964ce DM |
24 | let keyobj = HashParseKey(k) |
25 | let newkey = EVAL(keyobj, a:env) | |
26 | let newval = EVAL(v, a:env) | |
27 | let keystring = HashMakeKey(newkey) | |
28 | let ret[keystring] = newval | |
29 | endfor | |
30 | return HashNew(ret) | |
31 | else | |
32 | return a:ast | |
33 | end | |
34 | endfunction | |
35 | ||
36 | function EVAL(ast, env) | |
37 | if !ListQ(a:ast) | |
38 | return EvalAst(a:ast, a:env) | |
39 | end | |
efa2daef JM |
40 | if EmptyQ(a:ast) |
41 | return a:ast | |
42 | endif | |
50a964ce DM |
43 | |
44 | " apply list | |
45 | let el = EvalAst(a:ast, a:env) | |
46 | ||
82641edb DM |
47 | let Fn = el.val[0] |
48 | return Fn(el.val[1:-1]) | |
50a964ce DM |
49 | endfunction |
50 | ||
51 | function PRINT(exp) | |
52 | return PrStr(a:exp, 1) | |
53 | endfunction | |
54 | ||
55 | function REP(str, env) | |
56 | return PRINT(EVAL(READ(a:str), a:env)) | |
57 | endfunction | |
58 | ||
50a964ce | 59 | let repl_env = {} |
aa62cbda DM |
60 | let repl_env["+"] = {a -> IntegerNew(a[0].val + a[1].val)} |
61 | let repl_env["-"] = {a -> IntegerNew(a[0].val - a[1].val)} | |
62 | let repl_env["*"] = {a -> IntegerNew(a[0].val * a[1].val)} | |
63 | let repl_env["/"] = {a -> IntegerNew(a[0].val / a[1].val)} | |
50a964ce DM |
64 | |
65 | while 1 | |
66 | let [eof, line] = Readline("user> ") | |
67 | if eof | |
68 | break | |
69 | endif | |
70 | if line == "" | |
71 | continue | |
72 | endif | |
73 | try | |
74 | call PrintLn(REP(line, repl_env)) | |
75 | catch | |
76 | call PrintLn("ERROR: " . v:exception) | |
77 | endtry | |
78 | endwhile | |
79 | qall! |