summaryrefslogtreecommitdiff
path: root/vm1/vm_test.go
blob: 33ace0097582be7b453845bb91b906c87e5f67a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package vm1

import (
	"fmt"
	"testing"
)

func TestVM(t *testing.T) {
	for _, test := range tests {
		t.Run("", func(t *testing.T) {
			m := &Machine{}
			for _, v := range test.sym {
				m.Push(v)
			}
			m.PushCode(test.code)
			m.Run()
			t.Log(m.mem)
			r := fmt.Sprintf("%v", m.mem[test.start:test.end])
			if r != test.mem {
				t.Errorf("got %v, want %v", r, test.mem)
			}
		})
	}
}

var tests = []struct {
	sym        []any     // initial memory values
	code       [][]int64 // bytecode to execute
	start, end int       //
	mem        string    // expected memory content
}{{ // #00 -- A simple addition.
	code: [][]int64{
		{Push, 1},
		{Push, 2},
		{Add},
		{Exit},
	},
	start: 0, end: 1, mem: "[3]",
}, { // #01 -- Calling a function defined outside the VM.
	sym: []any{fmt.Println, "Hello"},
	code: [][]int64{
		{CallX, 1},
		{Exit},
	},
	start: 0, end: 2, mem: "[6 <nil>]",
}, { // #02 -- Defining and calling a function in VM.
	code: [][]int64{
		{Jump, 4},   // 0
		{Enter},     // 1
		{Push, 3},   // 2
		{Return, 1}, // 3
		{Push, 1},   // 4
		{Call, -4},  // 5
		{Exit},      // 6
	},
	start: 0, end: 1, mem: "[3]",
}, { // #03 -- Fibonacci numbers, hand written. Showcase recursivity.
	code: [][]int64{
		{Jump, 18},     // 0, goto 18
		{Enter},        // 1,
		{Fdup, -2},     // 2, [i]
		{Push, 2},      // 3, [i 2]
		{Lower},        // 4, [true/false]
		{JumpTrue, 11}, // 5, [], goto 16
		{Fdup, -2},     // 6  [i]
		{Push, 2},      // 7  [i 2]
		{Sub},          // 8  [(i-2)]
		{Call, -8},     // 9  [fib(i-2)]
		{Fdup, -2},     // 10 [fib(i-2) i]
		{Push, 1},      // 11 [(i-2) i 1]
		{Sub},          // 12 [(i-2) (i-1)]
		{Call, -12},    // 13 [fib(i-2) fib(i-1)]
		{Add},          // 14 [fib(i-2)+fib(i-1)]
		{Return, 1},    // 15 return i
		{Fdup, -2},     // 16 [i]
		{Return, 1},    // 17 return i
		{Push, 6},      // 18 [1]
		{Call, -18},    // 19 [fib(*1)]
		{Exit},         // 20
	},
	start: 0, end: 1, mem: "[8]",
}}