3e46e67d48
- Fix segfault from uninitialized Symbol structs in scope/hir_lower/sema - Fix null ReadFile crash in Cli_MergeFileInto (missing stdlib files) - Extend function params from 6 to 9 (bux_str_format needs 9 args) - Add ExprList/HirArgList linked lists for >2 call arguments - Add banner image to README - Update docs: C backend is now primary (not QBE)
96 lines
2.5 KiB
Plaintext
96 lines
2.5 KiB
Plaintext
// scope.bux — Symbol table with parent-chain lookup
|
|
module Scope {
|
|
|
|
// Symbol kinds
|
|
const skVar: int = 0;
|
|
const skFunc: int = 1;
|
|
const skType: int = 2;
|
|
const skConst: int = 3;
|
|
const skModule: int = 4;
|
|
|
|
// Maximum symbols per scope
|
|
const maxSymbols: int = 1024;
|
|
|
|
struct Symbol {
|
|
kind: int;
|
|
name: String;
|
|
typeKind: int;
|
|
typeName: String;
|
|
isMutable: bool;
|
|
isPublic: bool;
|
|
decl: *Decl; // associated declaration (for funcs, structs, enums)
|
|
}
|
|
|
|
struct Scope {
|
|
symbols: *Symbol;
|
|
count: int;
|
|
parent: *Scope;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Scope operations
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func Scope_New() -> Scope {
|
|
let sz: uint = maxSymbols as uint * sizeof(Symbol);
|
|
let data: *Symbol = bux_alloc(sz) as *Symbol;
|
|
return Scope { symbols: data, count: 0, parent: null as *Scope };
|
|
}
|
|
|
|
func Scope_NewChild(parent: *Scope) -> Scope {
|
|
let sz: uint = maxSymbols as uint * sizeof(Symbol);
|
|
let data: *Symbol = bux_alloc(sz) as *Symbol;
|
|
return Scope { symbols: data, count: 0, parent: parent };
|
|
}
|
|
|
|
func Scope_Define(scope: *Scope, sym: Symbol) -> bool {
|
|
// Check local scope for duplicates
|
|
var i: int = 0;
|
|
while i < scope.count {
|
|
if String_Eq(scope.symbols[i].name, sym.name) {
|
|
return false;
|
|
}
|
|
i = i + 1;
|
|
}
|
|
if scope.count < maxSymbols {
|
|
scope.symbols[scope.count] = sym;
|
|
scope.count = scope.count + 1;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
func Scope_Lookup(scope: *Scope, name: String) -> Symbol {
|
|
var cur: *Scope = scope;
|
|
while cur != null as *Scope {
|
|
var i: int = 0;
|
|
while i < cur.count {
|
|
if String_Eq(cur.symbols[i].name, name) {
|
|
return cur.symbols[i];
|
|
}
|
|
i = i + 1;
|
|
}
|
|
cur = cur.parent;
|
|
}
|
|
var empty: Symbol = Symbol { kind: 0, name: "", typeKind: 0, typeName: "", isMutable: false, isPublic: false, decl: null as *Decl };
|
|
return empty;
|
|
}
|
|
|
|
func Scope_LookupLocal(scope: *Scope, name: String) -> Symbol {
|
|
var i: int = 0;
|
|
while i < scope.count {
|
|
if String_Eq(scope.symbols[i].name, name) {
|
|
return scope.symbols[i];
|
|
}
|
|
i = i + 1;
|
|
}
|
|
var empty: Symbol = Symbol { kind: 0, name: "", typeKind: 0, typeName: "", isMutable: false, isPublic: false, decl: null as *Decl };
|
|
return empty;
|
|
}
|
|
|
|
func Scope_Free(scope: *Scope) {
|
|
bux_free(scope.symbols as *void);
|
|
}
|
|
|
|
}
|