about summary refs log tree commit diff
path: root/pkg/lang
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-08-18 00:14:20 +0000
committerMel <einebeere@gmail.com>2022-08-18 00:14:20 +0000
commit0b06db39b833099bc6683abff176b13a1c97ca93 (patch)
tree06b227cf56d48cac7434b61bf70040e83a09dae2 /pkg/lang
parentbe6cd2217b6bb1bb411d46ebd9d003dfd928af96 (diff)
downloadjinx-0b06db39b833099bc6683abff176b13a1c97ca93.tar.zst
jinx-0b06db39b833099bc6683abff176b13a1c97ca93.zip
Fix local index getting reset when entering block
Diffstat (limited to 'pkg/lang')
-rw-r--r--pkg/lang/compiler/scope/scope_chain.go31
1 files changed, 25 insertions, 6 deletions
diff --git a/pkg/lang/compiler/scope/scope_chain.go b/pkg/lang/compiler/scope/scope_chain.go
index 0c8f5cf..419a982 100644
--- a/pkg/lang/compiler/scope/scope_chain.go
+++ b/pkg/lang/compiler/scope/scope_chain.go
@@ -63,6 +63,23 @@ func (sc *ScopeChain) CurrentLoop() *LoopScope {
 	return &sc.loopScopes[len(sc.loopScopes)-1]
 }
 
+func (sc *ScopeChain) CalculateTopLocalIndex() int {
+	topFunctionScope := sc.CurrentFunction()
+
+	sumLocals := 0
+	for scopeIndex := len(sc.symbolScopes) - 1; scopeIndex >= 0; scopeIndex-- {
+		scope := sc.symbolScopes[scopeIndex]
+		sumLocals += len(scope.variableSymbols)
+
+		// Function scope signifies start of stack boundry.
+		if ScopeID(scopeIndex) == topFunctionScope.id {
+			break
+		}
+	}
+
+	return sumLocals
+}
+
 func (sc *ScopeChain) Enter() {
 	sc.symbolScopes = append(sc.symbolScopes, NewSymbolScope())
 }
@@ -129,35 +146,37 @@ func (sc *ScopeChain) Declare(name string) (int, bool) {
 		indexInScope: indexInScope,
 	}
 
+	localIndex := sc.CalculateTopLocalIndex()
+
 	// Declare the symbol in the current scope.
 	current.variableSymbols = append(current.variableSymbols, Symbol[SymbolVariable]{
 		name: name,
 		data: SymbolVariable{
-			localIndex: indexInScope,
+			localIndex: localIndex,
 		},
 	})
 
 	sc.nameToSymbol[name] = symbolID
 
-	return indexInScope, true
+	return localIndex, true
 }
 
 func (sc *ScopeChain) DeclareAnonymous() int {
 	current := sc.Current()
-	index := len(current.variableSymbols)
+	localIndex := sc.CalculateTopLocalIndex()
 
 	current.variableSymbols = append(current.variableSymbols, Symbol[SymbolVariable]{
 		name: "", // An anonymous symbol has no name.
 		data: SymbolVariable{
-			localIndex: index,
+			localIndex: localIndex,
 		},
 	})
 
-	return index
+	return localIndex
 }
 
 func (sc *ScopeChain) DeclareTemporary() int {
-	return len(sc.Current().variableSymbols) // :)
+	return sc.CalculateTopLocalIndex() // :)
 }
 
 func (sc *ScopeChain) DeclareGlobal(name, module, author string) bool {