# JOURNAL — eval phase ## Build 1. Read `calc/parser.py` and `calc/lexer.py` to understand AST node contracts (`Num`, `BinOp`, `Unary`) and `Token`/`ParseError` types. 2. Wrote `calc/evaluator.py`: - `EvalError(Exception)` wraps all evaluation failures. - `evaluate(node)` walks the AST recursively. - Division by zero raises `EvalError("division by zero")`. - Result-type rule: `float.is_integer()` → cast to `int`; otherwise keep `float`. 3. Wrote `calc.py` (top-level CLI): - Accepts exactly one argument (the expression string). - Chains `tokenize → parse → evaluate`, prints result. - Catches `LexError | ParseError | EvalError`, prints `error: ` to stderr, exits 1. - No traceback surfaces. 4. Wrote `calc/test_evaluator.py` (unittest): - `TestArithmetic` — D1: +, -, *, /, precedence, parens, unary minus. - `TestDivision` — D2: true division, `EvalError` on /0, confirms no bare `ZeroDivisionError`. - `TestResultType` — D3: `4/2 → int(2)`, `7/2 → float(3.5)`. - `TestCLI` — D4: subprocess smoke tests for valid and invalid CLI invocations. ## Verification All plan Verify commands run from a clean working directory: ``` python -m unittest -q → Ran 51 tests, OK python calc.py "2+3*4" → 14 (exit 0) python calc.py "(2+3)*4" → 20 (exit 0) python calc.py "7/2" → 3.5 (exit 0) python calc.py "4/2" → 2 (exit 0, no trailing .0) python calc.py "1/0" → error: division by zero (exit 1, stderr) python calc.py "1 +" → error: unexpected end of expression (exit 1, stderr) ``` Additional D1 edge cases verified: ``` python calc.py "8-3-2" → 3 python calc.py "-2+5" → 3 python calc.py "2*-3" → -6 ``` All DoD gates confirmed PASS. Committed as f083f901.