diff options
| author | Mel <einebeere@gmail.com> | 2022-05-20 00:05:20 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-20 00:05:20 +0200 |
| commit | 360f092fe693f66219891581417026a3cffd2709 (patch) | |
| tree | 61370560419450ce0b306a68d20e85ce2c9f69a5 /pkg/lang/vm/exec.go | |
| parent | fe93d5c015e8e2c883d2c1e74f2e5ce071256cb5 (diff) | |
| download | jinx-360f092fe693f66219891581417026a3cffd2709.tar.zst jinx-360f092fe693f66219891581417026a3cffd2709.zip | |
More VM operations needed for Fib
Diffstat (limited to 'pkg/lang/vm/exec.go')
| -rw-r--r-- | pkg/lang/vm/exec.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index 54f43db..1b94572 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -227,3 +227,142 @@ func (vm *VM) execIndex() error { return nil } + +func (vm *VM) execLte() error { + top := vm.stack.Top() + + x, err := top.Pop() + if err != nil { + return err + } + y, err := top.Pop() + if err != nil { + return err + } + + var res value.Value + + switch x.Type().Kind { + case value.IntType: + xv := x.Data().(value.IntData).Get() + switch y.Type().Kind { + case value.IntType: + yv := y.Data().(value.IntData).Get() + res = value.NewBool(xv <= yv) + case value.FloatType: + yv := y.Data().(value.FloatData).Get() + res = value.NewBool(float64(xv) <= yv) + default: + return ErrInvalidOperandTypes{ + Op: code.OpLte, + X: x.Type(), + Y: y.Type(), + } + } + case value.FloatType: + xv := x.Data().(value.FloatData).Get() + switch y.Type().Kind { + case value.IntType: + yv := y.Data().(value.IntData).Get() + res = value.NewBool(xv <= float64(yv)) + case value.FloatType: + yv := y.Data().(value.FloatData).Get() + res = value.NewBool(xv <= yv) + default: + return ErrInvalidOperandTypes{ + Op: code.OpLte, + X: x.Type(), + Y: y.Type(), + } + } + default: + return ErrInvalidOperandTypes{ + Op: code.OpLte, + X: x.Type(), + Y: y.Type(), + } + } + + top.Push(res) + return nil +} + +func (vm *VM) execJumpIf(pc int, cond bool) error { + top := vm.stack.Top() + + b, err := top.Pop() + if err != nil { + return err + } + + switch b.Type().Kind { + case value.BoolType: + bl := b.Data().(value.BoolData) + if bl.Get() == cond { + vm.pc = pc + } + default: + var op code.Op + if cond { + op = code.OpJt + } else { + op = code.OpJf + } + + return ErrInvalidOperandType{ + Op: op, + X: b.Type(), + } + } + + return nil +} + +func (vm *VM) execTempArrLen() error { + top := vm.stack.Top() + + a, err := top.Pop() + if err != nil { + return err + } + + switch a.Type().Kind { + case value.ArrayType: + arr := a.Data().(value.ArrayData) + res := value.NewInt(int64(arr.Len())) + top.Push(res) + default: + return ErrInvalidOperandTypes{ + Op: code.OpTempArrLen, + X: a.Type(), + } + } + + return nil +} + +func (vm *VM) execTempArrPush() error { + top := vm.stack.Top() + + a, err := top.Pop() + if err != nil { + return err + } + e, err := top.Pop() + if err != nil { + return err + } + + switch a.Type().Kind { + case value.ArrayType: + arr := a.Data().(value.ArrayData) + arr.Push(e) + default: + return ErrInvalidOperandType{ + Op: code.OpTempArrPush, + X: a.Type(), + } + } + + return nil +} |
