Files
dimgigov 9b473c667c 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
2026-06-09 21:23:05 +03:00

56 lines
1.3 KiB
Nim

import std/tables
import types, ast
type
SymbolKind* = enum
skVar
skFunc
skType
skConst
skModule
Symbol* = ref object
kind*: SymbolKind
name*: string
typ*: Type
decl*: Decl ## optional back-reference to AST decl
isMutable*: bool
isPublic*: bool
isOwn*: bool ## true if declared as own T
Scope* = ref object
parent*: Scope
table*: Table[string, Symbol] ## O(1) lookup via hash table
proc newScope*(parent: Scope = nil): Scope =
result = Scope(parent: parent)
proc define*(scope: Scope, sym: Symbol): bool =
## Returns false if name already exists in this scope
if scope.table.hasKey(sym.name):
return false
scope.table[sym.name] = sym
return true
proc lookup*(scope: Scope, name: string): Symbol =
var cur = scope
while cur != nil:
if cur.table.hasKey(name):
return cur.table[name]
cur = cur.parent
return nil
proc lookupLocal*(scope: Scope, name: string): Symbol =
if scope.table.hasKey(name):
return scope.table[name]
return nil
proc lookupUpTo*(scope: Scope, name: string, limit: Scope): Symbol =
var cur = scope
while cur != nil:
if cur.table.hasKey(name):
return cur.table[name]
if cur == limit:
break
cur = cur.parent
return nil