vm_test.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package vm
  2. import (
  3. "fmt"
  4. "github/runnignwater/monkey/ast"
  5. "github/runnignwater/monkey/compiler"
  6. "github/runnignwater/monkey/lexer"
  7. "github/runnignwater/monkey/object"
  8. "github/runnignwater/monkey/parser"
  9. "testing"
  10. )
  11. type vmTestCase struct {
  12. input string
  13. expected interface{}
  14. }
  15. func TestIntegerArithmetic(t *testing.T) {
  16. tests := []vmTestCase{
  17. {"1", 1},
  18. {"2", 2},
  19. {"1 + 2", 3},
  20. }
  21. runVmTests(t, tests)
  22. }
  23. func runVmTests(t *testing.T, tests []vmTestCase) {
  24. t.Helper()
  25. for _, tt := range tests {
  26. program := parse(tt.input)
  27. comp := compiler.New()
  28. err := comp.Compile(program)
  29. if err != nil {
  30. t.Fatalf("compler error: %s", err)
  31. }
  32. vm := New(comp.ByteCode())
  33. err = vm.Run()
  34. if err != nil {
  35. t.Fatalf("vm error: %s", err)
  36. }
  37. stackElem := vm.StackTop()
  38. testExpectedObject(t, tt.expected, stackElem)
  39. }
  40. }
  41. func parse(input string) *ast.Program {
  42. l := lexer.New(input)
  43. p := parser.New(l)
  44. return p.ParseProgram()
  45. }
  46. func testExpectedObject(
  47. t *testing.T,
  48. expected interface{},
  49. actual object.Object,
  50. ) {
  51. t.Helper()
  52. switch expected := expected.(type) {
  53. case int:
  54. err := testIntegerObject(int64(expected), actual)
  55. if err != nil {
  56. t.Errorf("testIntegerObject failed: %s", err)
  57. }
  58. }
  59. }
  60. func testIntegerObject(expected int64, actual object.Object) error {
  61. result, ok := actual.(*object.Integer)
  62. if !ok {
  63. return fmt.Errorf("object is not Integer. got=%T (%+v)", actual, actual)
  64. }
  65. if result.Value != expected {
  66. return fmt.Errorf("object has wrong value. got=%d, want=%d", result.Value, expected)
  67. }
  68. return nil
  69. }