Fix resuming scope after returning from a called function

This commit is contained in:
Neemek 2024-12-29 21:07:44 +01:00
parent ce72ea6c47
commit 4b803100ef
Signed by: neemek
GPG key ID: 28360A8951CD0E9B

View file

@ -261,6 +261,7 @@ type Call struct {
ip Pos ip Pos
stackEnd Pos stackEnd Pos
variableEnd Pos variableEnd Pos
scope Pos
} }
var DefaultGlobals = map[string]Value{ var DefaultGlobals = map[string]Value{
@ -305,14 +306,17 @@ func (vm *VM) Next() bool {
v := vm.stack.Pop() v := vm.stack.Pop()
c := vm.call.Pop() c := vm.call.Pop()
// reset stack current and variable end // reset stack current and variable end and scope
vm.variableEnd = c.variableEnd vm.variableEnd = c.variableEnd
vm.stack.Current = c.stackEnd vm.stack.Current = c.stackEnd
vm.scope = c.scope
// reset to calling position // reset to calling position
vm.ip = c.ip vm.ip = c.ip
vm.chunk = c.chunk vm.chunk = c.chunk
vm.purgeVars()
vm.stack.Push(v) vm.stack.Push(v)
} }
@ -401,8 +405,10 @@ func (vm *VM) Next() bool {
ip: vm.ip, ip: vm.ip,
stackEnd: vm.stack.Current - Pos(len(f.Params)), stackEnd: vm.stack.Current - Pos(len(f.Params)),
variableEnd: vm.variableEnd, variableEnd: vm.variableEnd,
scope: vm.scope,
}) })
// TODO Fix the variables sometimes being wrongly assigned
for i := len(f.Params) - 1; i >= 0; i-- { for i := len(f.Params) - 1; i >= 0; i-- {
p := vm.stack.Current - Pos(len(f.Params)) + Pos(i) p := vm.stack.Current - Pos(len(f.Params)) + Pos(i)
vm.stack.items[p] = &VariableValue{ vm.stack.items[p] = &VariableValue{
@ -544,6 +550,11 @@ func (vm *VM) ascend() {
panic("invalid scope") panic("invalid scope")
} }
vm.purgeVars()
}
// purgeVars remove all variables not within scope
func (vm *VM) purgeVars() {
for ; vm.variableEnd > 0 && vm.stack.items[vm.variableEnd-1].(*VariableValue).scope > vm.scope; vm.variableEnd-- { for ; vm.variableEnd > 0 && vm.stack.items[vm.variableEnd-1].(*VariableValue).scope > vm.scope; vm.variableEnd-- {
vm.stack.Pop() vm.stack.Pop()
} }