diff --git a/lang/dist/platform/elc b/lang/dist/platform/elc index cb517e2..8af8093 100755 Binary files a/lang/dist/platform/elc and b/lang/dist/platform/elc differ diff --git a/lang/dist/platform/elc-new b/lang/dist/platform/elc-new index 68ee155..8af8093 100755 Binary files a/lang/dist/platform/elc-new and b/lang/dist/platform/elc-new differ diff --git a/lang/el-compiler/src/codegen.el b/lang/el-compiler/src/codegen.el index 7d5995d..ca231ed 100644 --- a/lang/el-compiler/src/codegen.el +++ b/lang/el-compiler/src/codegen.el @@ -3500,6 +3500,19 @@ fn codegen_streaming(tokens: [Any], sigs: [Map], source: String) -> if str_eq(k, "Eof") { let stream_running = false } else { + if str_eq(k, "Test") { + // Skip test "name" { ... } blocks entirely. + // The self-hosted compiler does not implement test execution. + // Without this skip, the body `{ ... }` would be parsed as a Map + // literal, building a huge AST with O(n²) string allocation that + // causes OOM on any file containing test blocks. + let p: Int = pos + 1 + let k_name: String = tok_kind(tokens, p) + if str_eq(k_name, "Str") { let p = p + 1 } + let k_body: String = tok_kind(tokens, p) + if str_eq(k_body, "LBrace") { let p = skip_to_rbrace(tokens, p) } + let pos = p + } else { let r = parse_one(tokens, pos) let stmt = r["node"] let new_pos: Int = r["pos"] @@ -3554,6 +3567,7 @@ fn codegen_streaming(tokens: [Any], sigs: [Map], source: String) -> let pos = new_pos } + } } } } @@ -3630,6 +3644,9 @@ fn codegen_streaming(tokens: [Any], sigs: [Map], source: String) -> el_release(toplevel_let_names) // Emit top-level executable stmts (lets and others) into main() + // Per-statement arena scope mirrors el_main_body: frees intermediate strings + // (str_concat fragments from cg_expr) after each statement, preventing O(n²) + // accumulation when many stmts are present (e.g. from unrecognized constructs). let tes_n2: Int = native_list_len(toplevel_exec_stmts) let tes_i2: Int = 0 while tes_i2 < tes_n2 { @@ -3637,7 +3654,9 @@ fn codegen_streaming(tokens: [Any], sigs: [Map], source: String) -> let tes_k2: String = tes2["stmt"] if !str_eq(tes_k2, "CgiBlock") { if !str_eq(tes_k2, "ServiceBlock") { + let tes_mark: Any = el_arena_push() let main_decl2 = cg_stmt(tes2, " ", main_decl2) + el_arena_pop(tes_mark) } } let tes_i2 = tes_i2 + 1