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)
+	}
+}