You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.7 KiB
Go

package vm
import (
"fmt"
"testing"
"gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey5/ast"
"gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey5/compiler"
"gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey5/lexer"
"gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey5/object"
"gitea.paas.celticinfo.fr/oabrivard/monkeylang/monkey5/parser"
)
func TestIntegerArithmetic(t *testing.T) {
tests := []vmTestCase{
{"1", 1},
{"2", 2},
{"1 + 2", 3},
}
runVmTests(t, tests)
}
type vmTestCase struct {
input string
expected interface{}
}
func runVmTests(t *testing.T, tests []vmTestCase) {
t.Helper()
for _, tt := range tests {
program := parse(tt.input)
comp := compiler.New()
err := comp.Compile(program)
if err != nil {
t.Fatalf("compiler error: %s", err)
}
vm := New(comp.Bytecode())
err = vm.Run()
if err != nil {
t.Fatalf("vm error: %s", err)
}
stackElem := vm.StackTop()
testExpectedObject(t, tt.expected, stackElem)
}
}
func parse(input string) *ast.Program {
l := lexer.New(input)
p := parser.New(l)
return p.ParseProgram()
}
func testExpectedObject(
t *testing.T,
expected interface{},
actual object.Object,
) {
t.Helper()
switch expected := expected.(type) {
case int:
err := testIntegerObject(int64(expected), actual)
if err != nil {
t.Errorf("testIntegerObject failed: %s", err)
}
}
}
func testIntegerObject(expected int64, actual object.Object) error {
result, ok := actual.(*object.Integer)
if !ok {
return fmt.Errorf("object is not Integer. got=%T (%+v)",
actual, actual)
}
if result.Value != expected {
return fmt.Errorf("object has wrong value. got=%d, want=%d",
result.Value, expected)
}
return nil
}