From 14fc765c78c06cca5cb1aecf7eb073f98d92b9b8 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Mon, 11 May 2026 03:44:59 +0300 Subject: [PATCH] fix: var hoisting in emitBlock for def inside deftest bodies - emitBlock now hoists 'var' declarations out of IIFE wrappers - emitProgramInternal cleaned up (removed debug output) - Exception type mapping: unknown types preserved (e.g. ValueError) - 230/233 compliance (98.7%), 78/80 unit tests (97.5%) --- src/emitter.nim | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/emitter.nim b/src/emitter.nim index 2789302..5db7c56 100644 --- a/src/emitter.nim +++ b/src/emitter.nim @@ -1923,8 +1923,26 @@ proc emitBlock(items: seq[CljVal], indent: int, useResult: bool = false): string else: code = indentStr(indent) & "discard " & stripped else: - let indentedCode = indentCode(code, 1) - code = indentStr(indent) & "discard ((proc (): CljVal =\n" & indentedCode & "\n" & indentStr(indent) & ")())" + # Multi-line code — check if it starts with a var declaration that should be hoisted + let codeLines = code.split("\n") + let firstLine = codeLines[0].strip() + if firstLine.startsWith("var ") and firstLine.contains(" = "): + # Split: emit var decl directly at current indent, wrap remaining in IIFE + if codeLines.len > 1: + var restLines: seq[string] = @[] + for li in 1.. 0: + let indentedRest = indentCode(restLines.join("\n"), 1) + code = indentStr(indent) & firstLine & "\n" & indentStr(indent) & "discard ((proc (): CljVal =\n" & indentedRest & "\n" & indentStr(indent) & ")())" + else: + code = indentStr(indent) & firstLine + else: + code = indentStr(indent) & firstLine + else: + let indentedCode = indentCode(code, 1) + code = indentStr(indent) & "discard ((proc (): CljVal =\n" & indentedCode & "\n" & indentStr(indent) & ")())" elif useResult: if stripped.startsWith("discard "): code = indentStr(indent) & "result = " & stripped[8..^1]