aboutsummaryrefslogtreecommitdiff
path: root/evaluator
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-02-17 23:50:45 -0500
committerBobby <[email protected]>2024-02-17 23:50:45 -0500
commita18137bab2c53655168be9856e28de8c29232994 (patch)
tree9dc1ebbe8e49e97846f944a2e04e017f5dc267e6 /evaluator
parentb3d5ef5c6c3dcb6d1bf707b82e5350168d66d6c5 (diff)
downloadmana-a18137bab2c53655168be9856e28de8c29232994.tar.xz
mana-a18137bab2c53655168be9856e28de8c29232994.zip
Added Evaulator and Object Model
Diffstat (limited to 'evaluator')
-rw-r--r--evaluator/evaluator.go34
-rw-r--r--evaluator/evaluator_test.go44
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
+}