artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,99 @@
|
||||
# STATUS-parse.md — Builder status
|
||||
|
||||
## DONE
|
||||
|
||||
## Current state
|
||||
All gates D1–D6 verified PASS by Adversary @2026-06-15T01:24Z. Phase complete.
|
||||
|
||||
## What was built
|
||||
- `calc/parser.py` — recursive-descent parser exposing `parse(tokens) -> Node`
|
||||
- `calc/test_parser.py` — 27 unittest tests covering D1–D5 structure assertions
|
||||
|
||||
## AST node shapes (stable contract for evaluator)
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Num:
|
||||
value: Union[int, float] # leaf
|
||||
|
||||
@dataclass
|
||||
class BinOp:
|
||||
op: str # '+', '-', '*', '/'
|
||||
left: Node
|
||||
right: Node
|
||||
|
||||
@dataclass
|
||||
class Unary:
|
||||
op: str # '-'
|
||||
operand: Node
|
||||
```
|
||||
|
||||
## Exact verification commands (re-run from any clone)
|
||||
|
||||
### D1 — precedence
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('1+2*3')))"
|
||||
```
|
||||
**Expected:** `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))`
|
||||
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('2*3+1')))"
|
||||
```
|
||||
**Expected:** `BinOp('+', BinOp('*', Num(2), Num(3)), Num(1))`
|
||||
|
||||
### D2 — left associativity
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(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(parse(tokenize('8/4/2')))"
|
||||
```
|
||||
**Expected:** `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))`
|
||||
|
||||
### D3 — parentheses
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(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(parse(tokenize('-5')))"
|
||||
```
|
||||
**Expected:** `Unary('-', Num(5))`
|
||||
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
|
||||
```
|
||||
**Expected:** `Unary('-', BinOp('+', Num(1), Num(2)))`
|
||||
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"
|
||||
```
|
||||
**Expected:** `BinOp('*', Num(3), Unary('-', Num(2)))`
|
||||
|
||||
### D5 — errors (each must raise ParseError, not any other exception)
|
||||
```
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
|
||||
for expr in ['1 +', '(1', '1 2', ')(', '']:
|
||||
try:
|
||||
parse(tokenize(expr))
|
||||
print(f'FAIL {expr!r}: no error raised')
|
||||
except ParseError as e:
|
||||
print(f'OK {expr!r}: ParseError: {e}')
|
||||
except Exception as e:
|
||||
print(f'FAIL {expr!r}: wrong exception {type(e).__name__}: {e}')
|
||||
"
|
||||
```
|
||||
**Expected output:** 5 lines all starting with `OK`.
|
||||
|
||||
### D6 — tests green
|
||||
```
|
||||
python -m unittest -q
|
||||
```
|
||||
**Expected:** `Ran 43 tests in 0.00Xs` `OK` (16 lexer + 27 parser, 0 failures)
|
||||
|
||||
## Commit
|
||||
All source in latest push on main. `calc/parser.py` and `calc/test_parser.py` are the relevant files.
|
||||
Reference in New Issue
Block a user