artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,105 @@
|
||||
# STATUS — phase `parse`
|
||||
|
||||
## DONE
|
||||
|
||||
## Gates
|
||||
- D1 (precedence): PASS @2026-06-15T03:40Z
|
||||
- D2 (left assoc): PASS @2026-06-15T03:40Z
|
||||
- D3 (parentheses): PASS @2026-06-15T03:40Z
|
||||
- D4 (unary minus): PASS @2026-06-15T03:40Z
|
||||
- D5 (errors): PASS @2026-06-15T03:40Z
|
||||
- D6 (tests green): PASS @2026-06-15T03:40Z
|
||||
|
||||
## Source files
|
||||
- `calc/parser.py` — AST node definitions + recursive-descent parser
|
||||
- `calc/test_parser.py` — 20 unittest cases covering D1–D5
|
||||
|
||||
## AST shape
|
||||
|
||||
Nodes are dataclasses defined in `calc/parser.py`:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Num:
|
||||
value: Union[int, float]
|
||||
|
||||
@dataclass
|
||||
class BinOp:
|
||||
op: str # '+', '-', '*', '/'
|
||||
left: Node
|
||||
right: Node
|
||||
|
||||
@dataclass
|
||||
class Unary:
|
||||
op: str # '-'
|
||||
operand: Node
|
||||
```
|
||||
|
||||
## Verify commands (cold)
|
||||
|
||||
```bash
|
||||
python -m unittest -q
|
||||
```
|
||||
Expected: `Ran 36 tests in Xs` / `OK` (0 failures)
|
||||
|
||||
```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)))`
|
||||
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8-3-2')))"
|
||||
```
|
||||
Expected: `BinOp(op='-', left=BinOp(op='-', left=Num(value=8), right=Num(value=3)), right=Num(value=2))`
|
||||
|
||||
```bash
|
||||
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=4)), right=Num(value=2))`
|
||||
|
||||
```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))`
|
||||
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-5')))"
|
||||
```
|
||||
Expected: `Unary(op='-', operand=Num(value=5))`
|
||||
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
|
||||
```
|
||||
Expected: `Unary(op='-', operand=BinOp(op='+', left=Num(value=1), right=Num(value=2)))`
|
||||
|
||||
```bash
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"
|
||||
```
|
||||
Expected: `BinOp(op='*', left=Num(value=3), right=Unary(op='-', operand=Num(value=2)))`
|
||||
|
||||
```bash
|
||||
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'{expr!r}: NO ERROR (FAIL)')
|
||||
except ParseError as e:
|
||||
print(f'{expr!r}: ParseError OK')
|
||||
"
|
||||
```
|
||||
Expected: all 5 lines print `ParseError OK`
|
||||
|
||||
## Gate-specific DoD mapping
|
||||
|
||||
**D1 — precedence:** `1+2*3` parses as `1+(2*3)` — `*` is under the right child of `+`, not the other way.
|
||||
|
||||
**D2 — left assoc:** `8-3-2` → left-leaning tree; `8/4/2` → left-leaning tree. The while-loop in `_expr`/`_term` naturally accumulates left.
|
||||
|
||||
**D3 — parens:** `(1+2)*3` → `BinOp('*', BinOp('+', ...), Num(3))` — `+` is under `*`'s left child.
|
||||
|
||||
**D4 — unary:** `-5` → `Unary`, `-(1+2)` → `Unary(BinOp(...))`, `3*-2` → `BinOp('*', Num(3), Unary(...))`.
|
||||
|
||||
**D5 — errors:** `"1 +"`, `"(1"`, `"1 2"`, `")("`, `""` all raise `ParseError` (not Python built-ins).
|
||||
|
||||
**D6 — tests:** `python -m unittest -q` → 36 tests, 0 failures.
|
||||
Reference in New Issue
Block a user