diff options
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/vm.go | 40 | ||||
| -rw-r--r-- | vm/vm_test.go | 5 |
2 files changed, 30 insertions, 15 deletions
@@ -14,7 +14,7 @@ const ( // instruction effect on stack: values consumed -- values produced Nop = iota // -- Add // n1 n2 -- sum ; sum = n1+n2 - Address // a -- &a ; + Addr // a -- &a ; Assign // val -- ; mem[$1] = val Fassign // val -- ; mem[$1] = val Vassign // val dest -- ; dest.Set(val) @@ -39,6 +39,7 @@ const ( Lower // n1 n2 -- cond ; cond = n1 < n2 Loweri // n1 -- cond ; cond = n1 < $1 Mul // n1 n2 -- prod ; prod = n1*n2 + New // -- x; mem[fp+$1] = new mem[$2] Not // c -- r ; r = !c Pop // v -- Push // -- v @@ -50,7 +51,7 @@ const ( var strop = [...]string{ // for VM tracing. Nop: "Nop", Add: "Add", - Address: "Address", + Addr: "Addr", Assign: "Assign", Call: "Call", Calli: "Calli", @@ -74,6 +75,7 @@ var strop = [...]string{ // for VM tracing. Lower: "Lower", Loweri: "Loweri", Mul: "Mul", + New: "New", Not: "Not", Pop: "Pop", Push: "Push", @@ -87,8 +89,7 @@ type Code [][]int64 // Machine represents a virtual machine. type Machine struct { - code Code // code to execute - // mem []any // memory, as a stack + code Code // code to execute mem []reflect.Value // memory, as a stack ip, fp int // instruction and frame pointer ic uint64 // instruction counter, incremented at each instruction executed @@ -113,7 +114,7 @@ func (m *Machine) Run() (err error) { op3 = strconv.Itoa(int(c[3])) } } - log.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-12s %-4s %-4s] mem:%v\n", ip, sp, fp, strop[c[1]], op2, op3, mem) + log.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-12s %-4s %-4s] mem:%v\n", ip, sp, fp, strop[c[1]], op2, op3, Vstring(mem)) } for { @@ -125,15 +126,15 @@ func (m *Machine) Run() (err error) { mem[sp-2] = reflect.ValueOf(int(mem[sp-2].Int() + mem[sp-1].Int())) mem = mem[:sp-1] case Mul: - mem[sp-2].SetInt(mem[sp-2].Int() * mem[sp-1].Int()) + mem[sp-2] = reflect.ValueOf(int(mem[sp-2].Int() * mem[sp-1].Int())) mem = mem[:sp-1] - case Address: + case Addr: mem[sp-1] = mem[sp-1].Addr() case Assign: - mem[op[2]] = mem[sp-1] + mem[op[2]].Set(mem[sp-1]) mem = mem[:sp-1] case Fassign: - mem[fp+int(op[2])-1] = mem[sp-1] + mem[fp+int(op[2])-1].Set(mem[sp-1]) mem = mem[:sp-1] case Call: nip := int(mem[sp-1].Int()) @@ -161,6 +162,8 @@ func (m *Machine) Run() (err error) { mem[sp-1] = mem[sp-1].Elem() case Dup: mem = append(mem, mem[int(op[2])]) + case New: + mem[int(op[2])+fp-1] = reflect.New(mem[int(op[3])].Type()).Elem() case Equal: mem[sp-2] = reflect.ValueOf(mem[sp-2].Equal(mem[sp-1])) mem = mem[:sp-1] @@ -226,7 +229,9 @@ func (m *Machine) Run() (err error) { case Pop: mem = mem[:sp-int(op[2])] case Push: - mem = append(mem, reflect.ValueOf(int(op[2]))) + //mem = append(mem, reflect.ValueOf(int(op[2]))) + mem = append(mem, reflect.New(reflect.TypeOf(0)).Elem()) + mem[sp].SetInt(op[2]) case Grow: mem = append(mem, make([]reflect.Value, op[2])...) case Return: @@ -236,10 +241,10 @@ func (m *Machine) Run() (err error) { mem = append(mem[:ofp-int(op[2])-int(op[3])-1], mem[sp-int(op[2]):]...) continue case Sub: - mem[sp-2].SetInt(mem[sp-1].Int() - mem[sp-2].Int()) + mem[sp-2] = reflect.ValueOf(int(mem[sp-1].Int() - mem[sp-2].Int())) mem = mem[:sp-1] case Subi: - mem[sp-1].SetInt(mem[sp-1].Int() - op[2]) + mem[sp-1] = reflect.ValueOf(int(mem[sp-1].Int() - op[2])) case Index: mem[sp-2] = mem[sp-1].Index(int(mem[sp-2].Int())) mem = mem[:sp-1] @@ -309,3 +314,14 @@ func slint(a []int64) []int { } return r } + +func Vstring(lv []reflect.Value) string { + s := "[" + for _, v := range lv { + if s != "[" { + s += " " + } + s += fmt.Sprintf("%v", v) + } + return s + "]" +} diff --git a/vm/vm_test.go b/vm/vm_test.go index c9540d2..07c063e 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -23,9 +23,8 @@ func TestVM(t *testing.T) { if err := m.Run(); err != nil { t.Errorf("run error: %v", err) } - t.Log(m.mem) - r := fmt.Sprintf("%v", m.mem[test.start:test.end]) - if r != test.mem { + t.Log(Vstring(m.mem)) + if r := Vstring(m.mem[test.start:test.end]); r != test.mem { t.Errorf("got %v, want %v", r, test.mem) } }) |
