parser/top-level #12

Merged
crowmaki merged 2 commits from parser/top-level into main 2026-08-23 23:13:53 +00:00
Owner
No description provided.
`parse` finally does its job: `program = { top-level-item } EOF`, over the
`parse_item` step 60 already built. With it, `parser/tests/fixtures.rs` comes
off `#[ignore]` and all 51 `parse/` + `semantics/` fixtures build a syntax
tree — the parse phase is feature-complete.

Four backlog items stood between the loop and an unignored driver:

- #26 `parse` was the step-00 stub. It now loops to EOF and asserts each
  iteration consumed a token; every `parse_item` arm does today, and the one
  that stopped would hang the compiler with no diagnostic.
- #27 `parse` built its cursor with `src: None`, and the scanner records an
  identifier as a span — so every name in a parsed program came out empty,
  silently. `parse(tokens, source)` takes the text and `Cursor.src` is a plain
  `String`: the `Option` was the defect, not the missing argument.
- #45 `TypeRef::Modified(TypeModifier, ...)` and a prefix arm in
  `parse_type_atom`. One nesting arm rather than a flag pair, because
  `*const []T` is a pointer to a const array.
- #46 `NewTarget::ArraySized(Box<Expr>, ...)`: an allocation is sized when it
  runs (`new [arr.length]f32`). Its `TypeRef::ArrayStatic` sibling keeps its
  `u64` — a type's extent is fixed before anything runs.
- #47 `static-member`, the spec's functional spelling of a static or instance
  member, reached through an `at_static_member` predicate that clones the
  cursor and tries the shape rather than scanning for it. The head must be
  `::`-qualified, so `f = (x) -> x;` stays an assignment. This widened
  `Decl::FunctionDecl`'s body to `LambdaBody`: "both spellings build one node"
  held only while nobody wrote the concise one.

`static-functions.cat` and `instance-functions.cat` gain the functional
spelling beside the C-style one — the same manifest feature in its second
documented spelling, so no new row.

Filed #48 while writing the tests: `this` is not an expression. `primary` does
not list it and `parse_primary` has no arm, so an instance function cannot
touch its receiver outside a string — which is why no fixture has caught it,
`instance-functions.cat` writing `"(${this.x})"` and the scanner keeping
interpolation verbatim.

Also corrects the `parse/` suite count in docs/parser/ from 32 to 35.
`primary` listed `true`, `false` and `null` but not `this`, and
`parse_primary` had no arm for the keyword — so an instance function could not
touch its receiver anywhere the parser could see.

What makes that a defect rather than a restriction is the grammar's own
`interpolation = "${" expression "}"`: the spec's `"(${this.x}, ${this.y})"`
*is* an expression by that rule. It went unnoticed because the scanner keeps
interpolation verbatim, so those bytes never reached the expression grammar —
`instance-functions.cat` is the only fixture that names the receiver, and it
names it inside a string.

- `Expr::This(Span)`, its own node rather than a `Named` spelled "this": it is
  a reserved word, it resolves to the enclosing declaration rather than to
  anything in scope, and it is legal only inside an instance function. A
  name-shaped node would hide all three from semantics.
- An arm in `parse_primary`, and one in `can_start_expr`. The second is what
  lets a statement begin with `this`; without it `this.x = 1;` reported
  "expected a statement" and named the wrong grammar.
- `"this"` joins the reserved-word terminals in `primary`, with the
  interpolation argument recorded beside it.

Pinned by `this_is_an_expression`, which covers member access, subscripts,
calls, statement position, and an instance function reading its receiver in
both of the spec's spellings. No fixture changes: the spec has no example of
`this` outside a string, and the grammar defects before this one (#9-#19) were
pinned by unit tests for the same reason.

Closes the backlog — no todo items remain.
crowmaki deleted branch parser/top-level 2026-08-23 23:13:53 +00:00
crowmaki referenced this pull request from a commit 2026-08-23 23:13:53 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crowmaki/catlang!12
No description provided.