diff options
| author | Mel <einebeere@gmail.com> | 2022-05-18 19:37:47 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-18 19:37:47 +0200 |
| commit | e4d68d39ce7f990895686139cd5cba20d2b2ef89 (patch) | |
| tree | 8862118abb2181f3bb244daaec5ced0497bc07fd /pkg/lang/vm/stack.go | |
| parent | 089fa82b8f83695cb17b8f41d0376c03303e7663 (diff) | |
| download | jinx-e4d68d39ce7f990895686139cd5cba20d2b2ef89.tar.zst jinx-e4d68d39ce7f990895686139cd5cba20d2b2ef89.zip | |
Handle errors gracefully in VM
Diffstat (limited to 'pkg/lang/vm/stack.go')
| -rw-r--r-- | pkg/lang/vm/stack.go | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/pkg/lang/vm/stack.go b/pkg/lang/vm/stack.go index 1d028e5..9cf7db8 100644 --- a/pkg/lang/vm/stack.go +++ b/pkg/lang/vm/stack.go @@ -1,6 +1,8 @@ package vm -import "jinx/pkg/lang/vm/value" +import ( + "jinx/pkg/lang/vm/value" +) type CallStack []*LocalStack @@ -8,34 +10,64 @@ func NewCallStack() CallStack { return []*LocalStack{{}} } -func (cs *CallStack) Push() { +func (cs *CallStack) Push() error { + if len(*cs) > 1000 { + return ErrCallStackOverflow + } + *cs = append(*cs, &LocalStack{}) + return nil } -func (cs *CallStack) Pop() { +func (cs *CallStack) Pop() error { + if len(*cs) <= 1 { + return ErrCantPopRootFrame + } + *cs = (*cs)[:len(*cs)-1] + return nil } func (cs *CallStack) Top() *LocalStack { return (*cs)[len(*cs)-1] } -func (cs *CallStack) Prev() *LocalStack { - return (*cs)[len(*cs)-2] +func (cs *CallStack) Prev() (*LocalStack, error) { + if len(*cs) <= 1 { + return nil, ErrNoPreviousCallFrame + } + + return (*cs)[len(*cs)-2], nil } type LocalStack []value.Value -func (ls *LocalStack) Push(v value.Value) { +func (ls *LocalStack) Push(v value.Value) error { + if len(*ls) > 1000 { + return ErrLocalStackOverflow + } + *ls = append(*ls, v) + return nil } -func (ls *LocalStack) Pop() value.Value { +func (ls *LocalStack) Pop() (value.Value, error) { + if len(*ls) == 0 { + return value.Value{}, ErrCallFrameEmpty + } + v := (*ls)[len(*ls)-1] *ls = (*ls)[:len(*ls)-1] - return v + return v, nil } -func (ls *LocalStack) At(at int) value.Value { - return (*ls)[at] +func (ls *LocalStack) At(at int) (value.Value, error) { + if at >= len(*ls) { + return value.Value{}, ErrLocalIndexOutOfBounds{ + Index: at, + Len: len(*ls), + } + } + + return (*ls)[at], nil } |
