git @ Cat's Eye Technologies Decoy / 50ad070
Checkpoint moving `cons` and `list` out of base tests. Chris Pressey 1 year, 4 months ago
3 changed file(s) with 209 addition(s) and 175 deletion(s). Raw diff Collapse all Expand all
9898 -> Functionality "Interpret Decoy Program" is implemented by shell command
9999 -> "./bin/decoy eval -m stdenv -I lib/ %(test-body-file)"
100100
101 > -> Functionality "Interpret Decoy Program" is implemented by shell command
102 > -> "./bin/decoy compile -m stdenv -I lib/ %(test-body-file) && node out.mjs"
103
104 -> Tests for functionality "Interpret Decoy Program"
101 |-> Functionality "Interpret Decoy Program" is implemented by shell command
102 |-> "./bin/decoy compile -m stdenv -I lib/ %(test-body-file) && node out.mjs"
103
104 -> Functionality "Interpret Consful Decoy Program" is implemented by shell command
105 -> "./bin/decoy eval -m stdenv -I lib/ %(test-body-file)"
105106
106107 Constructing and Manipulating Data
107108 ----------------------------------
108109
109 `quote` evaluates to literally what is in the head of the tail of
110 the cons cell whose head is `quote`.
111
112 (quote hello)
113 ===> hello
114
115 (quote (quote quote))
116 ===> (quote quote)
117
118 Atomic symbols may contain letters, `*`s, `?`s, and `-`s.
119
120 (quote abcdef-ghijklm*nopqrst?uvwxyz)
121 ===> abcdef-ghijklm*nopqrst?uvwxyz
122
123 `cons` lets you create a list from some thing and another list.
124
125 (cons (quote thing) (quote (rest)))
126 ===> (thing rest)
127
128 `cons` can be used to create an improper list.
129 (The `.` syntax for improper lists is not supported in the reader though.)
130
131 (cons (quote thing) (quote rest))
132 ===> (thing . rest)
133
134 `car` extracts the head of a list.
135
136 (car (quote (foo bar)))
137 ===> foo
138
139 `cdr` extracts the tail of a list.
140
141 (cdr (quote (foo bar)))
142 ===> (bar)
110 -> Tests for functionality "Interpret Decoy Program"
111
112 ### Strings
113
114 String literals evaluate to literally that string.
115
116 "hello"
117 ===> "hello"
143118
144119 Predicates and Types
145120 --------------------
146121
147 `equal?` works on symbols.
148
149 (cond (
150 (equal? (quote a) (quote a))
151 (quote true)) (else (quote false)))
152 ===> true
153
154 (cond (
155 (equal? (quote a) (quote b))
156 (quote true)) (else (quote false)))
157 ===> false
158
159 `equal?` works on lists.
160
161 (cond (
162 (equal? (quote (one (two three)))
163 (cons (quote one) (quote ((two three)))))
164 (quote true)) (else (quote false)))
165 ===> true
166
167 A symbol is not a list.
168
169 (cond (
170 (list? (quote a))
171 (quote true)) (else (quote false)))
172 ===> false
173
174 A list whose final cons cell's tail contains a null, is a list.
175
176 (cond (
177 (list? (cons (quote a) (quote ())))
178 (quote true)) (else (quote false)))
179 ===> true
180
181 (cond (
182 (list? (quote (a b c d e f)))
183 (quote true)) (else (quote false)))
184 ===> true
185
186 A pair is not a list.
187
188 Actually, pairs aren't defined at all in Decoy, so I wouldn't
189 blame an implementation for just freaking out at this one.
190
191 (cond (
192 (list? (cons (quote a) (quote b)))
193 (quote true)) (else (quote false)))
194 ===> false
195
196 Booleans are not lists.
197
198 (cond (
199 (list? (equal? (quote a) (quote b)))
200 (quote true)) (else (quote false)))
201 ===> false
202
203 Lambda functions are not lists.
204
205 (cond (
206 (list? (lambda (x y) (y x)))
207 (quote true)) (else (quote false)))
208 ===> false
209
210 But the empty list is a list.
211
212 (cond (
213 (list? (quote ()))
214 (quote true)) (else (quote false)))
215 ===> true
216
217 (cond (
218 (list? (cdr (quote (foo))))
219 (quote true)) (else (quote false)))
220 ===> true
221
222 The empty list can be expressed as `(quote ())`.
223
224 (cond (
225 (equal? (cdr (quote (foo))) (quote ()))
226 (quote true)) (else (quote false)))
227 ===> true
122 `cond` can be used to compare values.
123 `equal?` works on strings.
124
125 (cond
126 ((equal? "a" "a") "true")
127 (else "false"))
128 ===> "true"
129
130 (cond
131 ((equal? "a" "b") "true")
132 (else "false"))
133 ===> "false"
228134
229135 Binding to Names
230136 ----------------
232138 `let*` lets you bind identifiers to values. An identifier can be bound
233139 to a symbol.
234140
235 (let* ((a (quote hello))) a)
236 ===> hello
141 (let* ((a "hello")) a)
142 ===> "hello"
237143
238144 `let*` can appear in the binding expression in a `let*`.
239145
240 (let* ((a (let* ((b (quote c))) b))) a)
241 ===> c
146 (let* ((a (let* ((b "c")) b))) a)
147 ===> "c"
242148
243149 `let*` can bind a symbol to a function value.
244150
245 (let* ((a (lambda (x y) (cons x y))))
246 (a (quote foo) (quote ())))
247 ===> (foo)
151 (let* ((a (lambda (x y) y)))
152 (a "foo" "bar"))
153 ===> "bar"
248154
249155 Bindings established in a binding in a `let*` can be seen in
250156 subsequent bindings in the same `let*`.
251157
252 (let* ((a (quote hello)) (b (cons a (quote ())))) b)
253 ===> (hello)
158 (let* ((a "hello") (b (equal? a "hello"))) b)
159 ===> #t
254160
255161 Shadowing happens.
256162
257 (let* ((a (quote hello))) (let* ((a (quote goodbye))) a))
258 ===> goodbye
163 (let* ((a "hello")) (let* ((a "goodbye")) a))
164 ===> "goodbye"
259165
260166 `let*` can have an empty list of bindings.
261167
262 (let* () (quote hi))
263 ===> hi
168 (let* () "hi")
169 ===> "hi"
264170
265171 Decision-making
266172 ---------------
267173
268174 `if`.
269175
270 (if (equal? (quote a) (quote a)) (quote true) (quote false))
271 ===> true
272
273 (if (equal? (quote a) (quote b)) (quote true) (quote false))
274 ===> false
176 (if (equal? "a" "a") "true" "false")
177 ===> "true"
178
179 (if (equal? "a" "b") "true" "false")
180 ===> "false"
275181
276182 All non-booleans are considered true. This at least coincides with
277183 what Chicken tells me.
278184
279 (if (list 1) (quote true) (quote false))
280 ===> true
281
282 (if (list) (quote true) (quote false))
283 ===> true
284
285 (if 1 (quote true) (quote false))
286 ===> true
287
288 (if 0 (quote true) (quote false))
289 ===> true
290
291 (if "hey" (quote true) (quote false))
292 ===> true
293
294 (if "" (quote true) (quote false))
295 ===> true
185 (if 1 "true" "false")
186 ===> "true"
187
188 (if 0 "true" "false")
189 ===> "true"
190
191 (if "hey" "true" "false")
192 ===> "true"
193
194 (if "" "true" "false")
195 ===> "true"
296196
297197 `cond` works.
298198
299 (let* ((true (equal? (quote a) (quote a))))
300 (cond (true (quote hi)) (else (quote lo))))
301 ===> hi
302
303 (let* ((true (equal? (quote a) (quote a)))
304 (false (equal? (quote a) (quote b))))
305 (cond (false (quote hi)) (true (quote med)) (else (quote lo))))
306 ===> med
307
308 (let* ((true (equal? (quote a) (quote a)))
309 (false (equal? (quote a) (quote b))))
310 (cond (false (quote hi)) (false (quote med)) (else (quote lo))))
311 ===> lo
199 (let* ((true (equal? "a" "a")))
200 (cond (true "hi") (else "lo")))
201 ===> "hi"
202
203 (let* ((true (equal? "a" "a"))
204 (false (equal? "a" "b")))
205 (cond (false "hi") (true "med") (else "lo")))
206 ===> "med"
207
208 (let* ((true (equal? "a" "a"))
209 (false (equal? "a" "b")))
210 (cond (false "hi") (false "med") (else "lo")))
211 ===> "lo"
312212
313213 `cond` can have zero tests before the `else`.
314214
315 (cond (else (quote woo)))
316 ===> woo
215 (cond (else "woo"))
216 ===> "woo"
317217
318218 Functions
319219 ---------
320220
321221 You can define functions with `lambda`. They can be anonymous.
322222
323 ((lambda (a) a) (quote whee))
324 ===> whee
223 ((lambda (a) a) "whee")
224 ===> "whee"
325225
326226 Bindings in force when a function is defined will still be in force
327227 when the function is applied, even if they are not lexically in scope.
358258
359259 - - - -
360260
261 Cons Lists
262 ----------
263
264 -> Tests for functionality "Interpret Consful Decoy Program"
265
266 `quote` evaluates to literally what is in the head of the tail of
267 the cons cell whose head is `quote`.
268
269 (quote hello)
270 ===> hello
271
272 (quote (quote quote))
273 ===> (quote quote)
274
275 Atomic symbols may contain letters, `*`s, `?`s, and `-`s.
276
277 (quote abcdef-ghijklm*nopqrst?uvwxyz)
278 ===> abcdef-ghijklm*nopqrst?uvwxyz
279
280 `cons` lets you create a list from some thing and another list.
281
282 (cons (quote thing) (quote (rest)))
283 ===> (thing rest)
284
285 `cons` can be used to create an improper list.
286 (The `.` syntax for improper lists is not supported in the reader though.)
287
288 (cons (quote thing) (quote rest))
289 ===> (thing . rest)
290
291 `car` extracts the head of a list.
292
293 (car (quote (foo bar)))
294 ===> foo
295
296 `cdr` extracts the tail of a list.
297
298 (cdr (quote (foo bar)))
299 ===> (bar)
300
301 List lists
302 ----------
303
304 (if (list 1) "true" "false")
305 ===> "true"
306
307 (if (list) "true" "false")
308 ===> "true"
309
310 Predicates and Types
311 --------------------
312
313 `equal?` works on symbols.
314
315 (cond (
316 (equal? (quote a) (quote a))
317 (quote true)) (else (quote false)))
318 ===> true
319
320 (cond (
321 (equal? (quote a) (quote b))
322 (quote true)) (else (quote false)))
323 ===> false
324
325 `equal?` works on lists.
326
327 (cond (
328 (equal? (quote (one (two three)))
329 (cons (quote one) (quote ((two three)))))
330 (quote true)) (else (quote false)))
331 ===> true
332
333 A symbol is not a list.
334
335 (cond (
336 (list? (quote a))
337 (quote true)) (else (quote false)))
338 ===> false
339
340 A list whose final cons cell's tail contains a null, is a list.
341
342 (cond (
343 (list? (cons (quote a) (quote ())))
344 (quote true)) (else (quote false)))
345 ===> true
346
347 (cond (
348 (list? (quote (a b c d e f)))
349 (quote true)) (else (quote false)))
350 ===> true
351
352 A pair is not a list.
353
354 Actually, pairs aren't defined at all in Decoy, so I wouldn't
355 blame an implementation for just freaking out at this one.
356
357 (cond (
358 (list? (cons (quote a) (quote b)))
359 (quote true)) (else (quote false)))
360 ===> false
361
362 Booleans are not lists.
363
364 (cond (
365 (list? (equal? (quote a) (quote b)))
366 (quote true)) (else (quote false)))
367 ===> false
368
369 Lambda functions are not lists.
370
371 (cond (
372 (list? (lambda (x y) (y x)))
373 (quote true)) (else (quote false)))
374 ===> false
375
376 But the empty list is a list.
377
378 (cond (
379 (list? (quote ()))
380 (quote true)) (else (quote false)))
381 ===> true
382
383 (cond (
384 (list? (cdr (quote (foo))))
385 (quote true)) (else (quote false)))
386 ===> true
387
388 The empty list can be expressed as `(quote ())`.
389
390 (cond (
391 (equal? (cdr (quote (foo))) (quote ()))
392 (quote true)) (else (quote false)))
393 ===> true
394
361395 More Types
362396 ----------
397
398 -> Tests for functionality "Interpret Decoy Program"
363399
364400 ### Strings
365401
7777 e = Cons.table_to_list(es)
7878 end
7979 else
80 error("what is this I don't even: " .. scanner:get_token_text())
80 e = self:parse_sexp()
8181 end
8282 return e
8383 end
5151 print("import_from", env, registry, expr.name, depict(expr.import_list))
5252 end)
5353 env = registry:import_from(env, expr.name, expr.import_list)
54 elseif Cons.is_class_of(expr) then
54 else
5555 expr_processor(expr, env)
56 else
57 error("invalid toplevel: " .. depict(expr))
5856 end
5957 return env
6058 end