From 807f9818a5579e318edf7b50d70470d8b8a42382 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 11 Mar 2018 16:30:38 -0400 Subject: [PATCH] Add let macro. --- src/assembler/asm.c | 2 +- src/compiler/boot.dst | 16 +++++++++++++++- test/suite0.dst | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/assembler/asm.c b/src/assembler/asm.c index 709708da..44bf06d4 100644 --- a/src/assembler/asm.c +++ b/src/assembler/asm.c @@ -704,7 +704,7 @@ DstAssembleResult dst_asm(Dst source, int flags) { * NULL if not found. */ static const DstInstructionDef *dst_asm_reverse_lookup(uint32_t instr) { size_t i; - uint32_t opcode = instr & 0xFF; + uint32_t opcode = instr & 0x7F; for (i = 0; i < sizeof(dst_ops)/sizeof(DstInstructionDef); i++) { const DstInstructionDef *def = dst_ops + i; if (def->opcode == opcode) diff --git a/src/compiler/boot.dst b/src/compiler/boot.dst index 36fe7cec..db0cbdb5 100644 --- a/src/compiler/boot.dst +++ b/src/compiler/boot.dst @@ -90,7 +90,21 @@ (tuple 'def endsym end) (tuple 'while (tuple '< sym endsym) (tuple-prepend body 'do) - (tuple 'varset! sym (tuple '+ sym 1))))) + (tuple 'varset! sym (tuple '+ sym inc))))) + +(defn even? [x] (== 0 (% x 2))) +(defn odd? [x] (== 1 (% x 2))) + +(defmacro let [bindings & body] + (def head (ast-unwrap1 bindings)) + (when (odd? (length head)) (error "expected even number of bindings to let")) + (var accum ['do]) + (for [i 0 (length head) 2] + (array-push accum (tuple 'def + (get head i) + (get head (+ 1 i))))) + (array-push accum (tuple-prepend body 'do)) + (apply tuple accum)) (defn pairs [x] (var lastkey (next x nil)) diff --git a/test/suite0.dst b/test/suite0.dst index 506b152c..4dc7730b 100644 --- a/test/suite0.dst +++ b/test/suite0.dst @@ -259,6 +259,12 @@ (varset! count (+ 1 count))) (assert (= (length syms) 128) "many symbols"))) +# Let + +(assert (= (let [a 1 b 2] (+ a b)) 3), "simple let") +(assert (= (let [[a b] [1 2]] (+ a b)) 3), "destructured let") +(assert (= (let [[a [c d] b] [1 (tuple 4 3) 2]] (+ a b c d)) 10), "double destructured let") + # Macros (def defmacro macro (fn [name & more]