aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-10 14:15:45 +0200
committerBad Diode <bd@badd10de.dev>2021-10-10 14:15:45 +0200
commit9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec (patch)
treecfdc7470c4aa088ce77f92f6fff5c3683f92835a
parent8f0c21094bc69a9adbebc42a4fc4744ed0501428 (diff)
downloadbdl-9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec.tar.gz
bdl-9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec.zip
Add cond special form
-rw-r--r--examples/booleans.bdl21
-rwxr-xr-xsrc/bootstrap/main.c2
-rw-r--r--src/bootstrap/primitives.c26
-rw-r--r--tests/booleans_expected.txt5
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 332Object *
333proc_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