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,70 @@
## DONE
# STATUS — phase `parse`
## Claimed gates: D1 D2 D3 D4 D5 D6
## Files
- `calc/parser.py` — parser implementation
- `calc/test_parser.py` — unittest suite
## AST node shapes
```
Num(value) — leaf numeric literal; value is int or float
BinOp(op, left, right) — binary op; op is one of '+' '-' '*' '/'
Unary(op, operand) — unary op; op is '-'
```
All nodes implement `__repr__` and `__eq__`.
## How to verify
```bash
# D6 — all tests green
python -m unittest -q
# D1 — * binds tighter than +
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)))
# 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 — parens override precedence
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 — ParseError for malformed input
python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
for s in ['1 +', '(1', '1 2', ')(' , '']:
try:
parse(tokenize(s))
print('FAIL', s)
except ParseError:
print('OK', repr(s))
"
# expected: all 5 lines print OK
# D1/D3 anti-confusion check — structure differs:
# 1+2*3 => BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) [* is the right child of +]
# (1+2)*3 => BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) [+ is the left child of *]
```
## Commit
`a05812d` — claim(D1-D6): add recursive-descent parser with full gate coverage