diff options
author | ubq323 <ubq323@ubq323.website> | 2024-08-17 21:28:12 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-08-17 21:28:12 +0100 |
commit | 976aeda6465d0700843acbacdf79e18a652fd57e (patch) | |
tree | 259686d58b6b1b8dab248f3b9bf03aa5157735ac | |
parent | 41989a2ad51b15bf512b81f2c147070ba8a28ef8 (diff) |
add when form
-rw-r--r-- | com.c | 25 | ||||
-rw-r--r-- | tests/when.bth | 2 | ||||
-rw-r--r-- | tests/when.out | 1 | ||||
-rw-r--r-- | util.h | 2 |
4 files changed, 23 insertions, 7 deletions
@@ -270,6 +270,24 @@ static void if_form(Compiler *C, ObjArr *a, Op _, int flags) { CHECK(stack_cur_a == orig_stack_cur + 1, "this should never happen"); } +static void when_form(Compiler *C, ObjArr *a, Op _, int flags) { + // (when cond body...) + // cond + // 0branch -> A + // body... + // drop + // A: + // nil + cpl_expr(C, a->d[1], 0); + cpl_op(C, OP_0BRANCH); + size_t ph = placeholder(C); + cpl_body(C, a, 2, 0); + cpl_op(C, OP_DROP); + size_t dest = BYTECODE(C).len; + patch(C, ph, dest - ph - 2); + cpl_op(C, OP_NIL); +} + static void while_form(Compiler *C, ObjArr *a, Op _, int flags) { // (while cond body ...) // A: @@ -576,6 +594,7 @@ static BuiltinForm builtin_forms[] = { { "set!", 2, false, set_form, 0 }, { "do", 1, true, do_form, 0 }, { "if", 3, false, if_form, 0 }, + { "when", 2, true, when_form, 0 }, { "while", 2, true, while_form, 0 }, { "for", 2, true, for_form, 0 }, { "each", 2, true, each_form, 0 }, @@ -670,12 +689,6 @@ static void cpl_expr(Compiler *C, Val v, int flags) { "local declared not at top level (compiler bug)"); } - - - - - - static char buf[8193]; int main(int argc, char **argv) { diff --git a/tests/when.bth b/tests/when.bth new file mode 100644 index 0000000..592bb54 --- /dev/null +++ b/tests/when.bth @@ -0,0 +1,2 @@ +(when (= (* 6 6) 36) (say 'yes)) +(when (= (+ 2 2) 5) (say 'no)) diff --git a/tests/when.out b/tests/when.out new file mode 100644 index 0000000..7cfab5b --- /dev/null +++ b/tests/when.out @@ -0,0 +1 @@ +yes @@ -4,7 +4,7 @@ #include <stdio.h> #include <stdlib.h> -#define CHECK(cond, ...) do { if (!(cond)) { fprintf(stderr, __VA_ARGS__); putchar('\n'); exit(1); } } while(0) +#define CHECK(cond, ...) do { if (!(cond)) { fflush(stdout); fprintf(stderr, __VA_ARGS__); putchar('\n'); exit(1); } } while(0) #define ERROR(...) CHECK(false, __VA_ARGS__) |