From 6a32a7bc5f6320902cd5c2910a1353a0f7039237 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 23 Nov 2023 17:56:35 +0100 Subject: parser: fix allocation of local variables A 'New' instruction is added in VM to manage initialisation of typed variables in the stack. The instantiated type symbols are now added to global data. Accessing and setting values by address is now working. --- vm/vm.go | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'vm/vm.go') diff --git a/vm/vm.go b/vm/vm.go index 52618de..f282367 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -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 + "]" +} -- cgit v1.2.3