fix catch handlers / match statements yielding past scope
This commit is contained in:
@@ -603,7 +603,55 @@
|
||||
- structurally identical anonymous struct payloads share type identity, so sum composition merges
|
||||
matching variants and still rejects same-name variants with different payload shapes
|
||||
|
||||
24. dynamic heap allocation
|
||||
24. bug fixes & interop/indexing oversights (surfaced by the raylib testbed)
|
||||
- the bouncing-shapes testbed (`testbed/game`) drove most of the language at once and
|
||||
exposed several gaps; grouped here as the next polish pass. it currently compiles only by
|
||||
keeping three non-interconverting integer "worlds" (`usize` for indices, the `int`
|
||||
constraint for `c_int` args, `c_float` for physics) and routing around the items below
|
||||
- `return match ...` doesn't work (and `yield match ...` probably doesn't either): a `match`
|
||||
is not accepted directly as a `return`/`yield` operand, so the value must be bound to a
|
||||
local first, or a statement-`match` with per-arm `return` used — the testbed's `next_kind`
|
||||
had to do the latter
|
||||
- signed-index array access must be a diagnostic, not a miscompile: `arr[i]` with a signed
|
||||
index (`i32`/`int`, including the `int` constraint) currently lowers to malformed LLVM IR
|
||||
(the indexed slot's address and the stored value get swapped: `store <struct>, ptr` with a
|
||||
value where a `ptr` is expected) for both reads and writes; only `usize` and compile-time
|
||||
literal indices work. settle the rule — index expressions require an unsigned
|
||||
(`usize`-coercible) type, as in Rust/Zig — and report a clear checker error instead of
|
||||
emitting bad IR
|
||||
- native scalar types should coerce to their C equivalents in general: `f32 -> c_float`,
|
||||
`f64 -> c_double`, and the integer cases (`i32 -> c_int`, `u8 -> c_uchar`,
|
||||
`usize -> the matching C width`, …) at call/return/assignment boundaries, following C's own
|
||||
same-width/family conversions. today only the `int` constraint coerces to `c_int`;
|
||||
concrete-width native scalars (`i32`, `usize`, `f32`) are stranded, which is why the testbed
|
||||
had to store physics directly in `c_float` and maintain parallel `usize`/`int` counters
|
||||
- explicit scalar type casting: there is no cast syntax yet (`c_float(x)` is rejected — that
|
||||
spelling is distinct-type construction, not a numeric cast), so any conversion the coercion
|
||||
rules above don't cover is currently impossible. settle a cast spelling; this removes most
|
||||
of the manual world-juggling the testbed needed
|
||||
- c scalars must be comparable with numeric literals: `x < 0.0` and `x != 0.0` where
|
||||
`x : c_float` currently error ("comparison requires compatible numeric operands") even
|
||||
though `x + 1.0` / `x * 2.0` already accept the literal. a comparison operand literal should
|
||||
adopt the other operand's concrete (c) scalar type exactly as arithmetic does — otherwise
|
||||
every zero/bound needs a `c_float` constant alias (the testbed added `ZF`, `SPINMAX`, etc.)
|
||||
- array sizes should accept compile-time-constant expressions, not just integer literals:
|
||||
`[CAP]T` with `CAP :: 64` (and `[N + 1]T`, …) should resolve through the same constant
|
||||
folding used for global initializers. runtime *variable* lengths stay rejected by design —
|
||||
a runtime-length array is a slice + allocation (milestone 25), not an array type (Zig/Rust
|
||||
parity: array lengths are comptime-known). the testbed had to hard-code `[64]` and keep a
|
||||
separate `CAP usize :: 64` for the bounds checks
|
||||
- peer-type resolution for string literals in value-`match` / value-`if` arms (Zig parity,
|
||||
not a brolang-specific limitation): arms yielding differently-sized string literals
|
||||
(`@[6;0]u8` for "circle" vs `@[8;0]u8` for "triangle") currently fail to unify, forcing a
|
||||
per-arm `DrawText("…")` workaround instead of `tag :: match k { … }; DrawText(tag, …)`.
|
||||
verified Zig 0.16 behavior: `switch`/`if` arms of string literals peer-resolve to a single
|
||||
sentinel slice `[:0]const u8` (preserving the common `:0`), which then coerces directly to a
|
||||
C string `[*c]const u8`. brolang should (a) peer-type-resolve same-sentinel string literals
|
||||
to a sentinel byte slice `[;0]u8`, and (b) allow a zero-terminated byte slice to convert to
|
||||
`*c_char` (extending milestone 3.5's pointer-view → `*c_char` rule to the matching sentinel
|
||||
slice). with both, a value-`match` label passes straight to a `?*c_char` parameter
|
||||
|
||||
25. 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