Commit | Line | Data |
---|---|---|
4eb88ef2 DM |
1 | load "../logo/readline.lg |
2 | load "../logo/reader.lg | |
3 | load "../logo/printer.lg | |
4 | load "../logo/types.lg | |
5 | ||
6 | to _read :str | |
7 | output read_str :str | |
8 | end | |
9 | ||
10 | to eval_ast :ast :env | |
11 | output case (obj_type :ast) [ | |
12 | [[symbol] localmake "val hashmap_get :env :ast | |
13 | if emptyp :val [(throw "error sentence (word "' obj_val :ast "' ) [not found])] | |
14 | :val ] | |
15 | [[list] obj_new "list map [_eval ? :env] obj_val :ast] | |
16 | [[vector] obj_new "vector map [_eval ? :env] obj_val :ast] | |
17 | [[hashmap] obj_new "hashmap map [_eval ? :env] obj_val :ast] | |
18 | [else :ast] | |
19 | ] | |
20 | end | |
21 | ||
22 | to _eval :ast :env | |
23 | if (obj_type :ast) <> "list [output eval_ast :ast :env] | |
24 | if emptyp obj_val :ast [output :ast] | |
25 | make "el obj_val eval_ast :ast :env | |
26 | output apply first :el butfirst :el | |
27 | end | |
28 | ||
29 | to _print :exp | |
30 | output pr_str :exp "true | |
31 | end | |
32 | ||
33 | to rep :str | |
34 | output _print _eval _read :str :repl_env | |
35 | end | |
36 | ||
37 | to mal_add :a :b | |
38 | output obj_new "number ((obj_val :a) + (obj_val :b)) | |
39 | end | |
40 | ||
41 | to mal_sub :a :b | |
42 | output obj_new "number ((obj_val :a) - (obj_val :b)) | |
43 | end | |
44 | ||
45 | to mal_mul :a :b | |
46 | output obj_new "number ((obj_val :a) * (obj_val :b)) | |
47 | end | |
48 | ||
49 | to mal_div :a :b | |
50 | output obj_new "number ((obj_val :a) / (obj_val :b)) | |
51 | end | |
52 | ||
53 | to repl | |
54 | localmake "running "true | |
55 | while [:running] [ | |
56 | localmake "line readline word "user> :space_char | |
57 | ifelse :line=[] [ | |
58 | print " | |
59 | make "running "false | |
60 | ] [ | |
61 | if not emptyp :line [ | |
62 | catch "error [print rep :line] | |
63 | localmake "exception error | |
64 | if not emptyp :exception [ | |
65 | (print "Error: first butfirst :exception) | |
66 | ] | |
67 | ] | |
68 | ] | |
69 | ] | |
70 | end | |
71 | ||
72 | make "repl_env [] | |
73 | make "repl_env hashmap_put :repl_env symbol_new "+ "mal_add | |
74 | make "repl_env hashmap_put :repl_env symbol_new "- "mal_sub | |
75 | make "repl_env hashmap_put :repl_env symbol_new "* "mal_mul | |
76 | make "repl_env hashmap_put :repl_env symbol_new "/ "mal_div | |
77 | repl | |
78 | bye |