diff options
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/op_string.go | 76 | ||||
| -rw-r--r-- | vm/vm.go | 30 | ||||
| -rw-r--r-- | vm/vm_test.go | 139 |
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 @@ -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]", +}} |
