summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/op_string.go19
-rw-r--r--vm/type.go10
-rw-r--r--vm/vm.go34
-rw-r--r--vm/vm_test.go102
4 files changed, 94 insertions, 71 deletions
diff --git a/vm/op_string.go b/vm/op_string.go
index 63bf738..7eb0e5d 100644
--- a/vm/op_string.go
+++ b/vm/op_string.go
@@ -38,18 +38,19 @@ func _() {
_ = x[Loweri-27]
_ = x[Mul-28]
_ = x[New-29]
- _ = x[Not-30]
- _ = x[Pop-31]
- _ = x[Push-32]
- _ = x[Return-33]
- _ = x[Sub-34]
- _ = x[Subi-35]
- _ = x[Swap-36]
+ _ = x[Negate-30]
+ _ = x[Not-31]
+ _ = x[Pop-32]
+ _ = x[Push-33]
+ _ = x[Return-34]
+ _ = x[Sub-35]
+ _ = x[Subi-36]
+ _ = x[Swap-37]
}
-const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewEqualEqualSetExitFieldFieldSetGreaterGrowIndexJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNotPopPushReturnSubSubiSwap"
+const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewEqualEqualSetExitFieldFieldSetGreaterGrowIndexJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNegateNotPopPushReturnSubSubiSwap"
-var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 73, 77, 82, 90, 97, 101, 106, 110, 118, 127, 138, 150, 155, 161, 164, 167, 170, 173, 177, 183, 186, 190, 194}
+var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 73, 77, 82, 90, 97, 101, 106, 110, 118, 127, 138, 150, 155, 161, 164, 167, 173, 176, 179, 183, 189, 192, 196, 200}
func (i Op) String() string {
idx := int(i) - 0
diff --git a/vm/type.go b/vm/type.go
index 644c106..3a8d901 100644
--- a/vm/type.go
+++ b/vm/type.go
@@ -104,3 +104,13 @@ func (t *Type) FieldIndex(name string) []int {
}
return nil
}
+
+// FieldType returns the type of struct field name.
+func (t *Type) FieldType(name string) *Type {
+ for _, f := range reflect.VisibleFields(t.Rtype) {
+ if f.Name == name {
+ return &Type{Name: f.Name, PkgPath: f.PkgPath, Rtype: f.Type}
+ }
+ }
+ return nil
+}
diff --git a/vm/vm.go b/vm/vm.go
index 6472156..caf9189 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -24,7 +24,7 @@ const (
Addr // a -- &a ;
Assign // val -- ; mem[$1] = val
Fassign // val -- ; mem[$1] = val
- Vassign // val dest -- ; dest.Set(val)
+ Vassign // dest val -- ; dest.Set(val)
Call // f [a1 .. ai] -- [r1 .. rj] ; r1, ... = prog[f](a1, ...)
Calli // f [a1 .. ai] -- [r1 .. rj] ; r1, ... = prog[f](a1, ...)
CallX // f [a1 .. ai] -- [r1 .. rj] ; r1, ... = mem[f](a1, ...)
@@ -49,6 +49,7 @@ const (
Loweri // n1 -- cond ; cond = n1 < $1
Mul // n1 n2 -- prod ; prod = n1*n2
New // -- x; mem[fp+$1] = new mem[$2]
+ Negate // -- ; - mem[fp]
Not // c -- r ; r = !c
Pop // v --
Push // -- v
@@ -119,10 +120,13 @@ func (m *Machine) Run() (err error) {
mem[fp+c.Arg[0]-1].Set(mem[sp-1].Value)
mem = mem[:sp-1]
case Call:
- nip := int(mem[sp-1].Int())
- mem = append(mem[:sp-1], ValueOf(ip+1), ValueOf(fp))
+ // nip := int(mem[sp-1].Int())
+ // mem = append(mem[:sp-1], ValueOf(ip+1), ValueOf(fp))
+ nip := int(mem[sp-1-c.Arg[0]].Int())
+ mem = append(mem, ValueOf(ip+1), ValueOf(fp))
ip = nip
- fp = sp + 1
+ // fp = sp + 1
+ fp = sp + 2
continue
case Calli:
mem = append(mem, ValueOf(ip+1), ValueOf(fp))
@@ -132,9 +136,9 @@ func (m *Machine) Run() (err error) {
case CallX: // Should be made optional.
in := make([]reflect.Value, c.Arg[0])
for i := range in {
- in[i] = mem[sp-2-i].Value
+ in[i] = mem[sp-1-i].Value
}
- f := mem[sp-1].Value
+ f := mem[sp-1-c.Arg[0]].Value
mem = mem[:sp-c.Arg[0]-1]
for _, v := range f.Call(in) {
mem = append(mem, Value{Value: v})
@@ -142,7 +146,8 @@ func (m *Machine) Run() (err error) {
case Deref:
mem[sp-1].Value = mem[sp-1].Value.Elem()
case Dup:
- mem = append(mem, mem[c.Arg[0]])
+ k := c.Arg[0]
+ mem = append(mem, mem[k])
case New:
mem[c.Arg[0]+fp-1] = NewValue(mem[c.Arg[1]].Type)
case Equal:
@@ -214,13 +219,15 @@ func (m *Machine) Run() (err error) {
}
mem = mem[:sp-1]
case Greater:
- mem[sp-2] = ValueOf(mem[sp-1].Int() > mem[sp-2].Int())
+ mem[sp-2] = ValueOf(mem[sp-2].Int() > mem[sp-1].Int())
mem = mem[:sp-1]
case Lower:
- mem[sp-2] = ValueOf(mem[sp-1].Int() < mem[sp-2].Int())
+ mem[sp-2] = ValueOf(mem[sp-2].Int() < mem[sp-1].Int())
mem = mem[:sp-1]
case Loweri:
mem[sp-1] = ValueOf(mem[sp-1].Int() < int64(c.Arg[0]))
+ case Negate:
+ mem[sp-1] = ValueOf(-mem[sp-1].Int())
case Not:
mem[sp-1] = ValueOf(!mem[sp-1].Bool())
case Pop:
@@ -234,10 +241,10 @@ func (m *Machine) Run() (err error) {
ip = int(mem[fp-2].Int())
ofp := fp
fp = int(mem[fp-1].Int())
- mem = append(mem[:ofp-c.Arg[0]-c.Arg[1]-1], mem[sp-c.Arg[0]:]...)
+ mem = append(mem[:ofp-c.Arg[0]-c.Arg[1]-2], mem[sp-c.Arg[0]:]...)
continue
case Sub:
- mem[sp-2] = ValueOf(int(mem[sp-1].Int() - mem[sp-2].Int()))
+ mem[sp-2] = ValueOf(int(mem[sp-2].Int() - mem[sp-1].Int()))
mem = mem[:sp-1]
case Subi:
mem[sp-1] = ValueOf(int(mem[sp-1].Int()) - c.Arg[0])
@@ -245,10 +252,11 @@ func (m *Machine) Run() (err error) {
a, b := sp-c.Arg[0]-1, sp-c.Arg[1]-1
mem[a], mem[b] = mem[b], mem[a]
case Index:
- mem[sp-2].Value = mem[sp-1].Index(int(mem[sp-2].Int()))
+ mem[sp-2].Value = mem[sp-2].Index(int(mem[sp-1].Int()))
mem = mem[:sp-1]
case Vassign:
- mem[sp-1].Set(mem[sp-2].Value)
+ // mem[sp-1].Set(mem[sp-2].Value)
+ mem[sp-2].Set(mem[sp-1].Value)
mem = mem[:sp-2]
}
ip++
diff --git a/vm/vm_test.go b/vm/vm_test.go
index a968281..950e61e 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -69,7 +69,7 @@ var tests = []struct {
{Op: Sub},
{Op: Exit},
},
- start: 0, end: 1, mem: "[1]",
+ start: 0, end: 1, mem: "[-1]",
}, { // #02 -- A simple multiplication.
code: []Instruction{
{Op: Push, Arg: []int{3}},
@@ -80,16 +80,16 @@ var tests = []struct {
start: 0, end: 1, mem: "[6]",
}, { // #03 -- lower.
code: []Instruction{
- {Op: Push, Arg: []int{3}},
{Op: Push, Arg: []int{2}},
+ {Op: Push, Arg: []int{3}},
{Op: Lower},
{Op: Exit},
},
start: 0, end: 1, mem: "[true]",
}, { // #04 -- greater.
code: []Instruction{
- {Op: Push, Arg: []int{2}},
{Op: Push, Arg: []int{3}},
+ {Op: Push, Arg: []int{2}},
{Op: Greater},
{Op: Exit},
},
@@ -153,16 +153,18 @@ var tests = []struct {
{Op: Exit},
},
start: 1, end: 3, mem: "[6 <nil>]",
-}, { // #12 -- Defining and calling a function in VM.
- code: []Instruction{
- {Op: Jump, Arg: []int{3}}, // 0
- {Op: Push, Arg: []int{3}}, // 1
- {Op: Return, Arg: []int{1, 1}}, // 2
- {Op: Push, Arg: []int{1}}, // 3
- {Op: Calli, Arg: []int{1}}, // 4
- {Op: Exit}, // 5
- },
- start: 0, end: 1, mem: "[3]",
+ /*
+ }, { // #12 -- Defining and calling a function in VM.
+ code: []Instruction{
+ {Op: Jump, Arg: []int{3}}, // 0
+ {Op: Push, Arg: []int{3}}, // 1
+ {Op: Return, Arg: []int{1, 1}}, // 2
+ {Op: Push, Arg: []int{1}}, // 3
+ {Op: Calli, Arg: []int{1}}, // 4
+ {Op: Exit}, // 5
+ },
+ start: 0, end: 1, mem: "[3]",
+ */
}, { // #13 -- Defining and calling a function in VM.
code: []Instruction{
{Op: Jump, Arg: []int{3}}, // 0
@@ -170,7 +172,7 @@ var tests = []struct {
{Op: Return, Arg: []int{1, 1}}, // 2
{Op: Push, Arg: []int{1}}, // 3
{Op: Push, Arg: []int{1}}, // 4
- {Op: Call}, // 5
+ {Op: Call, Arg: []int{0}}, // 5
{Op: Exit}, // 6
},
start: 0, end: 1, mem: "[3]",
@@ -183,56 +185,58 @@ var tests = []struct {
{Op: Return, Arg: []int{1, 1}}, // 4
{Op: Push, Arg: []int{1}}, // 5
{Op: Push, Arg: []int{1}}, // 6
- {Op: Call}, // 7
+ {Op: Call, Arg: []int{0}}, // 7
{Op: Exit}, // 8
},
- start: 0, end: 1, mem: "[3]",
+ start: 1, end: 2, mem: "[3]",
}, { // #15 -- Fibonacci numbers, hand written. Showcase recursivity.
code: []Instruction{
{Op: Jump, Arg: []int{19}}, // 0
- {Op: Push, Arg: []int{2}}, // 2 [2]
{Op: Fdup, Arg: []int{-2}}, // 1 [2 i]
+ {Op: Push, Arg: []int{2}}, // 2 [2]
{Op: Lower}, // 3 [true/false]
{Op: JumpTrue, Arg: []int{13}}, // 4 [], goto 17
- {Op: Push, Arg: []int{2}}, // 5 [i 2]
+ {Op: Push, Arg: []int{1}}, // 5
{Op: Fdup, Arg: []int{-2}}, // 6 [i]
- {Op: Sub}, // 7 [(i-2)]
- {Op: Push, Arg: []int{1}}, // 8
- {Op: Call}, // 9 [fib(i-2)]
- {Op: Push, Arg: []int{1}}, // 10 [(i-2) i 1]
+ {Op: Push, Arg: []int{2}}, // 7 [i 2]
+ {Op: Sub}, // 8 [(i-2)]
+ {Op: Call, Arg: []int{1}}, // 9 [fib(i-2)]
+ {Op: Push, Arg: []int{1}}, // 10
{Op: Fdup, Arg: []int{-2}}, // 11 [fib(i-2) i]
- {Op: Sub}, // 12 [(i-2) (i-1)]
- {Op: Push, Arg: []int{1}}, // 13
- {Op: Call}, // 14 [fib(i-2) fib(i-1)]
+ {Op: Push, Arg: []int{1}}, // 12 [(i-2) i 1]
+ {Op: Sub}, // 13 [(i-2) (i-1)]
+ {Op: Call, Arg: []int{1}}, // 14 [fib(i-2) fib(i-1)]
{Op: Add}, // 15 [fib(i-2)+fib(i-1)]
{Op: Return, Arg: []int{1, 1}}, // 16 return i
{Op: Fdup, Arg: []int{-2}}, // 17 [i]
{Op: Return, Arg: []int{1, 1}}, // 18 return i
- {Op: Push, Arg: []int{6}}, // 19 [1]
- {Op: Push, Arg: []int{1}}, // 20
- {Op: Call}, // 21 [fib(*1)]
+ {Op: Push, Arg: []int{1}}, // 19
+ {Op: Push, Arg: []int{6}}, // 20 [1]
+ {Op: Call, Arg: []int{1}}, // 21 [fib(*1)]
{Op: Exit}, // 22
},
start: 0, end: 1, mem: "[8]",
-}, { // #16 -- Fibonacci with some immediate instructions.
- code: []Instruction{
- {Op: Jump, Arg: []int{14}}, // 0
- {Op: Fdup, Arg: []int{-2}}, // 1 [i]
- {Op: Loweri, Arg: []int{2}}, // 2 [true/false]
- {Op: JumpTrue, Arg: []int{9}}, // 3 [], goto 12
- {Op: Fdup, Arg: []int{-2}}, // 4 [i]
- {Op: Subi, Arg: []int{2}}, // 5 [(i-2)]
- {Op: Calli, Arg: []int{1}}, // 6 [fib(i-2)]
- {Op: Fdup, Arg: []int{-2}}, // 7 [fib(i-2) i]
- {Op: Subi, Arg: []int{1}}, // 8 [(i-2) (i-1)]
- {Op: Calli, Arg: []int{1}}, // 9 [fib(i-2) fib(i-1)], call 1
- {Op: Add}, // 10 [fib(i-2)+fib(i-1)]
- {Op: Return, Arg: []int{1, 1}}, // 11 return i
- {Op: Fdup, Arg: []int{-2}}, // 12 [i]
- {Op: Return, Arg: []int{1, 1}}, // 13 return i
- {Op: Push, Arg: []int{6}}, // 14 [1]
- {Op: Calli, Arg: []int{1}}, // 15 [fib(*1)], call 1
- {Op: Exit}, // 16
- },
- start: 0, end: 1, mem: "[8]",
+ /*
+ }, { // #16 -- Fibonacci with some immediate instructions.
+ code: []Instruction{
+ {Op: Jump, Arg: []int{14}}, // 0
+ {Op: Fdup, Arg: []int{-2}}, // 1 [i]
+ {Op: Loweri, Arg: []int{2}}, // 2 [true/false]
+ {Op: JumpTrue, Arg: []int{9}}, // 3 [], goto 12
+ {Op: Fdup, Arg: []int{-2}}, // 4 [i]
+ {Op: Subi, Arg: []int{2}}, // 5 [(i-2)]
+ {Op: Calli, Arg: []int{1}}, // 6 [fib(i-2)]
+ {Op: Fdup, Arg: []int{-2}}, // 7 [fib(i-2) i]
+ {Op: Subi, Arg: []int{1}}, // 8 [(i-2) (i-1)]
+ {Op: Calli, Arg: []int{1}}, // 9 [fib(i-2) fib(i-1)], call 1
+ {Op: Add}, // 10 [fib(i-2)+fib(i-1)]
+ {Op: Return, Arg: []int{1, 1}}, // 11 return i
+ {Op: Fdup, Arg: []int{-2}}, // 12 [i]
+ {Op: Return, Arg: []int{1, 1}}, // 13 return i
+ {Op: Push, Arg: []int{6}}, // 14 [1]
+ {Op: Calli, Arg: []int{1}}, // 15 [fib(*1)], call 1
+ {Op: Exit}, // 16
+ },
+ start: 0, end: 1, mem: "[8]",
+ */
}}