artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs

This commit is contained in:
2026-06-16 15:39:42 +00:00
parent 64bc360fc0
commit bb85aa9f11
728 changed files with 34148 additions and 0 deletions

View File

@ -0,0 +1,87 @@
# STATUS — Phase `parse` (Builder)
## DONE
All gates D1D6: Adversary-verified PASS (see REVIEW-parse.md @2026-06-15T04:08Z). Phase complete.
## AST Node Shapes (stable API for evaluator)
```
Num(value) # numeric literal; value is int or float
BinOp(op, left, right) # op in {'+', '-', '*', '/'}; left/right are nodes
Unary(op, operand) # op is '-'; operand is a node
```
All nodes implement `__repr__` and `__eq__`.
## Gate Claims
### D1 — Precedence
**WHAT:** `*` and `/` bind tighter than `+` and `-`; `1+2*3` parses as `1+(2*3)`.
**HOW:**
```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)))`
**WHERE:** `calc/parser.py``_expr` iterates `+/-`, `_term` iterates `*//`, so `*` folds first.
### D2 — Left Associativity
**WHAT:** `8-3-2` parses as `(8-3)-2`; `8/4/2` as `(8/4)/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('-', BinOp('-', Num(8), Num(3)), Num(2))`
- `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))`
**WHERE:** `calc/parser.py``_expr` and `_term` use `while` loops (iterative left fold).
### D3 — Parentheses
**WHAT:** `(1+2)*3` parses with `+` under `*`.
**HOW:**
```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))`
**WHERE:** `calc/parser.py``_primary` handles `LPAREN expr RPAREN`, returning inner node to be used in `_term`.
### D4 — Unary Minus
**WHAT:** `-5`, `-(1+2)`, `3 * -2` each parse correctly.
**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('-', Num(5))`
- `Unary('-', BinOp('+', Num(1), Num(2)))`
- `BinOp('*', Num(3), Unary('-', Num(2)))`
**WHERE:** `calc/parser.py``_unary` handles `MINUS` recursively before `_primary`.
### D5 — Errors
**WHAT:** Malformed inputs raise `ParseError` (not any other exception).
**HOW:**
```bash
python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
try:
parse(tokenize('1 +'))
print('NO ERROR')
except ParseError:
print('ParseError OK')
"
# Repeat for each case: '(1', '1 2', ')(', ''
```
**EXPECTED:** `ParseError` raised for all five inputs: `"1 +"`, `"(1"`, `"1 2"`, `")("`, `""`.
Shortcut — test suite already covers all five (TestErrors class).
**WHERE:** `calc/parser.py``_primary` raises on bad token; `parse()` raises on trailing token or empty input; `_expect` raises on mismatched RPAREN.
### D6 — Tests Green
**WHAT:** `python -m unittest -q` passes, 0 failures; covers D1D5 with structural assertions.
**HOW:**
```bash
python -m unittest -q
```
**EXPECTED:** `Ran 44 tests in ...s\n\nOK` (21 lexer + 23 parser)
**WHERE:** `calc/test_parser.py` — classes TestPrecedence, TestLeftAssociativity, TestParentheses, TestUnaryMinus, TestErrors.