aboutsummaryrefslogtreecommitdiff
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: