From b6fa4bc82398b09307f2e6b75e27422d1d1ecb33 Mon Sep 17 00:00:00 2001 From: Mel Date: Tue, 19 Jul 2022 02:27:19 +0200 Subject: Implement stack hygiene --- pkg/lang/compiler/scope/scope_chain.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'pkg/lang/compiler/scope/scope_chain.go') 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) { -- cgit 1.4.1