From a1a65f1c275d9dd91c909825351a5b805f514b50 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Tue, 12 May 2026 12:54:00 +0300 Subject: [PATCH] fix(emitter): loop in expression context via needsValue + IIFE wrapper - Add needsValue parameter to emitExpr/emitSpecialForm to track expression context - loop wraps in (proc(): CljVal = ... )() when needsValue=true - Function call args, let/def values, vector/map literals pass needsValue=true - emitProgramInternal passes needsValue=isLast for top-level forms - Fixes: loop as function arg, loop in let RHS, loopResult at top level --- .gitignore | 1 + src/emitter.nim | 50 +++++++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 1d0353d..78da813 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ test_single_debug.py src/tui_config experiments/native-lib/test_client/test_client experiments/wasm/tools/zig/ +lib/bring_http.nim diff --git a/src/emitter.nim b/src/emitter.nim index 8d0f21e..46206ef 100644 --- a/src/emitter.nim +++ b/src/emitter.nim @@ -126,7 +126,7 @@ proc isLocalVar(name: string): bool = return true return false -proc emitExpr*(v: CljVal, indent: int = 0): string +proc emitExpr*(v: CljVal, indent: int = 0, needsValue: bool = false): string proc emitBlock*(items: seq[CljVal], indent: int, useResult: bool = false): string proc emitQuotedForm*(v: CljVal): string proc emitFnAsProc*(items: seq[CljVal], indent: int): string @@ -481,7 +481,7 @@ proc letDestructuredBindings(bindings: CljVal): CljVal = i += 2 return cljVector(result) -proc emitSpecialForm(items: seq[CljVal], indent: int): string = +proc emitSpecialForm(items: seq[CljVal], indent: int, needsValue: bool = false): string = let sp = indentStr(indent) let head = items[0] if head.kind != ckSymbol: @@ -494,7 +494,7 @@ proc emitSpecialForm(items: seq[CljVal], indent: int): string = # Head is not a symbol - evaluate as function call: ((fn ...) args...) var argParts: seq[string] = @[] for i in 1.. 0: var argParts: seq[string] = @[] for i in 1..", "<", ">=", "<=", "not=", "println", "prn", "print", "str", "pr-str", @@ -2163,7 +2173,7 @@ proc emitQuotedForm*(v: CljVal): string = else: return emitExpr(v, 0) -proc emitExpr*(v: CljVal, indent: int = 0): string = +proc emitExpr*(v: CljVal, indent: int = 0, needsValue: bool = false): string = let sp = indentStr(indent) case v.kind of ckNil: @@ -2237,12 +2247,12 @@ proc emitExpr*(v: CljVal, indent: int = 0): string = # Macro-expand before emitting let expanded = macroexpand(v) if expanded == v: - return emitSpecialForm(v.items, indent) - return emitExpr(expanded, indent) + return emitSpecialForm(v.items, indent, needsValue) + return emitExpr(expanded, indent, needsValue) of ckVector: var parts: seq[string] = @[] for item in v.items: - parts.add(emitExpr(item, indent)) + parts.add(emitExpr(item, indent, needsValue = true)) return sp & "cljVector(@[" & parts.join(", ") & "])" of ckMap: if v.mapKeys.len == 0: @@ -2250,18 +2260,18 @@ proc emitExpr*(v: CljVal, indent: int = 0): string = var keyParts: seq[string] = @[] var valParts: seq[string] = @[] for i in 0..