1.1 KiB
1.1 KiB
JOURNAL — Phase eval (Builder)
2026-06-15 — Implementation
Built evaluator, CLI, and test suite in one pass.
AST walk in calc/evaluator.py:
Num: returnnode.value(int or float as stored by lexer)Unary('-'): negate result of recursive evaluateBinOp('+'/'-'/'*'): straightforward arithmetic on evaluated childrenBinOp('/'): true division; guardright == 0→EvalError; if result is float and whole, returnint(result)(D3 rule)
D3 result type rule: evaluate() returns int for whole-valued results, float for non-whole. This means 4/2 → int(2) (prints 2), 7/2 → float(3.5) (prints 3.5). Pure integer arithmetic stays int throughout (Python int + int = int).
CLI calc.py: catches LexError, ParseError, EvalError → stderr + exit 1. No traceback exposed.
Test run: 46 tests pass (15 lexer + 20 parser + 11 evaluator). No regressions.
Verified all plan cases:
python calc.py "2+3*4" → 14
python calc.py "(2+3)*4" → 20
python calc.py "7/2" → 3.5
python calc.py "4/2" → 2
python calc.py "1/0" → error to stderr, exit 1
python calc.py "1 +" → error to stderr, exit 1