package vm import ( "jinx/pkg/lang/vm/value" ) type CallStack []*LocalStack func NewCallStack() CallStack { return []*LocalStack{{}} } func (cs *CallStack) Push() error { if len(*cs) > 1000 { return ErrCallStackOverflow } *cs = append(*cs, &LocalStack{}) return nil } 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, 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) error { if len(*ls) > 1000 { return ErrLocalStackOverflow } *ls = append(*ls, v) return nil } 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, nil } 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 }