diff options
Diffstat (limited to 'pkg/lang/vm/stack.go')
| -rw-r--r-- | pkg/lang/vm/stack.go | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/pkg/lang/vm/stack.go b/pkg/lang/vm/stack.go index 937be32..51e43c8 100644 --- a/pkg/lang/vm/stack.go +++ b/pkg/lang/vm/stack.go @@ -64,6 +64,39 @@ func (stack *Stack) Top() (value.Value, error) { return stack.data[stack.Len()-1], nil } +func (stack *Stack) Len() int { + return len(stack.data) +} + +func (stack *Stack) IsEmpty() bool { + return len(stack.data) == 0 +} + +func (stack *Stack) PushCall(newPc, returnPc int) error { + if stack.CallDepth() == 1000 { + return ErrReachedMaxCallDepth + } + + stack.calls = append(stack.calls, callFrame{ + pc: newPc, + returnPc: returnPc, + base: stack.Len(), + }) + + return nil +} + +func (stack *Stack) PopCall() (int, error) { + if stack.CallDepth() == 0 { + return 0, ErrReachedRootCallFrame + } + + call := stack.TopCall() + stack.calls = stack.calls[:stack.CallDepth()-1] + + return call.returnPc, nil +} + func (stack *Stack) ShiftTopCallBase(by int) error { call := stack.TopCall() newBase := call.base - by @@ -76,18 +109,14 @@ func (stack *Stack) ShiftTopCallBase(by int) error { return nil } -func (stack *Stack) Len() int { - return len(stack.data) -} - -func (stack *Stack) IsEmpty() bool { - return len(stack.data) == 0 -} - func (stack *Stack) TopCall() *callFrame { return &stack.calls[len(stack.calls)-1] } +func (stack *Stack) CallDepth() int { + return len(stack.calls) +} + func (stack *Stack) ReachedBaseOfCall() bool { return stack.TopCall().base == stack.Len() } |
