Commit | Line | Data |
---|---|---|
31690700 JM |
1 | Step Notes: |
2 | ||
3 | - step0_repl | |
4 | - prompt, input, READ, EVAL, PRINT, output | |
5 | - readline module | |
6 | - display prompt, read line of input | |
7 | ||
8 | - use native eval in EVAL if available | |
9 | ||
10 | - libedit/GNU readline: | |
11 | - use existing lib, wrap shell call or implement | |
12 | - load history file on first call | |
13 | - add non-blank lines to history | |
14 | - append to history file | |
15 | ||
16 | - step1_read_print | |
17 | - types module: | |
18 | - add boxed types if no language equivalent: | |
19 | - nil, true, false, symbol, integer, string, list | |
31690700 JM |
20 | - reader module: |
21 | - stateful reader object | |
22 | - alternative: mutate token list | |
1b4a9012 | 23 | - tokenize (if regex available) |
31690700 JM |
24 | - standard regex pattern: "/[\s,]*(~@|[\[\]{}()'`~^@]|\"(?:\\.|[^\\\"])*\"|;.*|[^\s\[\]{}('\"`,;)]*)/" |
25 | - read_str | |
26 | - read_form(new Reader(tokenize(str))) | |
27 | - read_form | |
28 | - detect errors | |
29 | - call read_list or read_atom | |
30 | - read_list | |
31 | - read_form until ')' | |
32 | - return array (boxed) | |
a3b0621d | 33 | - read_atom (not atom type) |
31690700 JM |
34 | - return scalar boxed type: |
35 | - nil, true, false, symbol, integer, string | |
53beaa0a JM |
36 | - printer module: |
37 | - _pr_str: | |
38 | - stringify boxed types to their Mal representations | |
39 | - list/array is recursive | |
aef93ea3 JM |
40 | - repl loop |
41 | - catch errors, print them and continue | |
42 | - impls without exception handling will need to have a global | |
43 | variable with checks for it at the beginning of critical | |
44 | code sections | |
31690700 | 45 | |
9af8aee6 JM |
46 | - comments |
47 | ||
31690700 JM |
48 | - vectors |
49 | - Basically: two array types that retain their boxed types, can be | |
50 | challenging depending on the language (e.g. JS, PHP: no clean | |
51 | way to derive new array types). | |
52 | - types module: | |
53 | - add vector boxed type | |
54 | - derived from array if possible | |
55 | - pr_str: | |
56 | - vector is recursive | |
57 | - sequential? | |
58 | - reader module: | |
59 | - read_vector: | |
60 | - re-use read_list but with different constructor, delims | |
61 | ||
62 | - hash-maps | |
63 | - reader module: | |
64 | - re-use read_list function and apply that using hash-map | |
65 | constructor | |
66 | - types module: | |
67 | - pr_str addition | |
68 | - hash-map, map?, assoc, dissoc, get, contains?, keys, | |
69 | vals (probably assoc! and dissoc! for internal) | |
70 | - eval_map: eval the keys and values of hash_maps | |
71 | - EVAL: | |
72 | - if hash_map, call eval_map on it | |
73 | ||
74 | - step2_eval | |
75 | - types module: | |
a3b0621d | 76 | - symbol?, list? (if no simple idiomatic impl type check) |
31690700 JM |
77 | - first, rest, nth on list |
78 | - eval_ast: | |
79 | - if symbol, return value of looking up in env | |
80 | - if list, eval each item, return new list | |
81 | - if vector support, eval each item, return new vector | |
82 | - if hash_map support, eval each value, return new hash_map | |
83 | - otherwise, just return unchanged ast | |
84 | - EVAL/apply: | |
85 | - if not a list, call eval_ast | |
86 | - otherwise, apply first item to eval_ast of (rest ast) | |
87 | - repl_env as simple one level assoc. array (or hash_map) | |
88 | - store function as hash_map value | |
89 | ||
90 | - step3_env | |
91 | - types module: | |
31690700 | 92 | - may need function type if HashMap is strongly typed (e.g. Java) |
a5a66058 JM |
93 | - env type: |
94 | - find, set, get (no binds/exprs in constructor yet) | |
31690700 JM |
95 | - EVAL/apply: |
96 | - def! - mutate current environment | |
97 | - let* - create new environment with bindings | |
31690700 JM |
98 | |
99 | - step4_if_fn_do | |
100 | - types module: | |
a5a66058 JM |
101 | - function type if no closures in impl language |
102 | - _equal_Q function (recursive) | |
103 | - reader module | |
104 | - string unescaping | |
105 | - printer module | |
106 | - print_readably option for pr_str | |
31690700 | 107 | - add function printing to pr_str |
a5a66058 JM |
108 | - string escaping in pr_str |
109 | - core module (export via core_ns): | |
110 | - export equal_Q from types as = | |
111 | - move arith operations here | |
112 | - add arith comparison functions | |
113 | - pr_str, str, prn, println | |
114 | - list, list?, count, empty? | |
115 | - env module: | |
31690700 | 116 | - add binds/exprs handling to Env constructor with variable arity |
31690700 JM |
117 | - EVAL: |
118 | - do: | |
119 | - if: | |
120 | - fn*: | |
121 | - simple if language supports closures | |
aef93ea3 JM |
122 | - otherwise needs a way of representing functions that can |
123 | have associated metadata | |
124 | - define "not" using REP/RE | |
31690700 | 125 | |
31690700 JM |
126 | - step5_tco |
127 | - types module: | |
60f2b363 | 128 | - mal function type: |
31690700 JM |
129 | - stores: func, exp, env, params |
130 | - func is EVAL in native mal case, otherwise reference to | |
131 | platform function | |
132 | - if metadata support, then store exp, env, params as | |
133 | metadata | |
60f2b363 JM |
134 | - printer |
135 | - add printing of mal function type | |
31690700 JM |
136 | - EVAL: |
137 | - while loop around whole thing | |
138 | - cases where we directly return result of EVAL, instead set | |
139 | ast and env to what would be put in the EVAL, then loop. | |
96115d4f JM |
140 | - do, if, "apply" |
141 | - for "apply" case, set env to new Env based on properties | |
31690700 JM |
142 | on the function |
143 | ||
144 | - step6_file | |
074cd748 JM |
145 | - core module: |
146 | - read-string, slurp functions | |
147 | - define eval and load-file functions | |
148 | - set *ARGV* | |
149 | - if files on command line, use load-file to run first argument | |
150 | using rest as arguments | |
31690700 JM |
151 | |
152 | - step7_quote | |
31690700 JM |
153 | - add is_pair and quasiquote functions |
154 | - rewrite ast using cons/concat functions | |
155 | - if vectors, use sequential? instead of list? in is_pair | |
156 | - EVAL: | |
157 | - add 'quote', 'quasiquote' cases | |
074cd748 | 158 | - core module: |
8e7e339d JM |
159 | - add cons and concat functions |
160 | - reader module: | |
161 | - add reader macros to read_form for quote, unquote, | |
162 | splice-unquote and quasiquote | |
31690700 JM |
163 | |
164 | - step8_macros | |
165 | - types module: | |
166 | - add first, rest functions | |
167 | - add is_macro_call and macroexpand | |
168 | - recursively macroexpand lists | |
169 | - if applying a macro function, run it on the ast first before | |
170 | continuing | |
171 | - call macroexpand apply in EVAL | |
172 | - EVAL: | |
173 | - add 'defmacro!' and 'macroexpand' | |
174 | - store ismacro property on function metadata | |
175 | ||
950e3c76 JM |
176 | - step9_interop |
177 | ||
31690700 | 178 | - stepA_more |
074cd748 | 179 | - core module: |
31690700 | 180 | - throw function |
950e3c76 JM |
181 | - apply, map functions: should not directly call EVAL, which |
182 | requires the function object to be runnable | |
074cd748 | 183 | - readline |
31690700 JM |
184 | - EVAL: |
185 | - try*/catch*: for normal exceptions, extracts string | |
186 | otherwise extracts full value | |
074cd748 | 187 | - set and print *host-language* |
9528bb14 JM |
188 | |
189 | - Extra defintions needed for self-hosting | |
190 | - types module: | |
191 | - symbol?, nil?, true?, false?, sequential? (if not already) | |
192 | - first, rest | |
193 | - define cond and or macros using REP/RE | |
194 | ||
195 | - Other misc: | |
196 | - conj function | |
31690700 JM |
197 | |
198 | - atoms | |
199 | - reader module: | |
200 | - @a reader macro -> (deref a) | |
201 | - types module: | |
202 | - pr_str case | |
203 | - atom type, atom, atom?, deref, reset!, swap! | |
204 | ||
205 | - metadata | |
206 | - types module: | |
207 | - support meta property on symbols, hash-maps, lists, vectors, | |
208 | functions, atoms | |
209 | - add with-meta, meta functions | |
210 | - reader module: | |
211 | - ^ reader macro reads ^meta obj -> (with-meta obj meta) |