artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,164 @@
|
||||
# STATUS — Phase parse
|
||||
|
||||
## DONE
|
||||
|
||||
All D1–D6 gates PASS (Adversary-verified @2026-06-15T05:00Z).
|
||||
|
||||
---
|
||||
|
||||
## Gate D6 CLAIMED — PASS
|
||||
|
||||
**WHAT:** `calc/test_parser.py` passes under `python -m unittest`, 0 failures, 37 total tests (18 lexer + 19 parser), covering D1–D5.
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
python -m unittest -q
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
Ran 37 tests in X.XXXs
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
**WHERE:** `calc/test_parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## Gate D5 CLAIMED — awaiting Adversary
|
||||
|
||||
**WHAT:** Each of `"1 +"`, `"(1"`, `"1 2"`, `")("`, and `""` raises `ParseError` (not any other exception).
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
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 no error for {src!r}')
|
||||
except ParseError as e:
|
||||
print(f'OK ParseError for {src!r}: {e}')
|
||||
except Exception as e:
|
||||
print(f'FAIL wrong exception for {src!r}: {type(e).__name__}: {e}')
|
||||
"
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
OK ParseError for '1 +': unexpected token 'EOF' (None)
|
||||
OK ParseError for '(1': unclosed parenthesis, got 'EOF'
|
||||
OK ParseError for '1 2': unexpected token 'NUMBER' (2)
|
||||
OK ParseError for ')(': unexpected token 'RPAREN' (')')
|
||||
OK ParseError for '': empty input
|
||||
```
|
||||
|
||||
**WHERE:** `calc/parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## Gate D4 CLAIMED — awaiting Adversary
|
||||
|
||||
**WHAT:** Unary minus parses correctly for `-5`, `-(1+2)`, `3 * -2`.
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-5')))"
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
Unary(op='-', operand=Num(value=5))
|
||||
Unary(op='-', operand=BinOp(op='+', left=Num(value=1), right=Num(value=2)))
|
||||
BinOp(op='*', left=Num(value=3), right=Unary(op='-', operand=Num(value=2)))
|
||||
```
|
||||
|
||||
**WHERE:** `calc/parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## Gate D3 CLAIMED — awaiting Adversary
|
||||
|
||||
**WHAT:** Parens override precedence: `(1+2)*3` parses as `BinOp(*, BinOp(+, Num(1), Num(2)), Num(3))`.
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('(1+2)*3')))"
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
BinOp(op='*', left=BinOp(op='+', left=Num(value=1), right=Num(value=2)), right=Num(value=3))
|
||||
```
|
||||
|
||||
**WHERE:** `calc/parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## Gate D2 CLAIMED — awaiting Adversary
|
||||
|
||||
**WHAT:** Same-precedence operators associate left: `8-3-2` → `BinOp(-, BinOp(-, Num(8), Num(3)), Num(2))`; `8/4/2` → `BinOp(/, BinOp(/, Num(8), Num(4)), Num(2))`.
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8-3-2')))"
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8/4/2')))"
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
BinOp(op='-', left=BinOp(op='-', left=Num(value=8), right=Num(value=3)), right=Num(value=2))
|
||||
BinOp(op='/', left=BinOp(op='/', left=Num(value=8), right=Num(value=4)), right=Num(value=2))
|
||||
```
|
||||
|
||||
**WHERE:** `calc/parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## Gate D1 CLAIMED — awaiting Adversary
|
||||
|
||||
**WHAT:** `*` and `/` bind tighter than `+` and `-`: `1+2*3` parses as `BinOp(+, Num(1), BinOp(*, Num(2), Num(3)))`.
|
||||
|
||||
**HOW:**
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('1+2*3')))"
|
||||
```
|
||||
|
||||
**EXPECTED:**
|
||||
```
|
||||
BinOp(op='+', left=Num(value=1), right=BinOp(op='*', left=Num(value=2), right=Num(value=3)))
|
||||
```
|
||||
|
||||
**WHERE:** `calc/parser.py` @ commit `866091c`
|
||||
|
||||
---
|
||||
|
||||
## AST Shape
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Num:
|
||||
value: int | float
|
||||
|
||||
@dataclass
|
||||
class BinOp:
|
||||
op: str # '+', '-', '*', '/'
|
||||
left: Node
|
||||
right: Node
|
||||
|
||||
@dataclass
|
||||
class Unary:
|
||||
op: str # '-'
|
||||
operand: Node
|
||||
```
|
||||
|
||||
Grammar:
|
||||
```
|
||||
expr = term (('+' | '-') term)*
|
||||
term = unary (('*' | '/') unary)*
|
||||
unary = '-' unary | primary
|
||||
primary = NUMBER | '(' expr ')'
|
||||
```
|
||||
Reference in New Issue
Block a user