diff options
| author | Mel <einebeere@gmail.com> | 2022-08-18 20:04:24 +0000 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-08-18 20:04:24 +0000 |
| commit | 18c6d49cc9982ad4362e82730812e1134478ea64 (patch) | |
| tree | 35c27cae8a6c32a45e4cb88fb761d4e626c7b9cd /pkg/lang/compiler | |
| parent | 73ac132294f3e659f1d769c961aa45bafdd19b45 (diff) | |
| download | jinx-18c6d49cc9982ad4362e82730812e1134478ea64.tar.zst jinx-18c6d49cc9982ad4362e82730812e1134478ea64.zip | |
Allow shadowing through function scopes
Diffstat (limited to 'pkg/lang/compiler')
| -rw-r--r-- | pkg/lang/compiler/scope/scope_chain.go | 46 | ||||
| -rw-r--r-- | pkg/lang/compiler/scope/scopes.go | 6 |
2 files changed, 40 insertions, 12 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go index 419a982..ba4c4c2 100644 --- a/pkg/lang/compiler/scope/scope_chain.go +++ b/pkg/lang/compiler/scope/scope_chain.go @@ -6,8 +6,6 @@ import ( ) type ScopeChain struct { - nameToSymbol map[string]SymbolID - symbolScopes []SymbolScope // All other scopes are bound to this by ID. functionScopes []FunctionScope loopScopes []LoopScope @@ -23,8 +21,6 @@ func NewScopeChain() ScopeChain { loopScopes := make([]LoopScope, 0) return ScopeChain{ - nameToSymbol: make(map[string]SymbolID), - symbolScopes: symbolScopes, functionScopes: functionScopes, loopScopes: loopScopes, @@ -80,6 +76,25 @@ func (sc *ScopeChain) CalculateTopLocalIndex() int { return sumLocals } +func (sc *ScopeChain) CanSymbolBeDeclared(name string) bool { + topFunctionScope := sc.CurrentFunction() + + for scopeIndex := len(sc.symbolScopes) - 1; scopeIndex >= 0; scopeIndex-- { + scope := sc.symbolScopes[scopeIndex] + + if _, ok := scope.nameToSymbol[name]; ok { + return false + } + + // Shadowing only allowed with at least one function scope in the chain. + if ScopeID(scopeIndex) == topFunctionScope.id { + return true + } + } + + return true +} + func (sc *ScopeChain) Enter() { sc.symbolScopes = append(sc.symbolScopes, NewSymbolScope()) } @@ -133,7 +148,7 @@ func (sc *ScopeChain) Exit() int { func (sc *ScopeChain) Declare(name string) (int, bool) { // Check whether the symbol is already declared in any of the scopes. - if _, ok := sc.nameToSymbol[name]; ok { + if !sc.CanSymbolBeDeclared(name) { return 0, false } @@ -156,7 +171,7 @@ func (sc *ScopeChain) Declare(name string) (int, bool) { }, }) - sc.nameToSymbol[name] = symbolID + current.nameToSymbol[name] = symbolID return localIndex, true } @@ -180,7 +195,7 @@ func (sc *ScopeChain) DeclareTemporary() int { } func (sc *ScopeChain) DeclareGlobal(name, module, author string) bool { - if _, ok := sc.nameToSymbol[name]; ok { + if !sc.CanSymbolBeDeclared(name) { return false } @@ -203,7 +218,7 @@ func (sc *ScopeChain) DeclareGlobal(name, module, author string) bool { }, }) - sc.nameToSymbol[name] = symbolID + current.nameToSymbol[name] = symbolID return true } @@ -231,9 +246,18 @@ func (sc *ScopeChain) CreateFunctionSubUnit(subUnitName string) code.Marker { } func (sc *ScopeChain) Lookup(name string) (SymbolID, bool) { - id, ok := sc.nameToSymbol[name] - if !ok { - return SymbolID{}, false + var id SymbolID + for scopeIndex := len(sc.symbolScopes) - 1; scopeIndex >= 0; scopeIndex-- { + scope := sc.symbolScopes[scopeIndex] + + if foundID, ok := scope.nameToSymbol[name]; ok { + id = foundID + break + } + + if scopeIndex == 0 { + return SymbolID{}, false + } } // Check whether the symbol is outside the current function scope. diff --git a/pkg/lang/compiler/scope/scopes.go b/pkg/lang/compiler/scope/scopes.go index e1a7a9f..f62ab56 100644 --- a/pkg/lang/compiler/scope/scopes.go +++ b/pkg/lang/compiler/scope/scopes.go @@ -13,12 +13,16 @@ const ( ) type SymbolScope struct { + nameToSymbol map[string]SymbolID + variableSymbols []Symbol[SymbolVariable] - globalSymbols []Symbol[SymbolGlobal] + globalSymbols []Symbol[SymbolGlobal] } func NewSymbolScope() SymbolScope { return SymbolScope{ + nameToSymbol: make(map[string]SymbolID), + variableSymbols: make([]Symbol[SymbolVariable], 0), globalSymbols: make([]Symbol[SymbolGlobal], 0), } |
