diff options
| author | Bobby <[email protected]> | 2024-02-17 23:50:45 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2024-02-17 23:50:45 -0500 |
| commit | a18137bab2c53655168be9856e28de8c29232994 (patch) | |
| tree | 9dc1ebbe8e49e97846f944a2e04e017f5dc267e6 /evaluator | |
| parent | b3d5ef5c6c3dcb6d1bf707b82e5350168d66d6c5 (diff) | |
| download | mana-a18137bab2c53655168be9856e28de8c29232994.tar.xz mana-a18137bab2c53655168be9856e28de8c29232994.zip | |
Added Evaulator and Object Model
Diffstat (limited to 'evaluator')
| -rw-r--r-- | evaluator/evaluator.go | 34 | ||||
| -rw-r--r-- | evaluator/evaluator_test.go | 44 |
2 files changed, 78 insertions, 0 deletions
diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go new file mode 100644 index 0000000..8d1b26d --- /dev/null +++ b/evaluator/evaluator.go @@ -0,0 +1,34 @@ +package evaluator + +import ( + "mana/ast" + "mana/object" +) + +// Eval evaluates the given ast.Node and returns an object.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) + + // Expressions + 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 +} diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go new file mode 100644 index 0000000..cd1edb1 --- /dev/null +++ b/evaluator/evaluator_test.go @@ -0,0 +1,44 @@ +package evaluator + +import ( + "mana/lexer" + "mana/object" + "mana/parser" + + "testing" +) + +func TestEvalIntegerExpression(t *testing.T) { + tests := []struct { + input string + expected int64 + }{ + {"5", 5}, + {"10", 10}, + } + + for _, tt := range tests { + evalated := testEval(tt.input) + testIntegerObject(t, evalated, tt.expected) + } +} + +func testEval(input string) object.Object { + l := lexer.New(input) + p := parser.New(l) + program := p.ParseProgram() + return Eval(program) +} + +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 +} |
