Skip to content

[blang-ast][U1] Source locations end to end - #129

Open
benpayne wants to merge 2 commits into
masterfrom
epic/blang-ast/u1-source-locations
Open

[blang-ast][U1] Source locations end to end#129
benpayne wants to merge 2 commits into
masterfrom
epic/blang-ast/u1-source-locations

Conversation

@benpayne

Copy link
Copy Markdown
Owner

Unit U1 — Phase 1 (create spec) — DRAFT, no implementation yet

Epic: blang-ast (docs/epics/blang-ast/). Covers REQ-001: every AST node carries a source location (file, line, column).

Speckit artifacts (specs/001-source-locations/)

  • spec.md — 3 user stories (nodes carry locations / backtracking accuracy / CompileError location), FR-001..FR-010, measurable success criteria, recorded assumptions (column convention, node-location=first-token, pre-order dump, NodeKind naming), out-of-scope list (error formatting → U2).
  • research.md — decisions R1–R8 grounded in verified code facts (per-token positions in the SymbolInfo replay list so backtracking can't desynchronize; counting in LexerReader::popChar fixing multi-line-token line drift; location on Statement/Symbol/Type bases; CompileError snapshot-at-throw; LocationDumper walker with typeid NodeKinds; minimal stdout suppression only in --dump-locations mode).
  • plan.md — technical context, constitution check (v1.1.0, all principles PASS, no complexity exceptions), file-level structure.
  • data-model.md, contracts/dump-locations-cli.md, quickstart.md — entity shapes, CLI + dump-line grammar contract, validation runbook.
  • tasks.md — T001–T020, ending with Gate A/B and the U1 golden-diff checks from evaluation.md.

Unit done-when (workplan.md U1)

--dump-locations flag; two committed goldens (test_files/golden/{func_simple,match_basic}.locations); both diffs exit 0; no node at line/col 0; all suites green in both build modes.

For the spec audit (Phase 2)

Please apply the Spec audit rubric in docs/epics/blang-ast/evaluation.md. Implementation (Phase 3) will not begin until this spec is approved.

benpayne added 2 commits July 13, 2026 21:08
Phase-1 spec ceremony output for unit U1 (REQ-001):
- spec.md: user stories, FR-001..FR-010, success criteria, assumptions
- plan.md: technical context, constitution check, structure, strategy
- research.md: decisions R1-R8 grounded in verified code facts
- data-model.md, contracts/dump-locations-cli.md, quickstart.md
- tasks.md: T001-T020 ending with per-unit gates (evaluation.md)
- checklists/requirements.md: spec quality checklist (all pass)

No implementation in this commit.
REQ-001: every AST node carries an accurate SourceLocation {file,line,col}.

Lexer/reader:
- LexerReader counts 1-based line/col in popChar (single consumption funnel)
  and retains the filename; fixes the multi-line-token line-drift bug
  (newlines inside string/char constants are now counted).
- SymbolInfo widened to freeze each token's line/col at scan time, so
  positions survive symbol-list replay / setCurrentPos backtracking.
- Lexer::getTokenLocation()/getFileName(); getLineNumber/Position delegate
  to the current token. Per-token stdout echo gated behind setTraceEnabled.

AST + parser:
- New SourceLocation.h value type; mLocation + accessors on Statement,
  Symbol, Type bases (no common base introduced — parser shape frozen).
- Every Parse factory stamps its node at the construct's first token;
  expression parser stamps primaries/postfix/binary nodes; assignment and
  desugared nodes inherit the leftmost/originating location. No reachable
  node keeps line/col 0 (verified over all 113 pass files).

Diagnostics:
- CompileError carries a SourceLocation snapshotted at throw time via
  COMPILE_ERROR; reporting no longer reads the live lexer. Message FORMAT
  unchanged (U2 owns reformatting); C++ __FILE__/__LINE__ retained for a
  future --debug-compiler mode.

Tooling:
- qcc --dump-locations: deterministic pre-order <file>:<line>:<col>
  <NodeKind> dump via new LocationDumper (typeid-demangled kinds). Implies
  parse-only, no LLVM dependency, byte-clean stdout.
- Two committed goldens: test_files/golden/{func_simple,match_basic}.locations.
- CMakeLists, CLAUDE.md updated.

Gates (all green): run_tests.sh 162/162 (LLVM) + 154/154 (parse-only);
test_codegen.sh 63/63; leak-check concurrency subset 6/6 0 leaks; both
golden diffs exit 0; corpus zero-location check clean; LLVM/parse-only dump
parity; deterministic across runs.
@benpayne
benpayne marked this pull request as ready for review July 14, 2026 05:56
@benpayne

Copy link
Copy Markdown
Owner Author

Phase 3 (Implement) complete — ready for code audit

All per-unit gates from evaluation.md were run locally and are green:

Gate A — LLVM build, full suites

  • cmake -S . -B build -DLLVM_DIR=/usr/lib/llvm-18/lib/cmake/llvm && cmake --build build → clean
  • ./run_tests.sh162/162 passed, 0 failed
  • ./test_codegen.sh63/63 passed

Gate B — parse-only build

  • cmake -S . -B build-parse -DBLANG_ENABLE_LLVM=OFF && cmake --build build-parse → clean
  • BUILD_DIR=build-parse ./run_tests.sh154/154 passed (8 cgfail auto-skipped)

U1-specific checks (evaluation.md §Unit-specific)

  • ./build/qcc --dump-locations test_files/pass/func_simple.b | diff - test_files/golden/func_simple.locations → exit 0
  • ./build/qcc --dump-locations test_files/pass/match_basic.b | diff - test_files/golden/match_basic.locations → exit 0
  • No node at line 0 / col 0 in either dump.
  • Corpus-wide FR-004 smoke check (auditor note Add data persistence, serialization, services, contracts, and testing to language design #2): --dump-locations over all 113 pass/*.b0 files with any :0: location.
  • Determinism: two runs byte-identical. Build-mode parity: LLVM vs parse-only dumps identical.

Gate C — leak-check (sanity; U1 touches no runtime/ARC)

  • ./test_codegen.sh --leak-check codegen_spawn*/sync*/shared* → 6/6, 0 leaks.

Note on Gate D (quiet-compile): NOT expected to pass at U1 — quiet-by-default is U2's scope. Default-mode stdout is intentionally unchanged; --dump-locations output is byte-clean on its own (parser trace goes to stderr, and dump mode diverts informational stdout).

Auditor notes folded in: (1) COMPILE_ERROR count corrected to ~215 in spec docs; (2) corpus smoke check added to quickstart.md and run; (3) T008 covered QProtocolDefinition.cpp (QParser.cpp is an empty placeholder — no stamping needed).

Diffstat: 26 files changed (+387/−68); 3 new files (SourceLocation.h, LocationDumper.h/.cpp) + 2 goldens.

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