about summary refs log tree commit diff
path: root/pkg/lang/vm/exec.go
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-05-20 00:05:20 +0200
committerMel <einebeere@gmail.com>2022-05-20 00:05:20 +0200
commit360f092fe693f66219891581417026a3cffd2709 (patch)
tree61370560419450ce0b306a68d20e85ce2c9f69a5 /pkg/lang/vm/exec.go
parentfe93d5c015e8e2c883d2c1e74f2e5ce071256cb5 (diff)
downloadjinx-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.go139
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
+}