diff options
Diffstat (limited to 'pkg/lang/compiler/scope')
| -rw-r--r-- | pkg/lang/compiler/scope/scope_chain.go | 37 | ||||
| -rw-r--r-- | pkg/lang/compiler/scope/scopes.go | 2 | ||||
| -rw-r--r-- | pkg/lang/compiler/scope/symbol.go | 14 |
3 files changed, 52 insertions, 1 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go index f386017..0c8f5cf 100644 --- a/pkg/lang/compiler/scope/scope_chain.go +++ b/pkg/lang/compiler/scope/scope_chain.go @@ -160,6 +160,35 @@ func (sc *ScopeChain) DeclareTemporary() int { return len(sc.Current().variableSymbols) // :) } +func (sc *ScopeChain) DeclareGlobal(name, module, author string) bool { + if _, ok := sc.nameToSymbol[name]; ok { + return false + } + + current := sc.Current() + indexInScope := len(current.globalSymbols) + + symbolID := SymbolID{ + symbolKind: SymbolKindGlobal, + scopeID: sc.CurrentScopeID(), + indexInScope: indexInScope, + } + + globalID := fmt.Sprintf("%s:%s:%s", author, module, name) + + // Declare the symbol in the current scope. + current.globalSymbols = append(current.globalSymbols, Symbol[SymbolGlobal]{ + name: name, + data: SymbolGlobal{ + id: globalID, + }, + }) + + sc.nameToSymbol[name] = symbolID + + return true +} + func (sc *ScopeChain) CreateAnonymousFunctionSubUnit() code.Marker { fnScope := sc.CurrentFunction() @@ -242,3 +271,11 @@ func (sc *ScopeChain) GetEnv(id SymbolID) Symbol[SymbolEnv] { }, } } + +func (sc *ScopeChain) GetGlobal(id SymbolID) Symbol[SymbolGlobal] { + if id.symbolKind != SymbolKindGlobal { + panic("incorrect symbol id kind given") + } + + return sc.symbolScopes[id.scopeID].globalSymbols[id.indexInScope] +} diff --git a/pkg/lang/compiler/scope/scopes.go b/pkg/lang/compiler/scope/scopes.go index 2a9453a..e1a7a9f 100644 --- a/pkg/lang/compiler/scope/scopes.go +++ b/pkg/lang/compiler/scope/scopes.go @@ -14,11 +14,13 @@ const ( type SymbolScope struct { variableSymbols []Symbol[SymbolVariable] + globalSymbols []Symbol[SymbolGlobal] } func NewSymbolScope() SymbolScope { return SymbolScope{ variableSymbols: make([]Symbol[SymbolVariable], 0), + globalSymbols: make([]Symbol[SymbolGlobal], 0), } } diff --git a/pkg/lang/compiler/scope/symbol.go b/pkg/lang/compiler/scope/symbol.go index b87d5aa..8bfe60a 100644 --- a/pkg/lang/compiler/scope/symbol.go +++ b/pkg/lang/compiler/scope/symbol.go @@ -26,6 +26,8 @@ const ( // An env symbol is bound to a local on the stack, outside of the function's scope. // Emitted at lookup time, so the SymbolScope has no array for them. SymbolKindEnv SymbolKind = iota + // A global symbol is bound to a global from a dependency. + SymbolKindGlobal SymbolKind = iota ) func (s SymbolKind) String() string { @@ -34,6 +36,8 @@ func (s SymbolKind) String() string { return "variable" case SymbolKindEnv: return "env" + case SymbolKindGlobal: + return "global" default: panic("unknown symbol kind") } @@ -49,7 +53,7 @@ func (s Symbol[D]) Data() D { } type SymbolData interface { - SymbolVariable | SymbolEnv + SymbolVariable | SymbolEnv | SymbolGlobal } type SymbolVariable struct { @@ -67,3 +71,11 @@ type SymbolEnv struct { func (se SymbolEnv) IndexInEnv() int { return se.indexInEnv } + +type SymbolGlobal struct { + id string +} + +func (sg SymbolGlobal) ID() string { + return sg.id +} \ No newline at end of file |
