add range constraint type

This commit is contained in:
2026-06-25 23:02:37 +02:00
parent c3208fdb61
commit 70a6d69d29
9 changed files with 222 additions and 40 deletions
+16 -11
View File
@@ -181,19 +181,26 @@
- disallow: `b :: undefined` since assigning undefined to something that can't change defeats the purpose
- disallow assigning `undefined` after declaration; use optionals and `none` for values that intentionally move back to an empty state
13. introduce a `float` type constraint (similar to `int`) (implemented)
- resolves a local binding to any float scalar (`f32`/`f64`) via static analysis; widens
`f32` -> `f64` across assignments, mirroring how `int` picks the smallest fitting integer
13. introduce `float` and `range` type constraints (the `int` family generalized) (implemented)
- `float` resolves a local binding to any float scalar (`f32`/`f64`) via static analysis;
widens `f32` -> `f64` across assignments, mirroring how `int` picks the smallest integer
- on a local declaration, integer literals satisfy `float` and default to `f64`
(`pi float = 3` is `3.0`); a runtime integer (`x float = some_i32`) stays a
`cannot implicitly convert` error
- a local initializer whose numeric family doesn't satisfy the constraint now errors for
both `int` and `float` instead of silently taking the initializer's natural type
- as with `int`, a constraint in a param/result position is a generic passthrough (it
forwards the inferred type unchanged, e.g. an identity `func(v int) int` over a range),
so the literal-as-float and family checks apply to local bindings, not passthroughs
- `range` is now a spellable type/constraint: `r range :: 0..10` resolves to the inferred
range (element type preserved), and `func(start, end int) range { return start..end }`
monomorphizes the result per call. this replaces the prior `int`-as-passthrough hack that
was the only way to forward a range through a function
- `int`/`float`/`range` constraints now gate by family in every position (previously
params/results were unchecked generic passthroughs):
- a local initializer out of family errors instead of silently taking the natural type
- a param rejects an out-of-family argument (`cannot pass f64 to 'int' parameter 'x'`);
a `float` param accepts an integer-literal argument as f64 (e.g. `f(3)`)
- a function result is narrowed to the constraint's family
14. add slice-by-range
14. broaden type inference to surrounding context
15. add slice-by-range
- allow the use of a range in slice expressions:
```
excl_range range :: 0..10
@@ -203,8 +210,6 @@
some_arr[incl_range] # slice by named inclusive range
```
15. broaden type inference from surrounding context
## A word on multi-unwrap
Unwrap multiple optionals with `and`. This **short-circuits**: if the first optional is none, subsequent expressions are not evaluated.