artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,78 @@
|
||||
# STATUS — Phase `parse`
|
||||
|
||||
## DONE
|
||||
|
||||
Gate: D1,D2,D3,D4,D5,D6 — all PASS (Adversary-verified @2026-06-15T04:03Z, commit e9a5152)
|
||||
|
||||
## What is claimed
|
||||
|
||||
All DoD gates D1–D6 implemented and all 20 parser tests pass (34 total across lex+parse).
|
||||
|
||||
**Commit:** see `claim(D1–D6)` commit on main.
|
||||
|
||||
## How to verify (cold, from a fresh clone)
|
||||
|
||||
```bash
|
||||
cd <clone>
|
||||
python -m unittest -q
|
||||
# Expect: Ran 34 tests in ~0.001s — OK
|
||||
|
||||
# D1 — precedence (*/ tighter than +-)
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('1+2*3'))))"
|
||||
# Expected: BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))
|
||||
|
||||
# D2 — left associativity
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('8-3-2'))))"
|
||||
# Expected: BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('8/4/2'))))"
|
||||
# Expected: BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))
|
||||
|
||||
# D3 — parentheses override
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('(1+2)*3'))))"
|
||||
# Expected: BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))
|
||||
|
||||
# D4 — unary minus
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('-5'))))"
|
||||
# Expected: Unary('-', Num(5))
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('-(1+2)'))))"
|
||||
# Expected: Unary('-', BinOp('+', Num(1), Num(2)))
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('3 * -2'))))"
|
||||
# Expected: BinOp('*', Num(3), Unary('-', Num(2)))
|
||||
|
||||
# D5 — errors raise ParseError
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
|
||||
for src in ['1 +', '(1', '1 2', ')(', '']:
|
||||
try:
|
||||
parse(tokenize(src))
|
||||
print(f'FAIL: {src!r} did not raise')
|
||||
except ParseError as e:
|
||||
print(f'OK ParseError: {src!r}')
|
||||
"
|
||||
```
|
||||
|
||||
## Expected outputs
|
||||
|
||||
- `python -m unittest -q` → `Ran 34 tests in ...s\nOK`
|
||||
- `1+2*3` → `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))`
|
||||
- `8-3-2` → `BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))`
|
||||
- `8/4/2` → `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))`
|
||||
- `(1+2)*3` → `BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))`
|
||||
- `-5` → `Unary('-', Num(5))`
|
||||
- `-(1+2)` → `Unary('-', BinOp('+', Num(1), Num(2)))`
|
||||
- `3 * -2` → `BinOp('*', Num(3), Unary('-', Num(2)))`
|
||||
- All 5 malformed inputs → `OK ParseError`
|
||||
|
||||
## AST shape (for evaluator)
|
||||
|
||||
```
|
||||
Num(value) — numeric literal; value is int or float
|
||||
BinOp(op, left, right) — binary; op in {'+', '-', '*', '/'}
|
||||
Unary(op, operand) — unary minus; op == '-'
|
||||
```
|
||||
|
||||
All three are `@dataclass`, so `==` comparison works for tests.
|
||||
|
||||
## Where
|
||||
|
||||
- `calc/parser.py` — parser implementation
|
||||
- `calc/test_parser.py` — 20 parser tests covering D1–D5
|
||||
Reference in New Issue
Block a user