| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- package vm
- import (
- "fmt"
- "github/runnignwater/monkey/ast"
- "github/runnignwater/monkey/compiler"
- "github/runnignwater/monkey/lexer"
- "github/runnignwater/monkey/object"
- "github/runnignwater/monkey/parser"
- "testing"
- )
- type vmTestCase struct {
- input string
- expected interface{}
- }
- func TestIntegerArithmetic(t *testing.T) {
- tests := []vmTestCase{
- {"1", 1},
- {"2", 2},
- {"1 + 2", 3},
- }
- runVmTests(t, tests)
- }
- 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("compler 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
- }
|