artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
# DECISIONS (append-only)
|
||||
|
||||
## lex phase
|
||||
|
||||
**Token as dataclass**: Used `@dataclass` for `Token` to get `__eq__` for free, enabling `assertIn` and `assertEqual` in tests.
|
||||
|
||||
**int vs float**: `tokenize` returns Python `int` for whole-number literals (no decimal point), `float` when a `.` is present. This matches the plan's wording "numeric value (int or float)".
|
||||
|
||||
**EOF value**: Set `EOF` token `value` to `None` (no meaningful payload).
|
||||
|
||||
## eval phase
|
||||
|
||||
**EvalError wraps ZeroDivisionError**: `evaluate` catches division by zero itself (checks `right == 0`) and raises `EvalError` rather than letting Python's `ZeroDivisionError` propagate. This is the public API contract: callers catch `EvalError`.
|
||||
|
||||
**D3 formatting rule in `fmt_result`**: Placed in `calc/evaluator.py` so it's importable and testable from `calc/test_evaluator.py`. Rule: `isinstance(v, float) and v.is_integer()` → `str(int(v))`, else `str(v)`. Python's `/` always returns float, so `4/2 = 2.0`; `fmt_result` converts to `"2"`.
|
||||
|
||||
**CLI at repo root as `calc.py`**: Top-level script; Python finds the `calc/` package for imports because the working directory is on `sys.path` when running `python calc.py`.
|
||||
Reference in New Issue
Block a user