summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/op_string.go76
-rw-r--r--vm/vm.go30
-rw-r--r--vm/vm_test.go139
3 files changed, 103 insertions, 142 deletions
diff --git a/vm/op_string.go b/vm/op_string.go
index 5542c6e..f53ce5e 100644
--- a/vm/op_string.go
+++ b/vm/op_string.go
@@ -15,48 +15,48 @@ func _() {
_ = x[Fassign-4]
_ = x[Vassign-5]
_ = x[Call-6]
- _ = x[Calli-7]
- _ = x[CallX-8]
- _ = x[Deref-9]
- _ = x[Dup-10]
- _ = x[Fdup-11]
- _ = x[Fnew-12]
- _ = x[FnewE-13]
- _ = x[Equal-14]
- _ = x[EqualSet-15]
- _ = x[Exit-16]
- _ = x[Field-17]
- _ = x[FieldE-18]
- _ = x[FieldSet-19]
- _ = x[FieldFset-20]
- _ = x[Greater-21]
- _ = x[Grow-22]
- _ = x[Index-23]
- _ = x[IndexSet-24]
- _ = x[MapIndex-25]
- _ = x[MapSet-26]
- _ = x[Jump-27]
- _ = x[JumpTrue-28]
- _ = x[JumpFalse-29]
- _ = x[JumpSetTrue-30]
- _ = x[JumpSetFalse-31]
- _ = x[Lower-32]
- _ = x[Loweri-33]
- _ = x[Mul-34]
- _ = x[New-35]
- _ = x[Negate-36]
- _ = x[Not-37]
- _ = x[Pop-38]
- _ = x[Push-39]
- _ = x[Return-40]
- _ = x[Sub-41]
- _ = x[Subi-42]
+ _ = x[CallX-7]
+ _ = x[Deref-8]
+ _ = x[Dup-9]
+ _ = x[Fdup-10]
+ _ = x[Fnew-11]
+ _ = x[FnewE-12]
+ _ = x[Equal-13]
+ _ = x[EqualSet-14]
+ _ = x[Exit-15]
+ _ = x[Field-16]
+ _ = x[FieldE-17]
+ _ = x[FieldSet-18]
+ _ = x[FieldFset-19]
+ _ = x[Greater-20]
+ _ = x[Grow-21]
+ _ = x[Index-22]
+ _ = x[IndexSet-23]
+ _ = x[Jump-24]
+ _ = x[JumpTrue-25]
+ _ = x[JumpFalse-26]
+ _ = x[JumpSetTrue-27]
+ _ = x[JumpSetFalse-28]
+ _ = x[Len-29]
+ _ = x[Lower-30]
+ _ = x[MapIndex-31]
+ _ = x[MapSet-32]
+ _ = x[Mul-33]
+ _ = x[New-34]
+ _ = x[Negate-35]
+ _ = x[Not-36]
+ _ = x[Pop-37]
+ _ = x[Push-38]
+ _ = x[Return-39]
+ _ = x[Slice-40]
+ _ = x[Slice3-41]
+ _ = x[Sub-42]
_ = x[Swap-43]
}
-const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewFnewEEqualEqualSetExitFieldFieldEFieldSetFieldFsetGreaterGrowIndexIndexSetMapIndexMapSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNegateNotPopPushReturnSubSubiSwap"
+const _Op_name = "NopAddAddrAssignFassignVassignCallCallXDerefDupFdupFnewFnewEEqualEqualSetExitFieldFieldEFieldSetFieldFsetGreaterGrowIndexIndexSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLenLowerMapIndexMapSetMulNewNegateNotPopPushReturnSliceSlice3SubSwap"
-var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 70, 78, 82, 87, 93, 101, 110, 117, 121, 126, 134, 142, 148, 152, 160, 169, 180, 192, 197, 203, 206, 209, 215, 218, 221, 225, 231, 234, 238, 242}
+var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 47, 51, 55, 60, 65, 73, 77, 82, 88, 96, 105, 112, 116, 121, 129, 133, 141, 150, 161, 173, 176, 181, 189, 195, 198, 201, 207, 210, 213, 217, 223, 228, 234, 237, 241}
func (i Op) String() string {
idx := int(i) - 0
diff --git a/vm/vm.go b/vm/vm.go
index 3f04bf6..07ea8e0 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -26,7 +26,6 @@ const (
Fassign // val -- ; mem[$1] = 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, ...)
Deref // x -- *x ;
Dup // addr -- value ; value = mem[addr]
@@ -44,15 +43,15 @@ const (
Grow // -- ; sp += $1
Index // a i -- a[i] ;
IndexSet // a i v -- a; a[i] = v
- MapIndex // a i -- a[i]
- MapSet // a i v -- a; a[i] = v
Jump // -- ; ip += $1
JumpTrue // cond -- ; if cond { ip += $1 }
JumpFalse // cond -- ; if cond { ip += $1 }
JumpSetTrue //
JumpSetFalse //
+ Len // -- x; x = mem[sp-$1]
Lower // n1 n2 -- cond ; cond = n1 < n2
- Loweri // n1 -- cond ; cond = n1 < $1
+ MapIndex // a i -- a[i]
+ MapSet // a i v -- a; a[i] = v
Mul // n1 n2 -- prod ; prod = n1*n2
New // -- x; mem[fp+$1] = new mem[$2]
Negate // -- ; - mem[fp]
@@ -60,8 +59,9 @@ const (
Pop // v --
Push // -- v
Return // [r1 .. ri] -- ; exit frame: sp = fp, fp = pop
+ Slice // a l h -- a; a = a [l:h]
+ Slice3 // a l h m -- a; a = a[l:h:m]
Sub // n1 n2 -- diff ; diff = n1 - n2
- Subi // n1 -- diff ; diff = n1 - $1
Swap // --
)
@@ -126,19 +126,11 @@ 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-c.Arg[0]].Int())
mem = append(mem, ValueOf(ip+1), ValueOf(fp))
ip = nip
- // fp = sp + 1
fp = sp + 2
continue
- case Calli:
- mem = append(mem, ValueOf(ip+1), ValueOf(fp))
- fp = sp + 2
- ip = c.Arg[0]
- continue
case CallX: // Should be made optional.
in := make([]reflect.Value, c.Arg[0])
for i := range in {
@@ -246,8 +238,8 @@ func (m *Machine) Run() (err error) {
case Lower:
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 Len:
+ mem = append(mem, ValueOf(mem[sp-1-c.Arg[0]].Len()))
case Negate:
mem[sp-1] = ValueOf(-mem[sp-1].Int())
case Not:
@@ -265,11 +257,15 @@ func (m *Machine) Run() (err error) {
fp = int(mem[fp-1].Int())
mem = append(mem[:ofp-c.Arg[0]-c.Arg[1]-2], mem[sp-c.Arg[0]:]...)
continue
+ case Slice:
+ mem[sp-3].Value = mem[sp-3].Slice(int(mem[sp-2].Int()), int(mem[sp-1].Int()))
+ mem = mem[:sp-2]
+ case Slice3:
+ mem[sp-4].Value = mem[sp-4].Slice3(int(mem[sp-3].Int()), int(mem[sp-2].Int()), int(mem[sp-1].Int()))
+ mem = mem[:sp-3]
case Sub:
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])
case Swap:
a, b := sp-c.Arg[0]-1, sp-c.Arg[1]-1
mem[a], mem[b] = mem[b], mem[a]
diff --git a/vm/vm_test.go b/vm/vm_test.go
index 6c1e4ff..94bba2c 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -154,90 +154,55 @@ var tests = []struct {
{Op: Exit},
},
start: 2, end: 4, 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]",
- },
- */{ // #13 -- 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: Push, Arg: []int{1}}, // 4
- {Op: Call, Arg: []int{0}}, // 5
- {Op: Exit}, // 6
- },
- start: 0, end: 1, mem: "[3]",
- }, { // #14 -- Defining and calling a function in VM.
- code: []Instruction{
- {Op: Jump, Arg: []int{5}}, // 0
- {Op: Push, Arg: []int{3}}, // 1
- {Op: Fassign, Arg: []int{-2}}, // 2
- {Op: Fdup, Arg: []int{-2}}, // 3
- {Op: Return, Arg: []int{1, 1}}, // 4
- {Op: Push, Arg: []int{1}}, // 5
- {Op: Push, Arg: []int{1}}, // 6
- {Op: Call, Arg: []int{0}}, // 7
- {Op: Exit}, // 8
- },
- start: 1, end: 2, mem: "[3]",
- }, { // #15 -- Fibonacci numbers, hand written. Showcase recursivity.
- code: []Instruction{
- {Op: Jump, Arg: []int{19}}, // 0
- {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{1}}, // 5
- {Op: Fdup, Arg: []int{-2}}, // 6 [i]
- {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: 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{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]",
- */
- }}
+}, { // #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: Push, Arg: []int{1}}, // 4
+ {Op: Call, Arg: []int{0}}, // 5
+ {Op: Exit}, // 6
+ },
+ start: 0, end: 1, mem: "[3]",
+}, { // #13 -- Defining and calling a function in VM.
+ code: []Instruction{
+ {Op: Jump, Arg: []int{5}}, // 0
+ {Op: Push, Arg: []int{3}}, // 1
+ {Op: Fassign, Arg: []int{-2}}, // 2
+ {Op: Fdup, Arg: []int{-2}}, // 3
+ {Op: Return, Arg: []int{1, 1}}, // 4
+ {Op: Push, Arg: []int{1}}, // 5
+ {Op: Push, Arg: []int{1}}, // 6
+ {Op: Call, Arg: []int{0}}, // 7
+ {Op: Exit}, // 8
+ },
+ start: 1, end: 2, mem: "[3]",
+}, { // #14 -- Fibonacci numbers, hand written. Showcase recursivity.
+ code: []Instruction{
+ {Op: Jump, Arg: []int{19}}, // 0
+ {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{1}}, // 5
+ {Op: Fdup, Arg: []int{-2}}, // 6 [i]
+ {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: 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{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]",
+}}