value if/loop follow-ups
This commit is contained in:
@@ -358,17 +358,44 @@
|
||||
loop body without a trailing fall-through `yield`; a `yield :blk` with no matching value
|
||||
loop. The TODO "BAD" loops (unlabeled yield from inside an `if`, an unbound labeled loop)
|
||||
fall out of these naturally
|
||||
- deferred to a later pass (`// ponytail:`): a value-if/loop nested as the *trailing*
|
||||
statement of a value block (first pass is the direct `x :: if …`/`for …` form); a branch
|
||||
that early-`return`s instead of yielding; unwrap-`if` (`if v |x| { yield … }`) as a value
|
||||
source; `yield none` before any concrete yield in an untyped loop (annotate instead);
|
||||
`yield :blk` to an outer (non-innermost) loop
|
||||
- follow-ups: a branch that early-`return`s instead of yielding, unwrap-`if` as a value
|
||||
source, and `none`-before-concrete typing in untyped loops are done in 20.6; labeled value
|
||||
blocks and `yield`/`break` to an outer loop are 20.7 (need labels in the IR)
|
||||
|
||||
20.6 value if/loop follow-ups (implemented; checker-only)
|
||||
- a value-if branch may end in `yield` **or** exit on every path (`return`/`break`/
|
||||
`continue`) — `r :: if (ok) { yield x } else { return -1 }`. A non-terminating, non-yielding
|
||||
branch is rejected ("a value branch must end with 'yield' or exit on every path"). Checked
|
||||
via `all_paths_exit` on the built branch in `emit_value_branch`
|
||||
- unwrap-`if` as a value source: `name :: if opt |v| { yield v * 2 } else { yield d }`.
|
||||
`emit_value_if` gained an unwrap path mirroring the build-pass `.If` unwrap arm (captures +
|
||||
guard), each branch assigning the slot; the HIR `.If` carries the unwraps, which the existing
|
||||
lowering already handles. (The simple "unwrap or fallback" case is just `orelse` —
|
||||
`name :: opt orelse d` — already a plain expression.)
|
||||
- untyped value loops pre-type their element from the first concrete (non-`none`) yield
|
||||
regardless of source order (a capture-scoped probe build, `value_loop_element_type`), so a
|
||||
`none` yielded before any concrete value still resolves the result to `?T`
|
||||
- still checker-only; no HIR/lowering change
|
||||
|
||||
20.7 labeled value blocks + `yield`/`break` to an outer loop (introduces labels in the IR)
|
||||
- `x :: blk: { …; yield :blk v }` — a labeled value *block* (the disambiguated form of "an
|
||||
if/loop at the end of a block"; an unlabeled trailing if/loop stays ambiguous and is not a
|
||||
value source). `yield :blk v` exits the block with a value
|
||||
- `yield :outer v` / labeled `break` to a non-innermost loop
|
||||
- both need exit targets to carry a label: add `label` to HIR `.While`/`.For`/`.Break` and a
|
||||
labeled `.Block`; generalize the lowering's `Loop_Ctx`/`State.loops` into an exit-target
|
||||
stack keyed by label (plain `break`/`continue` stay innermost-only; a labeled `.Break`
|
||||
searches by label; a labeled block pushes a non-loop target + an exit label after its body).
|
||||
First lowering change in the `yield` line
|
||||
|
||||
21. unions and tagged unions
|
||||
|
||||
22. match statements with tagged unions payload unwrapping
|
||||
|
||||
23. dynamic heap allocation
|
||||
23. error types
|
||||
- brolang should feature errors as values
|
||||
|
||||
24. dynamic heap allocation
|
||||
- see below for direction
|
||||
- notes below are too big in scope for a first pass and the language is not mature enough to support it yet
|
||||
- this first pass should focus on just basic heap allocation, so we have something to work with
|
||||
|
||||
Reference in New Issue
Block a user