summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-08-17 21:28:12 +0100
committerubq323 <ubq323@ubq323.website>2024-08-17 21:28:12 +0100
commit976aeda6465d0700843acbacdf79e18a652fd57e (patch)
tree259686d58b6b1b8dab248f3b9bf03aa5157735ac
parent41989a2ad51b15bf512b81f2c147070ba8a28ef8 (diff)
add when form
-rw-r--r--com.c25
-rw-r--r--tests/when.bth2
-rw-r--r--tests/when.out1
-rw-r--r--util.h2
4 files changed, 23 insertions, 7 deletions
diff --git a/com.c b/com.c
index 862d26f..e14bbc6 100644
--- a/com.c
+++ b/com.c
@@ -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
diff --git a/util.h b/util.h
index 6b61b56..e4c47f0 100644
--- a/util.h
+++ b/util.h
@@ -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__)