Fix some formatter bugs

This commit is contained in:
Richard Feldman 2025-12-02 22:27:59 -05:00
parent ada586b9a3
commit c04befd47d
No known key found for this signature in database
2 changed files with 375 additions and 156 deletions

View file

@ -10,6 +10,7 @@ Builtin :: [].{
].{
is_eq : Utf8Problem, Utf8Problem -> Bool
}
is_empty : Str -> Bool
concat : Str, Str -> Str
contains : Str, Str -> Bool
@ -31,17 +32,20 @@ Builtin :: [].{
release_excess_capacity : Str -> Str
to_utf8 : Str -> List(U8)
from_utf8_lossy : List(U8) -> Str
from_utf8 : List(U8) -> Try(Str, [BadUtf8({ problem : Str.Utf8Problem, index : U64 })])
from_utf8 : List(U8) -> Try(Str, [BadUtf8({ problem : Str.Utf8Problem, index : U64 }), ..others])
split_on : Str, Str -> List(Str)
join_with : List(Str), Str -> Str
is_eq : Str, Str -> Bool
}
List(_item) :: [ProvidedByCompiler].{
len : List(_item) -> U64
is_empty : List(_item) -> Bool
concat : List(item), List(item) -> List(item)
with_capacity : U64 -> List(item)
sort_with : List(item), (item, item -> [LT, EQ, GT]) -> List(item)
is_eq : List(item), List(item) -> Bool
where [item.is_eq : item, item -> Bool]
is_eq = |self, other| {
@ -61,28 +65,34 @@ Builtin :: [].{
True
}
append : List(a), a -> List(a)
first : List(item) -> Try(item, [ListWasEmpty])
first : List(item) -> Try(item, [ListWasEmpty, ..others])
first = |list| if List.is_empty(list) {
Try.Err(ListWasEmpty)
} else {
Try.Ok(list_get_unsafe(list, 0))
}
get : List(item), U64 -> Try(item, [OutOfBounds])
get : List(item), U64 -> Try(item, [OutOfBounds, ..others])
get = |list, index| if index < List.len(list) {
Try.Ok(list_get_unsafe(list, index))
} else {
Try.Err(OutOfBounds)
}
for_each! : List(item), (item => {}) => {}
for_each! = |items, cb!| for item in items {
cb!(item)
}
map : List(a), (a -> b) -> List(b)
map = |list, transform|
# Implement using fold + concat for now
# TODO: Optimize with in-place update when list is unique and element sizes match
List.fold(list, [], |acc, item| List.concat(acc, [transform(item)]))
keep_if : List(a), (a -> Bool) -> List(a)
keep_if = |list, predicate|
List.fold(
@ -95,6 +105,7 @@ Builtin :: [].{
acc
},
)
drop_if : List(a), (a -> Bool) -> List(a)
drop_if = |list, predicate|
List.fold(
@ -107,6 +118,7 @@ Builtin :: [].{
List.concat(acc, [elem])
},
)
fold : List(item), state, (state, item -> state) -> state
fold = |list, init, step| {
var $state = init
@ -117,6 +129,7 @@ Builtin :: [].{
$state
}
fold_rev : List(item), state, (item, state -> state) -> state
fold_rev = |list, init, step| {
var $state = init
@ -130,6 +143,7 @@ Builtin :: [].{
$state
}
any : List(a), (a -> Bool) -> Bool
any = |list, predicate| {
for item in list {
@ -139,10 +153,12 @@ Builtin :: [].{
}
False
}
contains : List(a), a -> Bool where [a.is_eq : a, a -> Bool]
contains = |list, elt| {
List.any(list, |x| x == elt)
}
all : List(a), (a -> Bool) -> Bool
all = |list, predicate| {
for item in list {
@ -152,31 +168,39 @@ Builtin :: [].{
}
True
}
last : List(item) -> Try(item, [ListWasEmpty])
last : List(item) -> Try(item, [ListWasEmpty, ..others])
last = |list| if List.is_empty(list) {
Try.Err(ListWasEmpty)
} else {
Try.Ok(list_get_unsafe(list, List.len(list) - 1))
}
single : item -> List(item)
single = |x| [x]
drop_at : List(a), U64 -> List(a)
sublist : List(a), { start : U64, len : U64 } -> List(a)
take_first : List(a), U64 -> List(a)
take_first = |list, n| {
List.sublist(list, { len: n, start: 0 })
}
take_last : List(a), U64 -> List(a)
take_last = |list, n| {
len = List.len(list)
start = if (len <= n) 0 else len - n
List.sublist(list, { start: start, len: len })
}
drop_first : List(a), U64 -> List(a)
drop_first = |list, n| {
len = List.len(list)
List.sublist(list, { start: n, len: len })
}
drop_last : List(a), U64 -> List(a)
drop_last = |list, n| {
len = List.len(list)
@ -184,42 +208,55 @@ Builtin :: [].{
List.sublist(list, { start: 0, len: take_len })
}
}
Bool := [False, True].{
not : Bool -> Bool
not = |bool| match bool {
Bool.True => Bool.False
Bool.False => Bool.True
}
is_eq : Bool, Bool -> Bool
# encoder : Bool -> Encoder(fmt, [])
# where [fmt implements EncoderFormatting]
# encoder =
# Encoder fmt := List U8, fmt -> List U8 where fmt implements EncoderFormatting
}
Box(item) :: [ProvidedByCompiler].{}
Try(ok, err) := [Ok(ok), Err(err)].{
is_ok : Try(_ok, _err) -> Bool
is_ok = |try| match try {
Ok(_) => True
Err(_) => False
}
is_err : Try(_ok, _err) -> Bool
is_err = |try| match try {
Ok(_) => False
Err(_) => True
}
ok_or : Try(ok, _err), ok -> ok
ok_or = |try, fallback| match try {
Ok(val) => val
Err(_) => fallback
}
err_or : Try(_ok, err), err -> err
err_or = |try, fallback| match try {
Err(val) => val
Ok(_) => fallback
}
is_eq : Try(ok, err), Try(ok, err) -> Bool
where
[
ok.is_eq : ok, ok -> Bool
,
err.is_eq : err, err -> Bool]
where [
ok.is_eq : ok, ok -> Bool,
err.is_eq : err, err -> Bool,
]
is_eq = |a, b| match a {
Ok(a_val) => {
match b {
@ -235,11 +272,14 @@ ok.is_eq : ok, ok -> Bool
}
}
}
Dict :: [EmptyDict].{}
Set(item) :: [].{
is_eq : Set(item), Set(item) -> Bool
is_eq = |_a, _b| Bool.False
}
Num :: {}.{
Numeral :: [
Self(
@ -268,6 +308,7 @@ ok.is_eq : ok, ok -> Bool
Self({ is_negative: neg, digits_before_pt: _, digits_after_pt: _ }) => neg
}
}
U8 :: [].{
to_str : U8 -> Str
is_zero : U8 -> Bool
@ -276,6 +317,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : U8, U8 -> Bool
is_lt : U8, U8 -> Bool
is_lte : U8, U8 -> Bool
plus : U8, U8 -> U8
minus : U8, U8 -> U8
times : U8, U8 -> U8
@ -284,23 +326,31 @@ ok.is_eq : ok, ok -> Bool
rem_by : U8, U8 -> U8
mod_by : U8, U8 -> U8
abs_diff : U8, U8 -> U8
from_int_digits : List(U8) -> Try(U8, [OutOfRange])
from_numeral : Numeral -> Try(U8, [InvalidNumeral(Str)])
from_str : Str -> Try(U8, [BadNumStr])
from_int_digits : List(U8) -> Try(U8, [OutOfRange, ..others])
from_numeral : Numeral -> Try(U8, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(U8, [BadNumStr, ..others])
# Conversions to signed integers (I8 is lossy, others are safe)
to_i8_wrap : U8 -> I8
to_i8_try : U8 -> Try(I8, [OutOfRange])
to_i8_try : U8 -> Try(I8, [OutOfRange, ..others])
to_i16 : U8 -> I16
to_i32 : U8 -> I32
to_i64 : U8 -> I64
to_i128 : U8 -> I128
# Conversions to unsigned integers (all safe widening)
to_u16 : U8 -> U16
to_u32 : U8 -> U32
to_u64 : U8 -> U64
to_u128 : U8 -> U128
# Conversions to floating point (all safe)
to_f32 : U8 -> F32
to_f64 : U8 -> F64
to_dec : U8 -> Dec
}
I8 :: [].{
to_str : I8 -> Str
is_zero : I8 -> Bool
@ -311,6 +361,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : I8, I8 -> Bool
is_lt : I8, I8 -> Bool
is_lte : I8, I8 -> Bool
negate : I8 -> I8
abs : I8 -> I8
plus : I8, I8 -> I8
@ -321,27 +372,35 @@ ok.is_eq : ok, ok -> Bool
rem_by : I8, I8 -> I8
mod_by : I8, I8 -> I8
abs_diff : I8, I8 -> U8
from_int_digits : List(U8) -> Try(I8, [OutOfRange])
from_numeral : Numeral -> Try(I8, [InvalidNumeral(Str)])
from_str : Str -> Try(I8, [BadNumStr])
from_int_digits : List(U8) -> Try(I8, [OutOfRange, ..others])
from_numeral : Numeral -> Try(I8, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(I8, [BadNumStr, ..others])
# Conversions to signed integers (all safe widening)
to_i16 : I8 -> I16
to_i32 : I8 -> I32
to_i64 : I8 -> I64
to_i128 : I8 -> I128
# Conversions to unsigned integers (all lossy for negative values)
to_u8_wrap : I8 -> U8
to_u8_try : I8 -> Try(U8, [OutOfRange])
to_u8_try : I8 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : I8 -> U16
to_u16_try : I8 -> Try(U16, [OutOfRange])
to_u16_try : I8 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : I8 -> U32
to_u32_try : I8 -> Try(U32, [OutOfRange])
to_u32_try : I8 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : I8 -> U64
to_u64_try : I8 -> Try(U64, [OutOfRange])
to_u64_try : I8 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : I8 -> U128
to_u128_try : I8 -> Try(U128, [OutOfRange])
to_u128_try : I8 -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : I8 -> F32
to_f64 : I8 -> F64
to_dec : I8 -> Dec
}
U16 :: [].{
to_str : U16 -> Str
is_zero : U16 -> Bool
@ -350,6 +409,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : U16, U16 -> Bool
is_lt : U16, U16 -> Bool
is_lte : U16, U16 -> Bool
plus : U16, U16 -> U16
minus : U16, U16 -> U16
times : U16, U16 -> U16
@ -358,25 +418,33 @@ ok.is_eq : ok, ok -> Bool
rem_by : U16, U16 -> U16
mod_by : U16, U16 -> U16
abs_diff : U16, U16 -> U16
from_int_digits : List(U8) -> Try(U16, [OutOfRange])
from_numeral : Numeral -> Try(U16, [InvalidNumeral(Str)])
from_str : Str -> Try(U16, [BadNumStr])
from_int_digits : List(U8) -> Try(U16, [OutOfRange, ..others])
from_numeral : Numeral -> Try(U16, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(U16, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : U16 -> I8
to_i8_try : U16 -> Try(I8, [OutOfRange])
to_i8_try : U16 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : U16 -> I16
to_i16_try : U16 -> Try(I16, [OutOfRange])
to_i16_try : U16 -> Try(I16, [OutOfRange, ..others])
to_i32 : U16 -> I32
to_i64 : U16 -> I64
to_i128 : U16 -> I128
# Conversions to unsigned integers
to_u8_wrap : U16 -> U8
to_u8_try : U16 -> Try(U8, [OutOfRange])
to_u8_try : U16 -> Try(U8, [OutOfRange, ..others])
to_u32 : U16 -> U32
to_u64 : U16 -> U64
to_u128 : U16 -> U128
# Conversions to floating point (all safe)
to_f32 : U16 -> F32
to_f64 : U16 -> F64
to_dec : U16 -> Dec
}
I16 :: [].{
to_str : I16 -> Str
is_zero : I16 -> Bool
@ -387,6 +455,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : I16, I16 -> Bool
is_lt : I16, I16 -> Bool
is_lte : I16, I16 -> Bool
negate : I16 -> I16
abs : I16 -> I16
plus : I16, I16 -> I16
@ -397,28 +466,36 @@ ok.is_eq : ok, ok -> Bool
rem_by : I16, I16 -> I16
mod_by : I16, I16 -> I16
abs_diff : I16, I16 -> U16
from_int_digits : List(U8) -> Try(I16, [OutOfRange])
from_numeral : Numeral -> Try(I16, [InvalidNumeral(Str)])
from_str : Str -> Try(I16, [BadNumStr])
from_int_digits : List(U8) -> Try(I16, [OutOfRange, ..others])
from_numeral : Numeral -> Try(I16, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(I16, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : I16 -> I8
to_i8_try : I16 -> Try(I8, [OutOfRange])
to_i8_try : I16 -> Try(I8, [OutOfRange, ..others])
to_i32 : I16 -> I32
to_i64 : I16 -> I64
to_i128 : I16 -> I128
# Conversions to unsigned integers (all lossy for negative values)
to_u8_wrap : I16 -> U8
to_u8_try : I16 -> Try(U8, [OutOfRange])
to_u8_try : I16 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : I16 -> U16
to_u16_try : I16 -> Try(U16, [OutOfRange])
to_u16_try : I16 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : I16 -> U32
to_u32_try : I16 -> Try(U32, [OutOfRange])
to_u32_try : I16 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : I16 -> U64
to_u64_try : I16 -> Try(U64, [OutOfRange])
to_u64_try : I16 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : I16 -> U128
to_u128_try : I16 -> Try(U128, [OutOfRange])
to_u128_try : I16 -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : I16 -> F32
to_f64 : I16 -> F64
to_dec : I16 -> Dec
}
U32 :: [].{
to_str : U32 -> Str
is_zero : U32 -> Bool
@ -427,6 +504,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : U32, U32 -> Bool
is_lt : U32, U32 -> Bool
is_lte : U32, U32 -> Bool
plus : U32, U32 -> U32
minus : U32, U32 -> U32
times : U32, U32 -> U32
@ -435,27 +513,35 @@ ok.is_eq : ok, ok -> Bool
rem_by : U32, U32 -> U32
mod_by : U32, U32 -> U32
abs_diff : U32, U32 -> U32
from_int_digits : List(U8) -> Try(U32, [OutOfRange])
from_numeral : Numeral -> Try(U32, [InvalidNumeral(Str)])
from_str : Str -> Try(U32, [BadNumStr])
from_int_digits : List(U8) -> Try(U32, [OutOfRange, ..others])
from_numeral : Numeral -> Try(U32, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(U32, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : U32 -> I8
to_i8_try : U32 -> Try(I8, [OutOfRange])
to_i8_try : U32 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : U32 -> I16
to_i16_try : U32 -> Try(I16, [OutOfRange])
to_i16_try : U32 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : U32 -> I32
to_i32_try : U32 -> Try(I32, [OutOfRange])
to_i32_try : U32 -> Try(I32, [OutOfRange, ..others])
to_i64 : U32 -> I64
to_i128 : U32 -> I128
# Conversions to unsigned integers
to_u8_wrap : U32 -> U8
to_u8_try : U32 -> Try(U8, [OutOfRange])
to_u8_try : U32 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : U32 -> U16
to_u16_try : U32 -> Try(U16, [OutOfRange])
to_u16_try : U32 -> Try(U16, [OutOfRange, ..others])
to_u64 : U32 -> U64
to_u128 : U32 -> U128
# Conversions to floating point (all safe)
to_f32 : U32 -> F32
to_f64 : U32 -> F64
to_dec : U32 -> Dec
}
I32 :: [].{
to_str : I32 -> Str
is_zero : I32 -> Bool
@ -466,6 +552,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : I32, I32 -> Bool
is_lt : I32, I32 -> Bool
is_lte : I32, I32 -> Bool
negate : I32 -> I32
abs : I32 -> I32
plus : I32, I32 -> I32
@ -476,29 +563,37 @@ ok.is_eq : ok, ok -> Bool
rem_by : I32, I32 -> I32
mod_by : I32, I32 -> I32
abs_diff : I32, I32 -> U32
from_int_digits : List(U8) -> Try(I32, [OutOfRange])
from_numeral : Numeral -> Try(I32, [InvalidNumeral(Str)])
from_str : Str -> Try(I32, [BadNumStr])
from_int_digits : List(U8) -> Try(I32, [OutOfRange, ..others])
from_numeral : Numeral -> Try(I32, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(I32, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : I32 -> I8
to_i8_try : I32 -> Try(I8, [OutOfRange])
to_i8_try : I32 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : I32 -> I16
to_i16_try : I32 -> Try(I16, [OutOfRange])
to_i16_try : I32 -> Try(I16, [OutOfRange, ..others])
to_i64 : I32 -> I64
to_i128 : I32 -> I128
# Conversions to unsigned integers (all lossy for negative values)
to_u8_wrap : I32 -> U8
to_u8_try : I32 -> Try(U8, [OutOfRange])
to_u8_try : I32 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : I32 -> U16
to_u16_try : I32 -> Try(U16, [OutOfRange])
to_u16_try : I32 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : I32 -> U32
to_u32_try : I32 -> Try(U32, [OutOfRange])
to_u32_try : I32 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : I32 -> U64
to_u64_try : I32 -> Try(U64, [OutOfRange])
to_u64_try : I32 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : I32 -> U128
to_u128_try : I32 -> Try(U128, [OutOfRange])
to_u128_try : I32 -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : I32 -> F32
to_f64 : I32 -> F64
to_dec : I32 -> Dec
}
U64 :: [].{
to_str : U64 -> Str
is_zero : U64 -> Bool
@ -507,6 +602,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : U64, U64 -> Bool
is_lt : U64, U64 -> Bool
is_lte : U64, U64 -> Bool
plus : U64, U64 -> U64
minus : U64, U64 -> U64
times : U64, U64 -> U64
@ -515,29 +611,37 @@ ok.is_eq : ok, ok -> Bool
rem_by : U64, U64 -> U64
mod_by : U64, U64 -> U64
abs_diff : U64, U64 -> U64
from_int_digits : List(U8) -> Try(U64, [OutOfRange])
from_numeral : Numeral -> Try(U64, [InvalidNumeral(Str)])
from_str : Str -> Try(U64, [BadNumStr])
from_int_digits : List(U8) -> Try(U64, [OutOfRange, ..others])
from_numeral : Numeral -> Try(U64, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(U64, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : U64 -> I8
to_i8_try : U64 -> Try(I8, [OutOfRange])
to_i8_try : U64 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : U64 -> I16
to_i16_try : U64 -> Try(I16, [OutOfRange])
to_i16_try : U64 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : U64 -> I32
to_i32_try : U64 -> Try(I32, [OutOfRange])
to_i32_try : U64 -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : U64 -> I64
to_i64_try : U64 -> Try(I64, [OutOfRange])
to_i64_try : U64 -> Try(I64, [OutOfRange, ..others])
to_i128 : U64 -> I128
# Conversions to unsigned integers
to_u8_wrap : U64 -> U8
to_u8_try : U64 -> Try(U8, [OutOfRange])
to_u8_try : U64 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : U64 -> U16
to_u16_try : U64 -> Try(U16, [OutOfRange])
to_u16_try : U64 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : U64 -> U32
to_u32_try : U64 -> Try(U32, [OutOfRange])
to_u32_try : U64 -> Try(U32, [OutOfRange, ..others])
to_u128 : U64 -> U128
# Conversions to floating point (all safe)
to_f32 : U64 -> F32
to_f64 : U64 -> F64
to_dec : U64 -> Dec
}
I64 :: [].{
to_str : I64 -> Str
is_zero : I64 -> Bool
@ -548,6 +652,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : I64, I64 -> Bool
is_lt : I64, I64 -> Bool
is_lte : I64, I64 -> Bool
negate : I64 -> I64
abs : I64 -> I64
plus : I64, I64 -> I64
@ -558,30 +663,38 @@ ok.is_eq : ok, ok -> Bool
rem_by : I64, I64 -> I64
mod_by : I64, I64 -> I64
abs_diff : I64, I64 -> U64
from_int_digits : List(U8) -> Try(I64, [OutOfRange])
from_numeral : Numeral -> Try(I64, [InvalidNumeral(Str)])
from_str : Str -> Try(I64, [BadNumStr])
from_int_digits : List(U8) -> Try(I64, [OutOfRange, ..others])
from_numeral : Numeral -> Try(I64, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(I64, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : I64 -> I8
to_i8_try : I64 -> Try(I8, [OutOfRange])
to_i8_try : I64 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : I64 -> I16
to_i16_try : I64 -> Try(I16, [OutOfRange])
to_i16_try : I64 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : I64 -> I32
to_i32_try : I64 -> Try(I32, [OutOfRange])
to_i32_try : I64 -> Try(I32, [OutOfRange, ..others])
to_i128 : I64 -> I128
# Conversions to unsigned integers (all lossy for negative values)
to_u8_wrap : I64 -> U8
to_u8_try : I64 -> Try(U8, [OutOfRange])
to_u8_try : I64 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : I64 -> U16
to_u16_try : I64 -> Try(U16, [OutOfRange])
to_u16_try : I64 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : I64 -> U32
to_u32_try : I64 -> Try(U32, [OutOfRange])
to_u32_try : I64 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : I64 -> U64
to_u64_try : I64 -> Try(U64, [OutOfRange])
to_u64_try : I64 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : I64 -> U128
to_u128_try : I64 -> Try(U128, [OutOfRange])
to_u128_try : I64 -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : I64 -> F32
to_f64 : I64 -> F64
to_dec : I64 -> Dec
}
U128 :: [].{
to_str : U128 -> Str
is_zero : U128 -> Bool
@ -590,6 +703,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : U128, U128 -> Bool
is_lt : U128, U128 -> Bool
is_lte : U128, U128 -> Bool
plus : U128, U128 -> U128
minus : U128, U128 -> U128
times : U128, U128 -> U128
@ -598,31 +712,41 @@ ok.is_eq : ok, ok -> Bool
rem_by : U128, U128 -> U128
mod_by : U128, U128 -> U128
abs_diff : U128, U128 -> U128
from_int_digits : List(U8) -> Try(U128, [OutOfRange])
from_numeral : Numeral -> Try(U128, [InvalidNumeral(Str)])
from_str : Str -> Try(U128, [BadNumStr])
from_int_digits : List(U8) -> Try(U128, [OutOfRange, ..others])
from_numeral : Numeral -> Try(U128, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(U128, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : U128 -> I8
to_i8_try : U128 -> Try(I8, [OutOfRange])
to_i8_try : U128 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : U128 -> I16
to_i16_try : U128 -> Try(I16, [OutOfRange])
to_i16_try : U128 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : U128 -> I32
to_i32_try : U128 -> Try(I32, [OutOfRange])
to_i32_try : U128 -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : U128 -> I64
to_i64_try : U128 -> Try(I64, [OutOfRange])
to_i64_try : U128 -> Try(I64, [OutOfRange, ..others])
to_i128_wrap : U128 -> I128
to_i128_try : U128 -> Try(I128, [OutOfRange])
to_i128_try : U128 -> Try(I128, [OutOfRange, ..others])
# Conversions to unsigned integers
to_u8_wrap : U128 -> U8
to_u8_try : U128 -> Try(U8, [OutOfRange])
to_u8_try : U128 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : U128 -> U16
to_u16_try : U128 -> Try(U16, [OutOfRange])
to_u16_try : U128 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : U128 -> U32
to_u32_try : U128 -> Try(U32, [OutOfRange])
to_u32_try : U128 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : U128 -> U64
to_u64_try : U128 -> Try(U64, [OutOfRange])
to_u64_try : U128 -> Try(U64, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : U128 -> F32
to_f64 : U128 -> F64
to_dec_try : U128 -> Try(Dec, [OutOfRange])
# Conversion to Dec (can overflow)
to_dec_try : U128 -> Try(Dec, [OutOfRange, ..others])
}
I128 :: [].{
to_str : I128 -> Str
is_zero : I128 -> Bool
@ -633,6 +757,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : I128, I128 -> Bool
is_lt : I128, I128 -> Bool
is_lte : I128, I128 -> Bool
negate : I128 -> I128
abs : I128 -> I128
plus : I128, I128 -> I128
@ -643,31 +768,41 @@ ok.is_eq : ok, ok -> Bool
rem_by : I128, I128 -> I128
mod_by : I128, I128 -> I128
abs_diff : I128, I128 -> U128
from_int_digits : List(U8) -> Try(I128, [OutOfRange])
from_numeral : Numeral -> Try(I128, [InvalidNumeral(Str)])
from_str : Str -> Try(I128, [BadNumStr])
from_int_digits : List(U8) -> Try(I128, [OutOfRange, ..others])
from_numeral : Numeral -> Try(I128, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(I128, [BadNumStr, ..others])
# Conversions to signed integers
to_i8_wrap : I128 -> I8
to_i8_try : I128 -> Try(I8, [OutOfRange])
to_i8_try : I128 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : I128 -> I16
to_i16_try : I128 -> Try(I16, [OutOfRange])
to_i16_try : I128 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : I128 -> I32
to_i32_try : I128 -> Try(I32, [OutOfRange])
to_i32_try : I128 -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : I128 -> I64
to_i64_try : I128 -> Try(I64, [OutOfRange])
to_i64_try : I128 -> Try(I64, [OutOfRange, ..others])
# Conversions to unsigned integers (all lossy for negative values)
to_u8_wrap : I128 -> U8
to_u8_try : I128 -> Try(U8, [OutOfRange])
to_u8_try : I128 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : I128 -> U16
to_u16_try : I128 -> Try(U16, [OutOfRange])
to_u16_try : I128 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : I128 -> U32
to_u32_try : I128 -> Try(U32, [OutOfRange])
to_u32_try : I128 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : I128 -> U64
to_u64_try : I128 -> Try(U64, [OutOfRange])
to_u64_try : I128 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : I128 -> U128
to_u128_try : I128 -> Try(U128, [OutOfRange])
to_u128_try : I128 -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (all safe)
to_f32 : I128 -> F32
to_f64 : I128 -> F64
to_dec_try : I128 -> Try(Dec, [OutOfRange])
# Conversion to Dec (can overflow)
to_dec_try : I128 -> Try(Dec, [OutOfRange, ..others])
}
Dec :: [].{
to_str : Dec -> Str
is_zero : Dec -> Bool
@ -678,6 +813,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : Dec, Dec -> Bool
is_lt : Dec, Dec -> Bool
is_lte : Dec, Dec -> Bool
negate : Dec -> Dec
abs : Dec -> Dec
plus : Dec, Dec -> Dec
@ -687,34 +823,42 @@ ok.is_eq : ok, ok -> Bool
div_trunc_by : Dec, Dec -> Dec
rem_by : Dec, Dec -> Dec
abs_diff : Dec, Dec -> Dec
from_int_digits : List(U8) -> Try(Dec, [OutOfRange])
from_dec_digits : (List(U8), List(U8)) -> Try(Dec, [OutOfRange])
from_numeral : Numeral -> Try(Dec, [InvalidNumeral(Str)])
from_str : Str -> Try(Dec, [BadNumStr])
from_int_digits : List(U8) -> Try(Dec, [OutOfRange, ..others])
from_dec_digits : (List(U8), List(U8)) -> Try(Dec, [OutOfRange, ..others])
from_numeral : Numeral -> Try(Dec, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(Dec, [BadNumStr, ..others])
# Conversions to signed integers (all lossy - truncates fractional part)
to_i8_wrap : Dec -> I8
to_i8_try : Dec -> Try(I8, [OutOfRange])
to_i8_try : Dec -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : Dec -> I16
to_i16_try : Dec -> Try(I16, [OutOfRange])
to_i16_try : Dec -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : Dec -> I32
to_i32_try : Dec -> Try(I32, [OutOfRange])
to_i32_try : Dec -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : Dec -> I64
to_i64_try : Dec -> Try(I64, [OutOfRange])
to_i64_try : Dec -> Try(I64, [OutOfRange, ..others])
to_i128_wrap : Dec -> I128
to_i128_try : Dec -> Try(I128, [OutOfRange])
to_i128_try : Dec -> Try(I128, [OutOfRange, ..others])
# Conversions to unsigned integers (all lossy - truncates fractional part)
to_u8_wrap : Dec -> U8
to_u8_try : Dec -> Try(U8, [OutOfRange])
to_u8_try : Dec -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : Dec -> U16
to_u16_try : Dec -> Try(U16, [OutOfRange])
to_u16_try : Dec -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : Dec -> U32
to_u32_try : Dec -> Try(U32, [OutOfRange])
to_u32_try : Dec -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : Dec -> U64
to_u64_try : Dec -> Try(U64, [OutOfRange])
to_u64_try : Dec -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : Dec -> U128
to_u128_try : Dec -> Try(U128, [OutOfRange])
to_u128_try : Dec -> Try(U128, [OutOfRange, ..others])
# Conversions to floating point (lossy - Dec has more precision)
to_f32_wrap : Dec -> F32
to_f32_try : Dec -> Try(F32, [OutOfRange])
to_f32_try : Dec -> Try(F32, [OutOfRange, ..others])
to_f64 : Dec -> F64
}
F32 :: [].{
to_str : F32 -> Str
is_zero : F32 -> Bool
@ -724,6 +868,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : F32, F32 -> Bool
is_lt : F32, F32 -> Bool
is_lte : F32, F32 -> Bool
negate : F32 -> F32
abs : F32 -> F32
plus : F32, F32 -> F32
@ -733,32 +878,40 @@ ok.is_eq : ok, ok -> Bool
div_trunc_by : F32, F32 -> F32
rem_by : F32, F32 -> F32
abs_diff : F32, F32 -> F32
from_int_digits : List(U8) -> Try(F32, [OutOfRange])
from_dec_digits : (List(U8), List(U8)) -> Try(F32, [OutOfRange])
from_numeral : Numeral -> Try(F32, [InvalidNumeral(Str)])
from_str : Str -> Try(F32, [BadNumStr])
from_int_digits : List(U8) -> Try(F32, [OutOfRange, ..others])
from_dec_digits : (List(U8), List(U8)) -> Try(F32, [OutOfRange, ..others])
from_numeral : Numeral -> Try(F32, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(F32, [BadNumStr, ..others])
# Conversions to signed integers (all lossy - truncation + range check)
to_i8_wrap : F32 -> I8
to_i8_try : F32 -> Try(I8, [OutOfRange])
to_i8_try : F32 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : F32 -> I16
to_i16_try : F32 -> Try(I16, [OutOfRange])
to_i16_try : F32 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : F32 -> I32
to_i32_try : F32 -> Try(I32, [OutOfRange])
to_i32_try : F32 -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : F32 -> I64
to_i64_try : F32 -> Try(I64, [OutOfRange])
to_i64_try : F32 -> Try(I64, [OutOfRange, ..others])
to_i128_wrap : F32 -> I128
to_i128_try : F32 -> Try(I128, [OutOfRange])
to_i128_try : F32 -> Try(I128, [OutOfRange, ..others])
# Conversions to unsigned integers (all lossy - truncation + range check)
to_u8_wrap : F32 -> U8
to_u8_try : F32 -> Try(U8, [OutOfRange])
to_u8_try : F32 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : F32 -> U16
to_u16_try : F32 -> Try(U16, [OutOfRange])
to_u16_try : F32 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : F32 -> U32
to_u32_try : F32 -> Try(U32, [OutOfRange])
to_u32_try : F32 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : F32 -> U64
to_u64_try : F32 -> Try(U64, [OutOfRange])
to_u64_try : F32 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : F32 -> U128
to_u128_try : F32 -> Try(U128, [OutOfRange])
to_u128_try : F32 -> Try(U128, [OutOfRange, ..others])
# Conversion to F64 (safe widening)
to_f64 : F32 -> F64
}
F64 :: [].{
to_str : F64 -> Str
is_zero : F64 -> Bool
@ -768,6 +921,7 @@ ok.is_eq : ok, ok -> Bool
is_gte : F64, F64 -> Bool
is_lt : F64, F64 -> Bool
is_lte : F64, F64 -> Bool
negate : F64 -> F64
abs : F64 -> F64
plus : F64, F64 -> F64
@ -777,32 +931,40 @@ ok.is_eq : ok, ok -> Bool
div_trunc_by : F64, F64 -> F64
rem_by : F64, F64 -> F64
abs_diff : F64, F64 -> F64
from_int_digits : List(U8) -> Try(F64, [OutOfRange])
from_dec_digits : (List(U8), List(U8)) -> Try(F64, [OutOfRange])
from_numeral : Numeral -> Try(F64, [InvalidNumeral(Str)])
from_str : Str -> Try(F64, [BadNumStr])
from_int_digits : List(U8) -> Try(F64, [OutOfRange, ..others])
from_dec_digits : (List(U8), List(U8)) -> Try(F64, [OutOfRange, ..others])
from_numeral : Numeral -> Try(F64, [InvalidNumeral(Str), ..others])
from_str : Str -> Try(F64, [BadNumStr, ..others])
# Conversions to signed integers (all lossy - truncation + range check)
to_i8_wrap : F64 -> I8
to_i8_try : F64 -> Try(I8, [OutOfRange])
to_i8_try : F64 -> Try(I8, [OutOfRange, ..others])
to_i16_wrap : F64 -> I16
to_i16_try : F64 -> Try(I16, [OutOfRange])
to_i16_try : F64 -> Try(I16, [OutOfRange, ..others])
to_i32_wrap : F64 -> I32
to_i32_try : F64 -> Try(I32, [OutOfRange])
to_i32_try : F64 -> Try(I32, [OutOfRange, ..others])
to_i64_wrap : F64 -> I64
to_i64_try : F64 -> Try(I64, [OutOfRange])
to_i64_try : F64 -> Try(I64, [OutOfRange, ..others])
to_i128_wrap : F64 -> I128
to_i128_try : F64 -> Try(I128, [OutOfRange])
to_i128_try : F64 -> Try(I128, [OutOfRange, ..others])
# Conversions to unsigned integers (all lossy - truncation + range check)
to_u8_wrap : F64 -> U8
to_u8_try : F64 -> Try(U8, [OutOfRange])
to_u8_try : F64 -> Try(U8, [OutOfRange, ..others])
to_u16_wrap : F64 -> U16
to_u16_try : F64 -> Try(U16, [OutOfRange])
to_u16_try : F64 -> Try(U16, [OutOfRange, ..others])
to_u32_wrap : F64 -> U32
to_u32_try : F64 -> Try(U32, [OutOfRange])
to_u32_try : F64 -> Try(U32, [OutOfRange, ..others])
to_u64_wrap : F64 -> U64
to_u64_try : F64 -> Try(U64, [OutOfRange])
to_u64_try : F64 -> Try(U64, [OutOfRange, ..others])
to_u128_wrap : F64 -> U128
to_u128_try : F64 -> Try(U128, [OutOfRange])
to_u128_try : F64 -> Try(U128, [OutOfRange, ..others])
# Conversion to F32 (lossy narrowing)
to_f32_wrap : F64 -> F32
to_f32_try : F64 -> Try(F32, [OutOfRange])
to_f32_try : F64 -> Try(F32, [OutOfRange, ..others])
to_f32_try = |num| {
answer = f64_to_f32_try_unsafe(num)
if answer.success != 0 {

View file

@ -534,14 +534,18 @@ const Formatter = struct {
try fmt.pushAll(".");
try fmt.push('{');
if (assoc.statements.span.len > 0) {
try fmt.ensureNewline();
fmt.curr_indent += 1;
const statements = fmt.ast.store.statementSlice(assoc.statements);
for (statements) |stmt_idx| {
const stmt_region = fmt.nodeRegion(@intFromEnum(stmt_idx));
_ = try fmt.flushCommentsBefore(stmt_region.start);
try fmt.ensureNewline();
try fmt.pushIndent();
_ = try fmt.formatStatement(stmt_idx);
try fmt.ensureNewline();
}
// Flush any trailing comments before the closing brace
_ = try fmt.flushCommentsBefore(assoc.region.end - 1);
try fmt.ensureNewline();
fmt.curr_indent -= 1;
try fmt.pushIndent();
}
@ -702,10 +706,8 @@ const Formatter = struct {
// Add opening bracket
if (clauses_are_multiline) {
try fmt.ensureNewline();
try fmt.pushAll(" [");
fmt.curr_indent += 1;
try fmt.pushIndent();
try fmt.push('[');
} else {
try fmt.pushAll(" [");
}
@ -714,19 +716,25 @@ const Formatter = struct {
if (clauses_are_multiline) {
const clause_region = fmt.nodeRegion(@intFromEnum(clause));
_ = try fmt.flushCommentsBefore(clause_region.start);
try fmt.ensureNewline();
try fmt.pushIndent();
}
if (i > 0) {
if (clauses_are_multiline) {
try fmt.push(',');
try fmt.ensureNewline();
try fmt.pushIndent();
} else {
if (!clauses_are_multiline) {
try fmt.pushAll(", ");
}
}
try fmt.formatWhereClause(clause);
if (clauses_are_multiline) {
try fmt.push(',');
}
}
if (clauses_are_multiline) {
try fmt.ensureNewline();
fmt.curr_indent -= 1;
try fmt.pushIndent();
}
try fmt.push(']');
}
@ -1965,7 +1973,56 @@ const Formatter = struct {
},
.tag_union => |t| {
region = t.region;
try fmt.formatCollection(t.region, .square, AST.TypeAnno.Idx, fmt.ast.store.typeAnnoSlice(t.tags), Formatter.formatTypeAnno);
const tags = fmt.ast.store.typeAnnoSlice(t.tags);
const has_open = t.open_anno != null;
const tag_multiline = fmt.ast.regionIsMultiline(region) or fmt.nodesWillBeMultiline(AST.TypeAnno.Idx, tags);
const tag_indent = fmt.curr_indent;
defer {
fmt.curr_indent = tag_indent;
}
try fmt.push('[');
if (tags.len == 0 and !has_open) {
try fmt.push(']');
} else {
if (tag_multiline) {
fmt.curr_indent += 1;
}
for (tags, 0..) |tag_idx, i| {
const tag_region = fmt.nodeRegion(@intFromEnum(tag_idx));
if (tag_multiline) {
_ = try fmt.flushCommentsBefore(tag_region.start);
try fmt.ensureNewline();
try fmt.pushIndent();
}
_ = try fmt.formatTypeAnno(tag_idx);
if (tag_multiline) {
try fmt.push(',');
} else if (i < (tags.len - 1) or has_open) {
try fmt.pushAll(", ");
}
}
// Handle the open extension (..others)
if (t.open_anno) |open| {
const open_region = fmt.nodeRegion(@intFromEnum(open));
if (tag_multiline) {
_ = try fmt.flushCommentsBefore(open_region.start);
try fmt.ensureNewline();
try fmt.pushIndent();
}
try fmt.pushAll("..");
_ = try fmt.formatTypeAnno(open);
if (tag_multiline) {
try fmt.push(',');
}
}
if (tag_multiline) {
_ = try fmt.flushCommentsBefore(region.end - 1);
fmt.curr_indent -= 1;
try fmt.ensureNewline();
try fmt.pushIndent();
}
try fmt.push(']');
}
},
.@"fn" => |f| {
region = f.region;