Bladeren bron

staring evaluation process - A Tree-Walking interpreter

simon 3 jaren geleden
bovenliggende
commit
711f30b76f
3 gewijzigde bestanden met toevoegingen van 113 en 0 verwijderingen
  1. 32 0
      evaluator/evaluator.go
  2. 44 0
      evaluator/evaluator_test.go
  3. 37 0
      object/object.go

+ 32 - 0
evaluator/evaluator.go

@@ -0,0 +1,32 @@
+package evaluator
+
+import (
+	"github/runnignwater/monkey/ast"
+	"github/runnignwater/monkey/object"
+)
+
+func Eval(node ast.Node) object.Object {
+	switch node := node.(type) {
+	// Statements
+	case *ast.Program:
+		return evalStatements(node.Statements)
+
+	case *ast.ExpressionStatement:
+		return Eval(node.Expression)
+
+	// Expression
+	case *ast.IntegerLiteral:
+		return &object.Integer{Value: node.Value}
+	}
+
+	return nil
+}
+
+func evalStatements(stmts []ast.Statement) object.Object {
+	var result object.Object
+
+	for _, statement := range stmts {
+		result = Eval(statement)
+	}
+	return result
+}

+ 44 - 0
evaluator/evaluator_test.go

@@ -0,0 +1,44 @@
+package evaluator
+
+import (
+	"github/runnignwater/monkey/lexer"
+	"github/runnignwater/monkey/object"
+	"github/runnignwater/monkey/parser"
+	"testing"
+)
+
+func TestEvalIntegerExpression(t *testing.T) {
+	tests := []struct {
+		input    string
+		expected int64
+	}{
+		{"5", 5},
+		{"10", 10},
+	}
+
+	for _, tt := range tests {
+		evaluated := testEval(tt.input)
+		testIntegerObject(t, evaluated, tt.expected)
+	}
+}
+
+func testIntegerObject(t *testing.T, obj object.Object, expected int64) bool {
+	result, ok := obj.(*object.Integer)
+	if !ok {
+		t.Errorf("object is not Integer. got=%T (%+v)", obj, obj)
+		return false
+	}
+	if result.Value != expected {
+		t.Errorf("object has wrong value. got=%d, want=%d", result.Value, expected)
+		return false
+	}
+	return true
+}
+
+func testEval(input string) object.Object {
+	l := lexer.New(input)
+	p := parser.New(l)
+	program := p.ParseProgram()
+
+	return Eval(program)
+}

+ 37 - 0
object/object.go

@@ -0,0 +1,37 @@
+package object
+
+import "fmt"
+
+// ObjType type of object
+type ObjType string
+
+const (
+	IntegerObj = "INTEGER"
+	BooleanObj = "BOOLEAN"
+	NullObj    = "NULL"
+)
+
+// Object source code as an Object
+type Object interface {
+	Type() ObjType
+	Inspect() string
+}
+
+type Integer struct {
+	Value int64
+}
+
+func (i *Integer) Type() ObjType   { return IntegerObj }
+func (i *Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) }
+
+type Boolean struct {
+	Value bool
+}
+
+func (b *Boolean) Type() ObjType   { return BooleanObj }
+func (b *Boolean) Inspect() string { return fmt.Sprintf("%t", b.Value) }
+
+type Null struct{}
+
+func (n *Null) Type() ObjType   { return NullObj }
+func (n *Null) Inspect() string { return "null" }