diff options
Diffstat (limited to 'vm1')
| -rw-r--r-- | vm1/vm.go | 31 | ||||
| -rw-r--r-- | vm1/vm_test.go | 89 |
2 files changed, 60 insertions, 60 deletions
@@ -16,7 +16,6 @@ const ( CallX // f [a1 .. ai] -- [r1 .. rj] ; r1, ... = mem[f](a1, ...) Dup // addr -- value ; value = mem[addr] Fdup // addr -- value ; value = mem[addr] - Enter // -- ; enter frame: push(fp), fp = sp Exit // -- ; Jump // -- ; ip += $1 JumpTrue // cond -- ; if cond { ip += $1 } @@ -38,7 +37,6 @@ var strop = [...]string{ // for VM tracing. CallX: "CallX", Dup: "Dup", Fdup: "Fdup", - Enter: "Enter", Exit: "Exit", Jump: "Jump", JumpTrue: "JumpTrue", @@ -67,11 +65,15 @@ func (m *Machine) Run() { defer func() { m.mem, m.ip, m.fp = mem, ip, fp }() trace := func() { - var op2 string - if len(code[ip]) > 2 { - op2 = strconv.Itoa(int(code[ip][2])) + var op2, op3 string + c := code[ip] + if l := len(c); l > 2 { + op2 = strconv.Itoa(int(c[2])) + if l > 3 { + op3 = strconv.Itoa(int(c[3])) + } } - fmt.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-9s %-4s] mem:%v\n", ip, sp, fp, strop[code[ip][1]], op2, mem) + fmt.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-9s %-4s %-4s] mem:%v\n", ip, sp, fp, strop[c[1]], op2, op3, mem) } _ = trace @@ -86,7 +88,8 @@ func (m *Machine) Run() { mem[op[2]] = mem[sp-1] mem = mem[:sp-1] case Call: - mem = append(mem, ip+1) + mem = append(mem, ip+1, fp) + fp = sp + 2 ip += int(op[2]) continue case CallX: // Should be made optional. @@ -102,9 +105,6 @@ func (m *Machine) Run() { } case Dup: mem = append(mem, mem[int(op[2])]) - case Enter: - mem = append(mem, fp) - fp = sp + 1 case Exit: return case Fdup: @@ -139,7 +139,7 @@ func (m *Machine) Run() { ip = mem[fp-2].(int) ofp := fp fp = mem[fp-1].(int) - mem = append(mem[:ofp-int(op[2])-2], mem[sp-int(op[2]):]...) + mem = append(mem[:ofp-int(op[2])-int(op[3])-1], mem[sp-int(op[2]):]...) continue case Sub: mem[sp-2] = mem[sp-2].(int) - mem[sp-1].(int) @@ -164,10 +164,13 @@ func (m *Machine) Pop() (v any) { l := len(m.mem) - 1; v = m.mem[l]; m.mem // Disassemble returns the code as a readable string. func Disassemble(code [][]int64) (asm string) { for _, op := range code { - if len(op) > 2 { - asm += fmt.Sprintf("%s %d\n", strop[op[1]], op[2]) - } else { + switch len(op) { + case 2: asm += strop[op[1]] + "\n" + case 3: + asm += fmt.Sprintf("%s %d\n", strop[op[1]], op[2]) + case 4: + asm += fmt.Sprintf("%s %d %d\n", strop[op[1]], op[2], op[3]) } } return asm diff --git a/vm1/vm_test.go b/vm1/vm_test.go index 53b0d07..cea4f29 100644 --- a/vm1/vm_test.go +++ b/vm1/vm_test.go @@ -62,60 +62,57 @@ var tests = []struct { start: 0, end: 2, mem: "[6 <nil>]", }, { // #02 -- Defining and calling a function in VM. code: [][]int64{ - {0, Jump, 4}, // 0 - {0, Enter}, // 1 - {0, Push, 3}, // 2 - {0, Return, 1}, // 3 - {0, Push, 1}, // 4 - {0, Call, -4}, // 5 - {0, Exit}, // 6 + {0, Jump, 3}, // 0 + {0, Push, 3}, // 1 + {0, Return, 1, 1}, // 2 + {0, Push, 1}, // 3 + {0, Call, -3}, // 4 + {0, Exit}, // 5 }, start: 0, end: 1, mem: "[3]", }, { // #03 -- Fibonacci numbers, hand written. Showcase recursivity. code: [][]int64{ - {0, Jump, 18}, // 0, goto 18 - {0, Enter}, // 1, - {0, Fdup, -2}, // 2, [i] - {0, Push, 2}, // 3, [i 2] - {0, Lower}, // 4, [true/false] - {0, JumpTrue, 11}, // 5, [], goto 16 - {0, Fdup, -2}, // 6 [i] - {0, Push, 2}, // 7 [i 2] - {0, Sub}, // 8 [(i-2)] - {0, Call, -8}, // 9 [fib(i-2)] - {0, Fdup, -2}, // 10 [fib(i-2) i] - {0, Push, 1}, // 11 [(i-2) i 1] - {0, Sub}, // 12 [(i-2) (i-1)] - {0, Call, -12}, // 13 [fib(i-2) fib(i-1)] - {0, Add}, // 14 [fib(i-2)+fib(i-1)] - {0, Return, 1}, // 15 return i - {0, Fdup, -2}, // 16 [i] - {0, Return, 1}, // 17 return i - {0, Push, 6}, // 18 [1] - {0, Call, -18}, // 19 [fib(*1)] - {0, Exit}, // 20 + {0, Jump, 17}, // 0 + {0, Fdup, -2}, // 1 [i] + {0, Push, 2}, // 2 [i 2] + {0, Lower}, // 3 [true/false] + {0, JumpTrue, 11}, // 4 [], goto 16 + {0, Fdup, -2}, // 5 [i] + {0, Push, 2}, // 6 [i 2] + {0, Sub}, // 7 [(i-2)] + {0, Call, -7}, // 8 [fib(i-2)] + {0, Fdup, -2}, // 9 [fib(i-2) i] + {0, Push, 1}, // 10 [(i-2) i 1] + {0, Sub}, // 11 [(i-2) (i-1)] + {0, Call, -11}, // 12 [fib(i-2) fib(i-1)] + {0, Add}, // 13 [fib(i-2)+fib(i-1)] + {0, Return, 1, 1}, // 14 return i + {0, Fdup, -2}, // 15 [i] + {0, Return, 1, 1}, // 16 return i + {0, Push, 6}, // 17 [1] + {0, Call, -17}, // 18 [fib(*1)] + {0, Exit}, // 19 }, start: 0, end: 1, mem: "[8]", }, { // #04 -- Fibonacci with some immediate instructions. code: [][]int64{ - {0, Jump, 15}, // 0, goto 15 - {0, Enter}, // 1, - {0, Fdup, -2}, // 2, [i] - {0, Loweri, 2}, // 3, [true/false] - {0, JumpTrue, 9}, // 4, [], goto 13 - {0, Fdup, -2}, // 5 [i] - {0, Subi, 2}, // 6 [(i-2)] - {0, Call, -6}, // 7 [fib(i-2)] - {0, Fdup, -2}, // 8 [fib(i-2) i] - {0, Subi, 1}, // 9 [(i-2) (i-1)] - {0, Call, -9}, // 10 [fib(i-2) fib(i-1)], call 1 - {0, Add}, // 11 [fib(i-2)+fib(i-1)] - {0, Return, 1}, // 12 return i - {0, Fdup, -2}, // 13 [i] - {0, Return, 1}, // 14 return i - {0, Push, 6}, // 15 [1] - {0, Call, -15}, // 16 [fib(*1)], call 1 - {0, Exit}, // 17 + {0, Jump, 14}, // 0 + {0, Fdup, -2}, // 1 [i] + {0, Loweri, 2}, // 2 [true/false] + {0, JumpTrue, 9}, // 3 [], goto 13 + {0, Fdup, -2}, // 4 [i] + {0, Subi, 2}, // 5 [(i-2)] + {0, Call, -5}, // 6 [fib(i-2)] + {0, Fdup, -2}, // 7 [fib(i-2) i] + {0, Subi, 1}, // 8 [(i-2) (i-1)] + {0, Call, -8}, // 9 [fib(i-2) fib(i-1)], call 1 + {0, Add}, // 10 [fib(i-2)+fib(i-1)] + {0, Return, 1, 1}, // 11 return i + {0, Fdup, -2}, // 12 [i] + {0, Return, 1, 1}, // 13 return i + {0, Push, 6}, // 14 [1] + {0, Call, -14}, // 15 [fib(*1)], call 1 + {0, Exit}, // 16 }, start: 0, end: 1, mem: "[8]", }} |
