about summary refs log tree commit diff
path: root/pkg/lang/vm
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-07-05 23:39:18 +0200
committerMel <einebeere@gmail.com>2022-07-06 14:05:28 +0200
commit3a31347d38ae9a4c04c52304330b50f95a54a826 (patch)
treee5ddbe398ede58f45c4a8e79c66018c5e37b06d8 /pkg/lang/vm
parentbb1f61f938be3cc209dacf97b0395336631319bb (diff)
downloadjinx-3a31347d38ae9a4c04c52304330b50f95a54a826.tar.zst
jinx-3a31347d38ae9a4c04c52304330b50f95a54a826.zip
Implement ForIn statement compilation
Diffstat (limited to 'pkg/lang/vm')
-rw-r--r--pkg/lang/vm/code/op.go1
-rw-r--r--pkg/lang/vm/exec.go57
-rw-r--r--pkg/lang/vm/text/decompiler.go1
-rw-r--r--pkg/lang/vm/text/op.go1
-rw-r--r--pkg/lang/vm/vm.go2
5 files changed, 62 insertions, 0 deletions
diff --git a/pkg/lang/vm/code/op.go b/pkg/lang/vm/code/op.go
index 8b8ff3a..d0b2555 100644
--- a/pkg/lang/vm/code/op.go
+++ b/pkg/lang/vm/code/op.go
@@ -35,6 +35,7 @@ const (
 	OpSub
 	OpMod
 	OpIndex
+	OpLt
 	OpLte
 	OpCall
 
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go
index 93b8845..181d74e 100644
--- a/pkg/lang/vm/exec.go
+++ b/pkg/lang/vm/exec.go
@@ -662,6 +662,63 @@ func (vm *VM) execIndex() error {
 	return nil
 }
 
+func (vm *VM) execLt() error {
+	y, err := vm.popAndDrop()
+	if err != nil {
+		return err
+	}
+	x, err := vm.popAndDrop()
+	if err != nil {
+		return err
+	}
+
+	var res value.Value
+
+	switch x.Type() {
+	case value.IntType:
+		xv := x.Data().(value.IntData).Get()
+		switch y.Type() {
+		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() {
+		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(),
+		}
+	}
+
+	vm.stack.Push(res)
+	return nil
+}
+
 func (vm *VM) execLte() error {
 	y, err := vm.popAndDrop()
 	if err != nil {
diff --git a/pkg/lang/vm/text/decompiler.go b/pkg/lang/vm/text/decompiler.go
index c8922ec..bef066b 100644
--- a/pkg/lang/vm/text/decompiler.go
+++ b/pkg/lang/vm/text/decompiler.go
@@ -61,6 +61,7 @@ func (d *Decompiler) decompileInstruction(bc code.Raw) (string, code.Raw) {
 		code.OpSub,
 		code.OpMod,
 		code.OpIndex,
+		code.OpLt,
 		code.OpLte,
 		code.OpRet,
 		code.OpTempArrLen,
diff --git a/pkg/lang/vm/text/op.go b/pkg/lang/vm/text/op.go
index 0d01bdb..17f4847 100644
--- a/pkg/lang/vm/text/op.go
+++ b/pkg/lang/vm/text/op.go
@@ -30,6 +30,7 @@ var (
 		code.OpSub:          "sub",
 		code.OpMod:          "mod",
 		code.OpIndex:        "index",
+		code.OpLt:          "lt",
 		code.OpLte:          "lte",
 		code.OpCall:         "call",
 		code.OpJmp:          "jmp",
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go
index e483176..3f0703a 100644
--- a/pkg/lang/vm/vm.go
+++ b/pkg/lang/vm/vm.go
@@ -168,6 +168,8 @@ func (vm *VM) step(op code.Op) (stepDecision, error) {
 		err = vm.execMod()
 	case code.OpIndex:
 		err = vm.execIndex()
+	case code.OpLt:
+		err = vm.execLt()
 	case code.OpLte:
 		err = vm.execLte()
 	case code.OpCall: