Step 6: Implement evaluator with TDD
- Eval(ast.Node) (float64, error) - recursive AST walker
- Handles all 4 operators: +, -, *, /
- Division by zero returns error
- Error propagation from sub-expressions
- 10 unit tests covering: single number, all operators, nested/deep
expressions, division by zero (direct and in sub-expr), floats
diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go
new file mode 100644
index 0000000..447adbe
--- /dev/null
+++ b/evaluator/evaluator.go
@@ -0,0 +1,45 @@
+package evaluator
+
+import (
+ "fmt"
+ "matheval/ast"
+ "matheval/token"
+)
+
+// Eval evaluates an AST node and returns the result.
+// Returns an error on division by zero.
+func Eval(node ast.Node) (float64, error) {
+ switch n := node.(type) {
+ case *ast.NumberLit:
+ return n.Value, nil
+
+ case *ast.BinaryExpr:
+ left, err := Eval(n.Left)
+ if err != nil {
+ return 0, err
+ }
+ right, err := Eval(n.Right)
+ if err != nil {
+ return 0, err
+ }
+
+ switch n.Op {
+ case token.Plus:
+ return left + right, nil
+ case token.Minus:
+ return left - right, nil
+ case token.Star:
+ return left * right, nil
+ case token.Slash:
+ if right == 0 {
+ return 0, fmt.Errorf("division by zero")
+ }
+ return left / right, nil
+ default:
+ return 0, fmt.Errorf("unknown operator: %v", n.Op)
+ }
+
+ default:
+ return 0, fmt.Errorf("unknown node type: %T", node)
+ }
+}