2.3 KiB
DONE
Phase: eval — evaluator + CLI All DoD items self-certified (BUILD phase — deferred Adversary review).
Files created
calc/evaluator.py—EvalError,evaluate(node) -> int | floatcalc.py— top-level CLIcalc/test_evaluator.py— 22 new unittest tests covering D1–D4
D1 — arithmetic
WHAT: evaluate(parse(tokenize(s))) correct for +, -, *, /, precedence, parens, unary minus.
HOW:
python calc.py "2+3*4" # → 14
python calc.py "(2+3)*4" # → 20
python calc.py "8-3-2" # → 3
python calc.py "-2+5" # → 3 (requires shell quoting awareness)
python calc.py "2*-3" # → -6
EXPECTED: outputs above
WHERE: calc/evaluator.py evaluate()
D2 — division
WHAT: / is true division; division by zero raises EvalError.
HOW:
python calc.py "7/2" # → 3.5
python calc.py "1/0" # → stderr error, exit 1
EXPECTED: 3.5 for 7/2; non-zero exit + stderr for 1/0
WHERE: calc/evaluator.py BinOp / branch
D3 — result type
WHAT: Whole-valued → int (no .0), non-whole → float.
HOW:
python calc.py "4/2" # → 2 (not 2.0)
python calc.py "7/2" # → 3.5
EXPECTED: 2 and 3.5
WHERE: calc/evaluator.py — if isinstance(result, float) and result == int(result): return int(result)
D4 — CLI
WHAT: python calc.py "2+3*4" → 14, exit 0; error → stderr, non-zero exit, no traceback.
HOW:
python calc.py "2+3*4" # → 14, exit 0
python calc.py "1 +" # → error to stderr, exit 1
EXPECTED: as above
WHERE: calc.py main()
D5 — tests green + end-to-end
WHAT: Full test suite (lex + parse + eval) passes; 0 failures.
HOW: python -m unittest -q
EXPECTED:
Ran 56 tests in 0.226s
OK
WHERE: calc/test_lexer.py (14) + calc/test_parser.py (20) + calc/test_evaluator.py (22)
Verify commands (from eval.md, verbatim)
python -m unittest -q # Ran 56 tests in ...s OK
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, non-zero exit
python calc.py "1 +" # error to stderr, non-zero exit
Commit: (see git log — latest commit on main)