diff options
| author | Mel <einebeere@gmail.com> | 2022-07-05 23:39:18 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-07-06 14:05:28 +0200 |
| commit | 3a31347d38ae9a4c04c52304330b50f95a54a826 (patch) | |
| tree | e5ddbe398ede58f45c4a8e79c66018c5e37b06d8 /pkg/lang/compiler/scope_chain.go | |
| parent | bb1f61f938be3cc209dacf97b0395336631319bb (diff) | |
| download | jinx-3a31347d38ae9a4c04c52304330b50f95a54a826.tar.zst jinx-3a31347d38ae9a4c04c52304330b50f95a54a826.zip | |
Implement ForIn statement compilation
Diffstat (limited to 'pkg/lang/compiler/scope_chain.go')
| -rw-r--r-- | pkg/lang/compiler/scope_chain.go | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/pkg/lang/compiler/scope_chain.go b/pkg/lang/compiler/scope_chain.go index 8d942ea..6b7e693 100644 --- a/pkg/lang/compiler/scope_chain.go +++ b/pkg/lang/compiler/scope_chain.go @@ -9,8 +9,9 @@ type ScopeChain struct { func NewScopeChain() ScopeChain { scopes := make([]Scope, 1) scopes[0] = Scope{ - kind: ScopeKindGlobal, - symbols: make(map[string]Symbol), + kind: ScopeKindGlobal, + nameToSymbol: make(map[string]int), + symbols: make([]Symbol, 0), } return ScopeChain{ @@ -24,8 +25,9 @@ func (sc *ScopeChain) Current() *Scope { func (sc *ScopeChain) Enter(kind ScopeKind) { sc.scopes = append(sc.scopes, Scope{ - kind: kind, - symbols: make(map[string]Symbol), + kind: kind, + nameToSymbol: make(map[string]int), + symbols: make([]Symbol, 0), }) } @@ -34,28 +36,51 @@ func (sc *ScopeChain) Exit() { sc.scopes = sc.scopes[:len(sc.scopes)-1] } -func (sc *ScopeChain) Declare(name string) bool { +func (sc *ScopeChain) Declare(name string) (int, bool) { // Check whether the symbol is already declared in any of the scopes. for _, scope := range sc.scopes { - if _, ok := scope.symbols[name]; ok { - return false + if _, ok := scope.nameToSymbol[name]; ok { + return 0, false } } + current := sc.Current() + index := len(current.symbols) + // Declare the symbol in the current scope. - sc.Current().symbols[name] = Symbol{ + current.symbols = append(current.symbols, Symbol{ kind: SymbolKindVariable, name: name, - localIndex: len(sc.Current().symbols), - } + localIndex: index, + }) + + current.nameToSymbol[name] = index + + return index, true +} + +func (sc *ScopeChain) DeclareAnonymous() int { + current := sc.Current() + index := len(current.symbols) + + // Declare the symbol in the current scope. + current.symbols = append(current.symbols, Symbol{ + kind: SymbolKindVariable, + name: "", + localIndex: index, + }) + + return index +} - return true +func (sc *ScopeChain) DeclareTemporary() int { + return len(sc.Current().symbols) } func (sc *ScopeChain) Lookup(name string) (Symbol, bool) { for i := len(sc.scopes) - 1; i >= 0; i-- { - if symbol, ok := sc.scopes[i].symbols[name]; ok { - return symbol, true + if symbol, ok := sc.scopes[i].nameToSymbol[name]; ok { + return sc.scopes[i].symbols[symbol], true } } @@ -71,6 +96,7 @@ const ( ) type Scope struct { - kind ScopeKind - symbols map[string]Symbol + kind ScopeKind + nameToSymbol map[string]int + symbols []Symbol } |
