diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-10 14:15:45 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-10 14:15:45 +0200 |
commit | 9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec (patch) | |
tree | cfdc7470c4aa088ce77f92f6fff5c3683f92835a | |
parent | 8f0c21094bc69a9adbebc42a4fc4744ed0501428 (diff) | |
download | bdl-9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec.tar.gz bdl-9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec.zip |
Add cond special form
-rw-r--r-- | examples/booleans.bdl | 21 | ||||
-rwxr-xr-x | src/bootstrap/main.c | 2 | ||||
-rw-r--r-- | src/bootstrap/primitives.c | 26 | ||||
-rw-r--r-- | tests/booleans_expected.txt | 5 |
4 files changed, 53 insertions, 1 deletions
diff --git a/examples/booleans.bdl b/examples/booleans.bdl index d526f25..24d57a0 100644 --- a/examples/booleans.bdl +++ b/examples/booleans.bdl | |||
@@ -54,3 +54,24 @@ | |||
54 | (print "(if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) -> ") (if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) | 54 | (print "(if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) -> ") (if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) |
55 | (print "(if true 7) -> ") (if true 7) | 55 | (print "(if true 7) -> ") (if true 7) |
56 | (print "(if false 7) -> ") (if false 7) | 56 | (print "(if false 7) -> ") (if false 7) |
57 | |||
58 | ;; Cond. | ||
59 | (print "(cond ((and true true true) 1) ((or true true false) 2) (else 3)) -> ") | ||
60 | (cond ((and true true true) 1) | ||
61 | ((or true true false) 2) | ||
62 | (else 3)) | ||
63 | (print "(cond ((and true true false) 1) ((or true true false) 2) (else 3)) -> ") | ||
64 | (cond ((and true true false) 1) | ||
65 | ((or true true false) 2) | ||
66 | (else 3)) | ||
67 | (print "(cond ((and true true false) 1) ((or false false false) 2) (else 3)) -> ") | ||
68 | (cond ((and true true false) 1) | ||
69 | ((or false false false) 2) | ||
70 | (else 3)) | ||
71 | (print "(cond ((and true true true) 1) ((or true true false) 2)) -> ") | ||
72 | (cond ((and true true false) 1) | ||
73 | ((or false false false) 2)) | ||
74 | (print "(cond ((and true true true) (+ 1 2 3)) ((or true true false) 2) (else 3)) -> ") | ||
75 | (cond ((and true true true) (+ 1 2 3)) | ||
76 | ((or true true false) 2) | ||
77 | (else 3)) | ||
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 8ec1231..c0f2e50 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c | |||
@@ -41,6 +41,8 @@ init(void) { | |||
41 | environment[env_n++] = (EnvSymbol){MAKE_SYM("and"), make_procedure(proc_and)}; | 41 | environment[env_n++] = (EnvSymbol){MAKE_SYM("and"), make_procedure(proc_and)}; |
42 | environment[env_n++] = (EnvSymbol){MAKE_SYM("or"), make_procedure(proc_or)}; | 42 | environment[env_n++] = (EnvSymbol){MAKE_SYM("or"), make_procedure(proc_or)}; |
43 | environment[env_n++] = (EnvSymbol){MAKE_SYM("if"), make_procedure(proc_if)}; | 43 | environment[env_n++] = (EnvSymbol){MAKE_SYM("if"), make_procedure(proc_if)}; |
44 | environment[env_n++] = (EnvSymbol){MAKE_SYM("else"), obj_true}; | ||
45 | environment[env_n++] = (EnvSymbol){MAKE_SYM("cond"), make_procedure(proc_cond)}; | ||
44 | environment[env_n++] = (EnvSymbol){MAKE_SYM("display"), make_procedure(proc_display)}; | 46 | environment[env_n++] = (EnvSymbol){MAKE_SYM("display"), make_procedure(proc_display)}; |
45 | environment[env_n++] = (EnvSymbol){MAKE_SYM("print"), make_procedure(proc_print)}; | 47 | environment[env_n++] = (EnvSymbol){MAKE_SYM("print"), make_procedure(proc_print)}; |
46 | } | 48 | } |
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 61ce360..29a1df8 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c | |||
@@ -329,6 +329,30 @@ proc_if(Object *args) { | |||
329 | return obj_nil; | 329 | return obj_nil; |
330 | } | 330 | } |
331 | 331 | ||
332 | // TODO: cond | 332 | Object * |
333 | proc_cond(Object *args) { | ||
334 | if (args->type != OBJ_TYPE_PAIR) { | ||
335 | fprintf(stderr, "error: wrong number of arguments.\n"); | ||
336 | return NULL; | ||
337 | } | ||
338 | |||
339 | if (args->car->type != OBJ_TYPE_PAIR) { | ||
340 | fprintf(stderr, "error: wrong argument type.\n"); | ||
341 | return NULL; | ||
342 | } | ||
343 | |||
344 | while (args != obj_nil) { | ||
345 | Object *clause = args->car; | ||
346 | if (eval(clause->car) == obj_true) { | ||
347 | return eval(clause->cdr->car); | ||
348 | } | ||
349 | |||
350 | args = args->cdr; | ||
351 | clause = args->car; | ||
352 | } | ||
353 | |||
354 | return obj_nil; | ||
355 | } | ||
356 | |||
333 | // TODO: equality greater than smaller than... | 357 | // TODO: equality greater than smaller than... |
334 | // TODO: fixnum left/right shift, mask, invert | 358 | // TODO: fixnum left/right shift, mask, invert |
diff --git a/tests/booleans_expected.txt b/tests/booleans_expected.txt index d05d314..f0612b8 100644 --- a/tests/booleans_expected.txt +++ b/tests/booleans_expected.txt | |||
@@ -41,3 +41,8 @@ | |||
41 | (if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) -> 6 | 41 | (if (or (+ 1 2 3) false) (+ 1 2 3) (+ 7 8 9)) -> 6 |
42 | (if true 7) -> 7 | 42 | (if true 7) -> 7 |
43 | (if false 7) -> () | 43 | (if false 7) -> () |
44 | (cond ((and true true true) 1) ((or true true false) 2) (else 3)) -> 1 | ||
45 | (cond ((and true true false) 1) ((or true true false) 2) (else 3)) -> 2 | ||
46 | (cond ((and true true false) 1) ((or false false false) 2) (else 3)) -> 3 | ||
47 | (cond ((and true true true) 1) ((or true true false) 2)) -> () | ||
48 | (cond ((and true true true) (+ 1 2 3)) ((or true true false) 2) (else 3)) -> 6 | ||