Repository navigation
Disambiguate qualified range endpoints from loop bodies #157
Description
Problem
While validating qualified constant folding for #154/#155, valid range headers ending in an imported constant were parsed as enum payloads. This is independent of constant evaluation and was reproduced before the evaluator change on Linux/386 and amd64.
// src/values.peep
const Zero: i64 = 0i64;
const One: i64 = 1i64;
// src/main.peep in project app
import "app/values";
fn Read() -> i64 {
for value in values::Zero..values::One {
return value;
}
}
Observed on baseline: P0003 enum variant payload requires 'with', P0002 recovery errors, missing range-end/body evidence, and downstream missing-return error. Expected: endpoints remain bound qualified value expressions; the brace opens the loop body.
Control: values::Zero..(values::One as i64) parses correctly. With qualified constant folding repaired, ascending ranges gain guaranteed-entry evidence; equal/reversed/runtime ranges retain missing-return behavior. The explicit cast in the prior regression isolated evaluator behavior; it was not a production parser workaround.
Owners and implementation scope
internal/frontend/parser/parse_stmt.go:parseForStmtowns the range/body boundary.internal/frontend/parser/parse_expr.go: index/range and Pratt expression parsing retain qualified endpoints and explicitly introduced literals.internal/frontend/parser/recover_literal.go: shared nesting-aware recovery for missing literal introducers; local caller delimiters protect headers, arguments, and following syntax.- Resolver/typechecker preserve parser-owned error nodes without redundant syntax diagnostics and record invalid type evidence.
Current grammar uses Enum::Variant with payload, Type.{...}, and .{...}. Peeper is pre-stable: preserve rejection and useful recovery for unsupported syntax, not migration-only parsing or compatibility state. A qualified path is not assumed to denote an enum. Two adjacent blocks alone cannot establish malformed literal intent.
Acceptance criteria
- Parse bare qualified range endpoints without consuming the loop-body brace.
- Cover ascending/equal/reversed/runtime headers; retain endpoint bindings, imported ownership, source locations, and downstream entry/lowering evidence on 386/amd64.
- Preserve explicit enum/struct construction and valid qualified control headers followed by standalone blocks.
- Keep unsupported literal forms rejected with targeted diagnostics; retain enclosing delimiters, following valid syntax, and independent later errors.
- Only mention type arguments when parsed syntax evidence establishes them; do not infer enum or generic declaration identity in the parser.
- Add focused parser/semantic/pipeline tests and positive/applicable negative
x_test/fixtures; validate with the rebuilt bundled compiler.
Delivered
Merged into main through #159 on 2026-10-07 at 29eac4d7de54cb82babf880ea26cf876ba6b1d92. GitHub automatically closed this issue on merge.
- Implementation commit:
a145d64. Merge comparison against PR headafc5568reports no file changes, so the validated implementation is the delivered tree. - All applicable PR checks passed: Quality, Unit, Race, CodeQL, self-review marker, and native Linux/macOS/Windows on amd64/arm64, including bundled source fixtures.
- Post-merge
mainCI also passed: https://github.com/PeeperLanguage/compiler/actions/runs/37576611310. Issue Disambiguate qualified range endpoints from loop bodies #157 and PR Fix qualified range endpoints and literal recovery #159 are bothDonein Peeper Roadmap. - Focused parser/resolver/typechecker checks, 386/amd64 pipeline regressions, and positive/negative bundled fixtures are recorded in Fix qualified range endpoints and literal recovery #159.
Numeric publication, foreign constant ownership, bounds checking, and shared evaluator repair remain in #154/#155.
Related follow-up: #134, a standalone LSP completion feature for current syntax. Assigned milestone: 0.2 Language Foundations.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity