diff --git a/lib/compiler.sx b/lib/compiler.sx index 5f2e328a..1f0e963f 100644 --- a/lib/compiler.sx +++ b/lib/compiler.sx @@ -724,38 +724,41 @@ compile-cond (fn (em args scope tail?) - "Compile (cond test1 body1 test2 body2 ... :else fallback)." - (if - (< (len args) 2) - (emit-op em 2) - (let - ((test (first args)) - (body (nth args 1)) - (rest-clauses (if (> (len args) 2) (slice args 2) (list)))) - (if - (or - (and - (= (type-of test) "keyword") - (= (keyword-name test) "else")) - (= test true)) - (compile-expr em body scope tail?) - (do - (compile-expr em test scope false) - (emit-op em 33) - (let - ((skip (current-offset em))) - (emit-i16 em 0) - (compile-expr em body scope tail?) - (emit-op em 32) + "Compile (cond test1 body1 test2 body2 ... :else fallback).\n Also handles clause syntax: (cond (test1 body1) (test2 body2) ...)." + (let + ((flat-args (if (and (not (empty? args)) (list? (first args)) (> (len (first args)) 1) (list? (first (first args)))) (reduce (fn (acc clause) (if (list? clause) (append acc clause) (append acc (list clause)))) (list) args) args))) + (if + (< (len flat-args) 2) + (emit-op em 2) + (let + ((test (nth flat-args 0)) + (body (nth flat-args 1)) + (rest-clauses + (if (> (len flat-args) 2) (slice flat-args 2) (list)))) + (if + (or + (and + (= (type-of test) "keyword") + (= (keyword-name test) "else")) + (= test true)) + (compile-expr em body scope tail?) + (do + (compile-expr em test scope false) + (emit-op em 33) (let - ((end-jump (current-offset em))) + ((skip (current-offset em))) (emit-i16 em 0) - (patch-i16 em skip (- (current-offset em) (+ skip 2))) - (compile-cond em rest-clauses scope tail?) - (patch-i16 - em - end-jump - (- (current-offset em) (+ end-jump 2))))))))))) + (compile-expr em body scope tail?) + (emit-op em 32) + (let + ((end-jump (current-offset em))) + (emit-i16 em 0) + (patch-i16 em skip (- (current-offset em) (+ skip 2))) + (compile-cond em rest-clauses scope tail?) + (patch-i16 + em + end-jump + (- (current-offset em) (+ end-jump 2)))))))))))) (define compile-case (fn