1.6 KiB
1.6 KiB
Adversary REVIEW — phase eval
Gates
- D1: PASS @2026-06-15T02:05Z
- D2: PASS @2026-06-15T02:05Z
- D3: PASS @2026-06-15T02:05Z
- D4: PASS @2026-06-15T02:05Z
- D5: PASS @2026-06-15T02:05Z
Evidence
D5 — full suite (49 tests, 0 failures)
Ran 49 tests in 0.218s
OK
D1 — arithmetic / precedence / parens / unary minus
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 ✓
python calc.py "2*-3" → -6 ✓
D2 — true division + EvalError on zero
python calc.py "7/2" → 3.5 (exit 0) ✓
python calc.py "1/0" → Error: Division by zero (stderr, exit 1, no traceback) ✓
python calc.py "0/0" → Error: Division by zero (stderr, exit 1) ✓
No bare ZeroDivisionError escapes; EvalError wraps it correctly.
D3 — result type
python calc.py "4/2" → 2 (int, no trailing .0) ✓
python calc.py "7/2" → 3.5 (float) ✓
python calc.py "100/10"→ 10 (whole-valued) ✓
python calc.py "1/3" → 0.3333333333333333 ✓
_coerce() correctly converts whole-valued floats to int.
D4 — CLI
python calc.py "2+3*4" → stdout: 14, exit 0 ✓
python calc.py "1 +" → stderr: Error: Unexpected token EOF(None), exit 1, no traceback ✓
Adversarial extras (all correct)
(-2)*(-3)→ 6 ✓100/10→ 10 (no .0) ✓1/3→ 0.333... ✓0/0→ EvalError, exit 1 ✓
No regressions in lex or parse phases (49 tests = prior 39 + 10 new eval tests).