diff options
| author | Mel <einebeere@gmail.com> | 2022-07-19 02:27:19 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-07-19 02:27:19 +0200 |
| commit | b6fa4bc82398b09307f2e6b75e27422d1d1ecb33 (patch) | |
| tree | e5b7aec7eb7f72f1c2f55e4b2a78d331bd81485e /pkg/lang/compiler/scope | |
| parent | e06aeb7fa2fcb9046b8861ed3c23417555e823f5 (diff) | |
| download | jinx-b6fa4bc82398b09307f2e6b75e27422d1d1ecb33.tar.zst jinx-b6fa4bc82398b09307f2e6b75e27422d1d1ecb33.zip | |
Implement stack hygiene
Diffstat (limited to 'pkg/lang/compiler/scope')
| -rw-r--r-- | pkg/lang/compiler/scope/scope_chain.go | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go index 4d5bbcf..d0108ee 100644 --- a/pkg/lang/compiler/scope/scope_chain.go +++ b/pkg/lang/compiler/scope/scope_chain.go @@ -84,13 +84,29 @@ func (sc *ScopeChain) EnterLoop() (code.Marker, code.Marker) { return breakMarker, continueMarker } -func (sc *ScopeChain) Exit() { +func (sc *ScopeChain) Exit() int { if sc.CurrentScopeID() == 0 { - return + return 0 } + id := sc.CurrentScopeID() + stackSpace := len(sc.symbolScopes[id].variableSymbols) - sc.symbolScopes[sc.CurrentScopeID()] = SymbolScope{} - sc.symbolScopes = sc.symbolScopes[:sc.CurrentScopeID()] + sc.symbolScopes[id] = SymbolScope{} + sc.symbolScopes = sc.symbolScopes[:id] + + if sc.CurrentLoop() != nil && sc.CurrentLoop().id == id { + lastLoopScope := len(sc.loopScopes) - 1 + sc.loopScopes[lastLoopScope] = LoopScope{} + sc.loopScopes = sc.loopScopes[:lastLoopScope] + } + + if sc.CurrentFunction().id == id { + lastFunctionScope := len(sc.functionScopes) - 1 + sc.functionScopes[lastFunctionScope] = FunctionScope{} + sc.functionScopes = sc.functionScopes[:lastFunctionScope] + } + + return stackSpace } func (sc *ScopeChain) Declare(name string) (int, bool) { |
