3.2 KiB
STATUS — phase lex (Builder)
DONE
All DoD gates Adversary-verified PASS. Phase complete.
Gates
| Gate | Status |
|---|---|
| D1 — numbers | PASS (Adversary @2026-06-15T00:36Z) |
| D2 — operators & parens | PASS (Adversary @2026-06-15T00:36Z) |
| D3 — whitespace & errors | PASS (Adversary @2026-06-15T00:36Z) |
| D4 — tests green | PASS (Adversary @2026-06-15T00:36Z) |
Post-verification fix
AF-01 addressed: Wrapped float(raw) in try/except ValueError to re-raise as LexError for malformed number literals like 1.2.3, ., ... 24 tests still pass.
Claim: D1 — numbers
WHAT: calc/lexer.py::tokenize correctly tokenizes integers and floats to NUMBER tokens with numeric Python values (int for integers, float for floats). EOF is always the final token.
HOW to verify:
python -c "from calc.lexer import tokenize; t=tokenize('42'); assert t[0].kind=='NUMBER' and t[0].value==42 and isinstance(t[0].value,int) and t[1].kind=='EOF', t"
python -c "from calc.lexer import tokenize; t=tokenize('3.14'); assert t[0].kind=='NUMBER' and abs(t[0].value-3.14)<1e-9 and isinstance(t[0].value,float), t"
python -c "from calc.lexer import tokenize; t=tokenize('.5'); assert t[0].value==0.5, t"
python -c "from calc.lexer import tokenize; t=tokenize('10.'); assert t[0].value==10.0, t"
EXPECTED: All assertions pass (exit 0).
WHERE: calc/lexer.py
Claim: D2 — operators & parens
WHAT: +, -, *, /, (, ) each tokenize to PLUS, MINUS, STAR, SLASH, LPAREN, RPAREN respectively. tokenize("1+2*3") → NUMBER PLUS NUMBER STAR NUMBER EOF.
HOW to verify:
python -c "from calc.lexer import tokenize; k=[t.kind for t in tokenize('1+2*3')]; assert k==['NUMBER','PLUS','NUMBER','STAR','NUMBER','EOF'], k"
python -c "from calc.lexer import tokenize; print([(t.kind,t.value) for t in tokenize('3.5*(1-2)')])"
EXPECTED:
- First command: exit 0 (assertion passes)
- Second command prints:
[('NUMBER', 3.5), ('STAR', '*'), ('LPAREN', '('), ('NUMBER', 1), ('MINUS', '-'), ('NUMBER', 2), ('RPAREN', ')'), ('EOF', None)]
WHERE: calc/lexer.py
Claim: D3 — whitespace & errors
WHAT: Spaces and tabs between tokens are skipped. Invalid characters (letters, @, $, etc.) raise LexError with the offending char and its position in the message.
HOW to verify:
python -c "from calc.lexer import tokenize; k=[t.kind for t in tokenize(' 12 + 3 ')]; assert k==['NUMBER','PLUS','NUMBER','EOF'], k"
python -c "
from calc.lexer import tokenize, LexError
try:
tokenize('1 @ 2')
assert False, 'should have raised'
except LexError as e:
assert '@' in str(e), str(e)
assert '2' in str(e), str(e)
print('OK')
"
EXPECTED:
- First command: exit 0
- Second command prints:
OK
WHERE: calc/lexer.py
Claim: D4 — tests green
WHAT: calc/test_lexer.py passes under python -m unittest with 0 failures (24 tests).
HOW to verify:
python -m unittest -q
EXPECTED:
----------------------------------------------------------------------
Ran 24 tests in 0.001s
OK
Exit code 0.
WHERE: calc/test_lexer.py, calc/lexer.py