artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
134
calculators/builder-solo/run-03/machine-docs/STATUS-parse.md
Normal file
134
calculators/builder-solo/run-03/machine-docs/STATUS-parse.md
Normal file
@ -0,0 +1,134 @@
|
||||
# STATUS-parse.md
|
||||
|
||||
## AST Node Shapes
|
||||
|
||||
```
|
||||
Num(value) — numeric literal (int or float)
|
||||
Unary('-', operand) — unary negation; operand is any Node
|
||||
BinOp(op, left, right) — binary operation; op in {'+', '-', '*', '/'}
|
||||
```
|
||||
|
||||
All nodes are Python dataclasses with `__repr__` and structural equality via `__eq__`.
|
||||
|
||||
## Gate Verification
|
||||
|
||||
### D1 — Precedence (`*`/`/` bind tighter than `+`/`-`)
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
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)))`
|
||||
**Observed:** `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))` ✓
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
### D2 — Left Associativity (same-precedence operators associate left)
|
||||
|
||||
**Commands:**
|
||||
```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:**
|
||||
- `8-3-2` → `BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))`
|
||||
- `8/4/2` → `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))`
|
||||
|
||||
**Observed:**
|
||||
- `BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))` ✓
|
||||
- `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))` ✓
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
### D3 — Parentheses override precedence
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
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))`
|
||||
**Observed:** `BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))` ✓
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
### D4 — Unary minus (leading and nested)
|
||||
|
||||
**Commands:**
|
||||
```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:**
|
||||
- `-5` → `Unary('-', Num(5))`
|
||||
- `-(1+2)` → `Unary('-', BinOp('+', Num(1), Num(2)))`
|
||||
- `3 * -2` → `BinOp('*', Num(3), Unary('-', Num(2)))`
|
||||
|
||||
**Observed:**
|
||||
- `Unary('-', Num(5))` ✓
|
||||
- `Unary('-', BinOp('+', Num(1), Num(2)))` ✓
|
||||
- `BinOp('*', Num(3), Unary('-', Num(2)))` ✓
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
### D5 — Malformed input raises ParseError
|
||||
|
||||
**Commands:** `parse(tokenize(x))` for each bad input x
|
||||
|
||||
| Input | Expected | Observed |
|
||||
|---------|--------------------|--------------------------------------------------|
|
||||
| `"1 +"` | ParseError | `ParseError: unexpected end of input` ✓ |
|
||||
| `"(1"` | ParseError | `ParseError: expected ')' but got 'EOF'` ✓ |
|
||||
| `"1 2"` | ParseError | `ParseError: unexpected token 'NUMBER' (2)...` ✓|
|
||||
| `")("` | ParseError | `ParseError: unexpected token 'RPAREN' (')')` ✓ |
|
||||
| `""` | ParseError | `ParseError: empty input` ✓ |
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
### D6 — Tests green
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
python -m unittest -q
|
||||
```
|
||||
**Expected:** 0 failures
|
||||
**Observed:**
|
||||
```
|
||||
Ran 46 tests in 0.001s
|
||||
OK
|
||||
```
|
||||
|
||||
**Status: PASS**
|
||||
|
||||
---
|
||||
|
||||
## Exact Shape Assertion (for cold verification)
|
||||
|
||||
```python
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, BinOp, Num, Unary
|
||||
|
||||
# D1
|
||||
assert parse(tokenize('1+2*3')) == BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))
|
||||
# D2
|
||||
assert parse(tokenize('8-3-2')) == BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))
|
||||
assert parse(tokenize('8/4/2')) == BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))
|
||||
# D3
|
||||
assert parse(tokenize('(1+2)*3')) == BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))
|
||||
# D4
|
||||
assert parse(tokenize('-5')) == Unary('-', Num(5))
|
||||
assert parse(tokenize('-(1+2)')) == Unary('-', BinOp('+', Num(1), Num(2)))
|
||||
assert parse(tokenize('3 * -2')) == BinOp('*', Num(3), Unary('-', Num(2)))
|
||||
```
|
||||
|
||||
## DONE
|
||||
Reference in New Issue
Block a user