diff options
| author | Mel <einebeere@gmail.com> | 2022-05-20 21:04:37 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-20 21:04:37 +0200 |
| commit | 3f4efe745a0404953266476ec52db54b182de2f8 (patch) | |
| tree | 107542d587c97b99f749c537870e84d196058210 /pkg/lang/vm/stack.go | |
| parent | 25eb5ca1b0a8b9b35f36deedec4901bca02bf43e (diff) | |
| download | jinx-3f4efe745a0404953266476ec52db54b182de2f8.tar.zst jinx-3f4efe745a0404953266476ec52db54b182de2f8.zip | |
Call and return from functions
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() } |
