generate perf analysis
[jackhill/mal.git] / docs / cheatsheet.html
CommitLineData
a15f76bd
JM
1<html>
2<head>
3 <style>
4 h2 {
5 text-align: center;
6 }
7 table {
8 font-size: 11px;
9 border-width: 0px;
10 border-collapse: collapse;
11 }
12 table tr {
13 border: none;
14 }
15 table td,th {
16 border-left: solid 1px #008;
17 }
18 table td:first-child, th:first-child {
19 border-left: none;
20 }
21
22 table td {
23 vertical-align: top;
24 padding: 2px;
25 }
26 pre {
27 background: #FCFCF9;
28 padding: 3px;
29 border-width: 1px;
30 border-style: solid;
31 border-color: lightgrey;
32 }
33
34 .file {
35 font-weight: 700;
36 color: #338833;
37 }
38 .var {
39 font-weight: 700;
40 color: #BB8855;
41 }
42 .function {
43 font-weight: 700;
44 color: #887744;
45 }
46 .object {
47 font-weight: 700;
48 color: #DD7744;
49 }
50 .malsym {
51 font-weight: 600;
52 color: #883333;
53 }
54 .string {
55 font-weight: 400;
56 color: #994444;
57 }
58 </style>
59</head>
60<body>
61 <h2>Make-A-Lisp Cheatsheet</h2>
62 <table align=left>
63 <tr>
64 <th>Step 1</th> <th>Step 6</th>
65 <tr>
66 <td width=50%>
67<!--
68<pre><code><span class=file>step0_repl.EXT</span>:
69 <span class=function>READ</span></span>(<span class=var>ast</span>): passthrough <span class=var>ast</span>
70 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>): passthrough <span class=var>ast</span>
71 <span class=function>PRINT</span>(<span class=var>ast</span>): passthrough <span class=var>ast</span>
72 <span class=function>main</span>(<span class=var>args</span>): loop: <span class=function>writeline</span> <span class=function>PRINT</span>(<span class=function>EVAL</span>(<span class=function>READ</span>(<span class=function>readline</span>()), <span class=string>""</span>))
73
74
75
76
77</code></pre>
78-->
79<pre><code><span class=file>reader.EXT</span>:
80 <span class=object>Reader</span>(<span class=var>tokens</span>) object: <span class=var>position</span>, <span class=function>next</span>(), <span class=function>peek</span>()
81 <span class=function>tokenize</span>: <span class=string>/[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)/</span>
82 <span class=function>read_atom</span>: int, float, string (escaped), keyword, nil, true, false, symbol
83 <span class=function>read_list</span>: repeatedly <span class=function>read_form</span> until end token (<span class=object>EOF</span> is error)
84 <span class=function>read_form</span>: expand reader macros, <span class=function>read_list</span> (vector/maps too), or <span class=function>read_atom</span>
85 <span class=function>read_str</span>: <span class=function>tokenize</span>, error if no tokens, call <span class=function>read_form</span>(<span class=object>Reader</span>(<span class=var>tokens</span>))
86<span class=file>printer.EXT</span>:
87 <span class=function>pr_str</span>(<span class=var>ast</span>, <span class=var>print_readably</span>):
88 - map <span class=function>pr_str</span> across collections
89 - unescape strings if <span class=var>print_readably</span>
90<span class=file>step1_read_print.EXT</span>:
91 <span class=function>main</span>(<span class=var>args</span>): loop: <span class=function>writeline</span> <span class=function>PRINT</span>(<span class=function>EVAL</span>(<span class=function>READ</span>(<span class=function>readline</span>()), <span class=string>""</span>))
92</code></pre>
93 </td>
94 <td width=50%>
95<pre><code><span class=file>core.EXT</span>:
96 <span class=function>read-string</span>: call <span class=function>reader.read_str</span>
97 <span class=function>slurp</span>: return file content as a string
98 <span class=function>atom</span>, <span class=function>atom?</span>, <span class=function>deref</span>, <span class=function>reset!</span>, <span class=function>swap!</span>: atom functions
99<span class=file>step6_file.EXT</span>:
100 <span class=function>main</span>(<span class=var>args</span>):
101 - add <span class=malsym>eval</span> and <span class=malsym>*ARGV*</span> to <span class=var>repl_env</span>
102 - define <span class=malsym>load-file</span> using <span class=function>rep</span>
103 - if <span class=var>args</span>, set <span class=malsym>*ARGV*</span> to rest(<span class=var>args</span>) and call <span class=malsym>load-file</span> with <span class=var>arg</span>s[0]
104
105
106
107
108</code></pre>
109 </td>
110 <tr>
111 <th>&nbsp;</th> <th>&nbsp;</th>
112 <tr>
113 <th>Step 2</th> <th>Step 7</th>
114 <tr>
115 <td width=50%>
116<pre><code><span class=file>step2_eval.EXT</span>:
117 <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>): lookup symbols in <span class=var>env</span>, map <span class=function>EVAL</span> across collections
118 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
119 - if not list?(<span class=var>ast</span>), return <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>)
120 - otherwise apply (<span class=var>ast</span> is a list):
121 <span class=var>el</span> = <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>)
122 return <span class=var>el</span>[0](rest(<span class=var>el</span>))
123 <span class=function>main</span>(<span class=var>args</span>): loop: <span class=function>writeline</span> <span class=function>PRINT</span>(<span class=function>EVAL</span>(<span class=function>READ</span>(<span class=function>readline</span>()), {<span class=malsym>+</span>: <span class=function>add</span>, ...}))
124
125
126
127</code></pre>
128 </td>
129 <td width=50%>
130<pre><code><span class=file>core.EXT</span>:
131 <span class=function>cons</span>, <span class=function>concat</span>: sequence functions
132<span class=file>step7_quote.EXT</span>:
133 <span class=function>quasiquote</span>(ast):
134 - <span class=var>ast</span> is empty or not a list -> (<span class=malsym>quote</span> <span class=var>ast</span>)
135 - (<span class=malsym>unquote</span> FOO) -> FOO
136 - ((<span class=malsym>splice-unquote</span> FOO) BAR..) -> (<span class=malsym>concat</span> FOO <span class=function>quasiquote</span>(BAR...))</span>
137 - (FOO BAR...) -> (<span class=malsym>cons</span> FOO <span class=function>quasiquote</span>(BAR...))</span>
138 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
139 - <span class=malsym>quote</span> -> return <span class=var>ast</span>[1]
140 - <span class=malsym>quasiquote</span> -> set <span class=var>ast</span> to <span class=function>quasiquote</span>(<span class=var>ast</span>[1]), loop
141</code></pre>
142 </td>
143 <tr>
144 <th>&nbsp;</th> <th>&nbsp;</th>
145 <tr>
146 <th>Step 3</th> <th>Step 8</th>
147 <tr>
148 <td width=50%>
149<pre><code><span class=file>env.EXT</span>:
150 <span class=object>Env</span>(<span class=var>outer</span>) object: <span class=var>data</span>, <span class=function>set</span>(<span class=var>k</span>, <span class=var>v</span>), <span class=function>find</span>(<span class=var>k</span>), <span class=function>get</span>(<span class=var>k</span>)
151<span class=file>step3_env.EXT</span>:
152 <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>): switch to <span class=var>env</span>.<span class=function>get</span> for symbol lookup
153 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
154 - <span class=malsym>def!</span> -> return <span class=var>env</span>.<span class=function>set</span>(<span class=var>ast</span>[1], <span class=function>EVAL</span>(<span class=var>ast</span>[2], <span class=var>env</span>))
155 - <span class=malsym>let*</span> -> create new env <span class=var>let_env</span>
156 for each ODD/EVEN pair in <span class=var>ast[1]</span>:
157 <span class=var>let_env</span>.<span class=function>set</span>(ODD, <span class=function>EVAL</span>(EVEN, <span class=var>let_env</span>))
158 return <span class=function>EVAL</span>(<span class=var>ast</span>[2], <span class=var>let_env</span>)
159 <span class=function>main</span>(<span class=var>args</span>): populate <span class=var>repl_env</span> with numeric functions using <span class=var>repl_env</span>.<span class=function>set</span>
160</code></pre>
161 </td>
162 <td width=50%>
163<pre><code><span class=file>core.EXT</span>:
164 <span class=function>nth</span>, <span class=function>first</span>, <span class=function>rest</span>: sequence functions
165<span class=file>step8_macros.EXT</span>:
166 <span class=function>macroexpand</span>(<span class=var>ast</span>, <span class=var>env</span>):
167 - while <span class=var>env</span>.<span class=function>get</span>(<span class=var>ast</span>[0]) is a macro: <span class=var>ast</span> = <span class=var>env</span>.<span class=function>get</span>(<span class=var>ast</span>[0])(rest(<span class=var>ast</span>))
168 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
169 - before apply section, add <span class=var>ast</span> = <span class=function>macroexpand</span>(<span class=var>ast</span>, <span class=var>env</span>)
170 - <span class=malsym>defmacro!</span> -> same as <span class=malsym>def!</span>, but set mal function macro flag
171 - <span class=malsym>macroexpand</span> -> return <span class=function>macroexpand</span>(<span class=var>ast</span>[1], <span class=var>env</span>)
172
173
174</code></pre>
175 </td>
176 <tr>
177 <th>&nbsp;</th> <th>&nbsp;</th>
178 <tr>
179 <th>Step 4</th> <th>Step 9</th>
180 <tr>
181 <td width=50%>
182<pre><code><span class=file>env.EXT</span>:
183 <span class=object>Env</span>(<span class=var>outer</span>, <span class=var>binds</span>, <span class=var>exprs</span>) object: map <span class=var>binds</span> to <span class=var>exprs</span>, handle <span class=string>"&amp;"</span> as variadic
184<span class=file>core.EXT</span>:
185 <span class=function>=</span>: recursive compare of collections
186 <span class=function>pr-str</span>, <span class=function>str</span>: return <span class=function>pr_str</span>(<span class=function>arg</span>, true) join <span class=string>" "</span>, <span class=function>pr_str</span>(<span class=function>arg</span>, false) join <span class=string>""</span>
187 <span class=function>prn</span>, <span class=function>println</span>: print <span class=function>pr_str</span>(<span class=function>arg</span>, true) join <span class=string>""</span>, <span class=function>pr_str</span>(<span class=function>arg</span>, false) join <span class=string>""</span>
188 <span class=function><</span>, <span class=function><=</span>, <span class=function>></span>, <span class=function>>=</span>, <span class=function>+</span>, <span class=function>-</span>, <span class=function>*</span>, <span class=function>/</span>: numeric comparison and numeric operations
189 <span class=function>list</span>, <span class=function>list?</span>, <span class=function>empty?</span>, <span class=function>count</span>: sequence functions
190<span class=file>step4_do_if_fn.EXT</span>:
191 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
192 - <span class=malsym>do</span> -> return last element of <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>)
193 - <span class=malsym>if</span> -> if <span class=function>EVAL</span>(<span class=var>ast[1]</span>, <span class=var>env</span>): return <span class=function>EVAL</span>(<span class=var>ast[2]</span>, <span class=var>env</span>)
194 else : return <span class=function>EVAL</span>(<span class=var>ast[3]</span>, <span class=var>env</span>)
195 - <span class=malsym>fn*</span> -> return closure:
196 (<span class=var>args</span>) -> <span class=function>EVAL</span>(<span class=var>ast</span>[2], new <span class=object>Env</span>(<span class=var>env</span>, <span class=var>ast</span>[1], <span class=var>args</span>))
197 <span class=function>main</span>(<span class=var>args</span>): populate <span class=var>repl_env</span> with core functions, define not using <span class=function>rep</span>()
198</code></pre>
199 </td>
200 <td width=50%>
201<pre><code><span class=file>core.EXT</span>:
202 <span class=function>throw</span>: raise mal value as exception (maybe wrap in native exception)
203 <span class=function>vector</span>, <span class=function>vector?</span>: sequence functions
204 <span class=function>hash-map</span>, <span class=function>get</span>, <span class=function>contains?</span>, <span class=function>keys</span>, <span class=function>vals</span>: hash-map functions
205 <span class=function>assoc</span>, <span class=function>dissoc</span>: immutable hash-map transform functions
206 <span class=function>apply</span>(<span class=var>f</span>, <span class=var>args...</span>, <span class=var>last</span>): return <span class=function>f</span>(<span class=function>concat</span>(<span class=var>args</span>, <span class=var>last</span>))
207 <span class=function>map</span>(<span class=var>f</span>, <span class=var>args</span>): return list of mapping <span class=function>f</span> on each <span class=var>args</span>
208<span class=file>step9_try.EXT</span>:
209 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
210 - <span class=malsym>try*</span> -> try <span class=function>EVAL</span>(<span class=var>ast</span>[1], <span class=var>env</span>)
211 catch exception <span class=var>exc</span> (unwrap if necessary):
212 new <span class=var>err_env</span> with <span class=var>ast</span>[2][1] symbol bound to <span class=var>exc</span>
213 <span class=function>EVAL</span>(<span class=var>ast</span>[2][2], <span class=var>err_env</span>)
214
215
216
217</code></pre>
218 </td>
219 <tr>
220 <th>&nbsp;</th> <th>&nbsp;</th>
221 <tr>
222 <th>Step 5</th> <th>Step A</th>
223 <tr>
224 <td width=50%>
225<pre><code><span class=file>step5_tco.EXT</span>:
226 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
227 - top level loop in <span class=function>EVAL</span>
228 - <span class=malsym>let*</span> -> set <span class=var>env</span> to <span class=var>let_env</span>, set <span class=var>ast</span> to <span class=var>ast</span>[2], loop
229 - <span class=malsym>do</span> -> <span class=function>eval_ast</span> of middle elements, sets <span class=var>ast</span> to last element, loop
230 - <span class=malsym>if</span> -> set <span class=var>ast</span> to <span class=var>ast</span>[2] or <span class=var>ast</span>[3] (or <span class=malsym>nil</span>) depending condition, loop
231 - <span class=malsym>fn*</span> -> return new mal function type <span class=var>f</span> with:
232 <span class=var>f</span>.<span class=var>ast</span>=<span class=var>ast</span>[2], <span class=var>f</span>.<span class=var>params</span>=<span class=var>ast</span>[1], <span class=var>f</span>.<span class=var>env</span>=<span class=var>env</span>
233 - apply -> <span class=var>el</span> = <span class=function>eval_ast</span>(<span class=var>ast</span>, <span class=var>env</span>)
234 <span class=var>f</span> = <span class=var>el</span>[0]
235 if <span class=var>f</span> is a mal function: <span class=var>ast</span> = <span class=var>f</span>.<span class=var>ast</span> and <span class=var>env</span> = <span class=var>f</span>.<span class=var>env</span>, loop
236 else : return <span class=var>el</span>[0](rest(<span class=var>el</span>))
237
238</code></pre>
239 </td>
240 <td width=50%>
241<pre><code><span class=file>core.EXT</span>:
242 <span class=function>string?</span>: true if string
243 <span class=function>readline</span>: prompt and read a line of input (synchronous)
244 <span class=function>time-ms</span>: return milliseconds since epoch (1970-1-1)
245 <span class=function>conj</span>, <span class=function>seq</span>: type specific sequence functions
246 <span class=function>meta</span>, <span class=function>with-meta</span>: metadata functions
247<span class=file>step9_try.EXT</span>:
248 <span class=function>EVAL</span>(<span class=var>ast</span>, <span class=var>env</span>):
249 - set <span class=malsym>*host-language*</span> in <span class=var>repl_env</span> to host language name
a15f76bd
JM
250 <span class=function>main</span>(<span class=var>args</span>): <span class=function>rep</span>(<span class=string>"(println (str \"Mal [\" <span class=malsym>*host-language*</span> \"]\"))"</span>)
251</code></pre>
252 </td>
253 <tr>
254 <th>&nbsp;</th> <th>&nbsp;</th>
255 </table>
256</body>
257</html>