closures with captures: env struct + global instance + body rewriting

- AST: captureCount + captureName0..7 + captureType0..7 in Expr
- Sema: Scope_LookupUpTo + closureScope for capture analysis
- HIR Lower: env struct generation, capture assignments in skLet,
  body rewriting (ekIdent -> hFieldAccess on env instance)
- C Backend: env struct def + global instance emission for closures
- Bootstrap: full capture support in sema, hir_lower, lir_lower, lir_c_backend
- Selfhost loop remains deterministic
This commit is contained in:
2026-06-09 21:23:05 +03:00
parent ba54aa240e
commit 9b473c667c
17 changed files with 5267 additions and 53 deletions
+14
View File
@@ -345,6 +345,14 @@ proc lowerExpr(ctx: var LowerToLirCtx, node: HirNode): LirValue =
b.emitRawC(&"{t.strVal} = (void*)&({lirValToC(base)}.{node.fieldName});")
return t
of hFieldAccess:
let base = lowerExpr(ctx, node.fieldAccessBase)
let cType = hirTypeToC(ctx, node)
let t = b.freshTemp()
b.emitAlloca(t.strVal, cType)
b.emitRawC(&"{t.strVal} = {lirValToC(base)}.{node.fieldAccessName};")
return t
of hArrowField:
let base = lowerExpr(ctx, node.arrowFieldBase)
let t = b.freshTemp()
@@ -549,6 +557,9 @@ proc buildLval(ctx: var LowerToLirCtx, n: HirNode): string =
of hArrowField:
let baseStr = buildLval(ctx, n.arrowFieldBase)
return baseStr & "->" & n.arrowFieldName
of hFieldAccess:
let baseStr = buildLval(ctx, n.fieldAccessBase)
return baseStr & "." & n.fieldAccessName
of hIndexPtr:
let baseStr = buildLval(ctx, n.indexPtrBase)
let idx = lowerExpr(ctx, n.indexPtrIndex)
@@ -669,6 +680,9 @@ proc lowerStmt(ctx: var LowerToLirCtx, node: HirNode) =
of hFieldPtr:
let lval = buildLval(ctx, node.assignTarget)
b.emitRawC(&"{lval} = {lirValToC(value)};")
of hFieldAccess:
let lval = buildLval(ctx, node.assignTarget)
b.emitRawC(&"{lval} = {lirValToC(value)};")
of hArrowField:
let lval = buildLval(ctx, node.assignTarget)
b.emitRawC(&"{lval} = {lirValToC(value)};")