From a5bed368b056910336ce11eeaebca42622d2a466 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Mon, 11 May 2026 11:02:33 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20macro=20test=20failures=20=E2=80=94=20an?= =?UTF-8?q?d,=20or,=20when,=20cond,=20as->,=20some->?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - and: fix base case for 2 args (was double-wrapping in if) - or: simplify to direct if without let/gensym - when: remove nil else branch, validate args.len >= 2 - cond: recursive expansion with cond in else branch - as->: swap arg order to match Clojure (init, name, body) - some->: use nil? check instead of truthy check --- src/macros.nim | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/macros.nim b/src/macros.nim index 65f912e..8b5bbb4 100644 --- a/src/macros.nim +++ b/src/macros.nim @@ -149,9 +149,7 @@ proc initMacros*() = defineMacro("and", proc(args: seq[CljVal]): CljVal = if args.len == 0: return cljBool(true) if args.len == 1: return args[0] - var result = cljList(@[cljSymbol("if"), args[^1], - args[^1], - cljBool(false)]) + var result = args[^1] for i in countdown(args.len - 2, 0): result = cljList(@[cljSymbol("if"), args[i], result, cljBool(false)]) return result @@ -163,9 +161,7 @@ proc initMacros*() = if args.len == 1: return args[0] var result = args[^1] for i in countdown(args.len - 2, 0): - let gs = cljSymbol(gensymName("or_")) - result = cljList(@[cljSymbol("let"), cljVector(@[gs, args[i]]), - cljList(@[cljSymbol("if"), gs, gs, result])]) + result = cljList(@[cljSymbol("if"), args[i], args[i], result]) return result ) @@ -205,13 +201,12 @@ proc initMacros*() = # when defineMacro("when", proc(args: seq[CljVal]): CljVal = - if args.len < 1: + if args.len < 2: raise newException(CatchableError, "when requires condition and body") let cond = args[0] let body = args[1..^1] cljList(@[cljSymbol("if"), cond, - cljList(@[cljSymbol("do")] & body), - cljNil()]) + cljList(@[cljSymbol("do")] & body)]) ) # when-not @@ -229,15 +224,14 @@ proc initMacros*() = if args.len == 0: return cljNil() if args.len mod 2 != 0: raise newException(CatchableError, "cond requires pairs of test/expr") - var result = cljNil() - for i in countdown((args.len div 2) - 1, 0): - let test = args[i * 2] - let expr = args[i * 2 + 1] - if test.kind == ckKeyword and test.kwName == "else": - result = expr - else: - result = cljList(@[cljSymbol("if"), test, expr, result]) - return result + let test = args[0] + let expr = args[1] + if test.kind == ckKeyword and test.kwName == "else": + return expr + if args.len == 2: + return cljList(@[cljSymbol("if"), test, expr]) + return cljList(@[cljSymbol("if"), test, expr, + cljList(@[cljSymbol("cond")] & args[2..^1])]) ) # cond-> @@ -314,9 +308,9 @@ proc initMacros*() = # as-> defineMacro("as->", proc(args: seq[CljVal]): CljVal = if args.len < 3: - raise newException(CatchableError, "as-> requires name, init, and body") - let name = args[0] - let init = args[1] + raise newException(CatchableError, "as-> requires init, name, and body") + let init = args[0] + let name = args[1] let body = args[2..^1] var result = init for form in body: @@ -333,16 +327,17 @@ proc initMacros*() = var result = init for form in body: let gs = cljSymbol(gensymName("st_")) + let nilCheck = cljList(@[cljSymbol("nil?"), gs]) if form.kind == ckList and form.items.len > 0: result = cljList(@[cljSymbol("let"), cljVector(@[gs, result]), - cljList(@[cljSymbol("if"), gs, - cljList(@[form.items[0], gs] & form.items[1..^1]), - cljNil()])]) + cljList(@[cljSymbol("if"), nilCheck, + cljNil(), + cljList(@[form.items[0], gs] & form.items[1..^1])])]) else: result = cljList(@[cljSymbol("let"), cljVector(@[gs, result]), - cljList(@[cljSymbol("if"), gs, - cljList(@[form, gs]), - cljNil()])]) + cljList(@[cljSymbol("if"), nilCheck, + cljNil(), + cljList(@[form, gs])])]) return result )