Skip to content

feat: Calendar Era — date literals, date arithmetic, date comparison, today injection#53

Merged
rmichaelthomas merged 1 commit into
mainfrom
feat/calendar-era
Jul 4, 2026
Merged

feat: Calendar Era — date literals, date arithmetic, date comparison, today injection#53
rmichaelthomas merged 1 commit into
mainfrom
feat/calendar-era

Conversation

@rmichaelthomas

Copy link
Copy Markdown
Owner

Summary

  • Adds date as a third scalar value type (alongside number and string), threaded through the full pipeline: lexer → parser → interpreter → analyzer → renderer.
  • Zero new reserved words. TokenType.DATE is a literal type, accounted the same way as NUMBERALL_RESERVED count is unchanged by this build (61 → 61; note: the count was already 61 on main before this PR, not 60 as CLAUDE.md's stale note says — pre-existing drift, unrelated to this change).
  • Date literals (2025-07-01, bare ISO 8601), calendar validation at parse time, date arithmetic (plus/minus in whole days, date minus date → day count), date comparison (all condition operators), within on dates (day-count tolerance), today as a product-layer injected value (run(..., inject={"today": ...}), wired into the CLI automatically).
  • starting/until now accept bare dates in addition to quoted dates.
  • Extended highest/lowest and list operations (list_of_dates) to dates for parity with numbers/strings — needed for the spec's goal forms but not explicitly itemized in its file-by-file list.
  • Mirrored the new date-comparison guard into listener.py's duplicate _apply_op (Phase 2 reactive path), per that file's existing "both copies must stay in sync" contract.

Test plan

  • pytest tests/ — 1615 passed, 0 failed (1557 pre-existing + 58 new in tests/test_date.py)
  • TokenType.DATE exists; ALL_RESERVED count unchanged by this PR
  • Smoke: date storage/display/comparison, date arithmetic, quoted date stays a string (all via CLI)
  • Renderer round-trip verified for date literals and starting/until bare-date canonicalization
  • Backward compat: existing numeric/string arithmetic, lists, and quoted-date-as-string behavior unaffected

Known gaps (disclosed, not fixed here)

  • A quoted numeric-looking string (e.g. "123") already fails render round-trip on main (canonical rendering drops quotes when "unambiguous", so re-parsing yields a different literal type). Adding dates introduces the identical case for "2025-07-01". Pre-existing _emit_string limitation, not date-specific — left out of scope for this PR.

🤖 Generated with Claude Code

Adds `date` as a third scalar value type alongside number and string,
threaded through the full pipeline: lexer (TokenType.DATE, _DATE_RE),
parser (DateLiteral, calendar validation, bare-date starting/until),
interpreter (storage, display, comparison, arithmetic, within-tolerance,
today injection), analyzer (date types, _require_comparable, date-aware
arithmetic checks, list_of_dates parity with existing list types), and
renderer (bare ISO 8601 round-trip). Zero new reserved words — DATE is
a literal type, accounted the same way as NUMBER.

Also extends highest/lowest to dates (interpreter.py) and mirrors the
new date-comparison guard into listener.py's duplicate _apply_op, both
needed for goal-form parity but not explicitly enumerated in the spec's
file list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@rmichaelthomas
rmichaelthomas merged commit da50fe8 into main Jul 4, 2026
2 checks passed
@rmichaelthomas
rmichaelthomas deleted the feat/calendar-era branch July 4, 2026 20:19
rmichaelthomas added a commit that referenced this pull request Jul 15, 2026
feat: Calendar Era — date literals, date arithmetic, date comparison, today injection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant