restore_raw_number.bend
bendvy-ecs-core@0.1.0.0 · 34 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/decode_data.bend as D
3
4type Checked is Data:
5 Value{value:U32}
6 Invalid{}
7def shifted(count:Nat,value:U32) -> U32:
8 match count:
9 case 0n: value
10 case 1n+rest: shifted(rest,U32.mul(value,2))
11def finite_checked(valid:Bool,value:U32,exponent:U32) -> Checked:
12 match valid:
13 case True{}:Value{shifted(U32.to_nat(U32.sub(exponent,1074)),value)}
14 case False{}:Invalid{}
15def finite(negative:Bool,high:U32,+low:U32,+exponent:U32) -> Checked:
16 match negative high low:
17 case False{} 0 0:Value{0}
18 case False{} 0 n:finite_checked(U32.is_ge(exponent,1074) && U32.is_le(exponent,1105) && U32.is_le(exponent,U32.add(1074,U32.sub(31,U32.from_nat(U32.log2(n))))),n,exponent)
19 case _ _ _:Invalid{}
20def normalized(value:D.Numeric) -> Checked:
21 match value:
22 case D.Finite{negative,high,low,exponent}:finite(negative,high,low,exponent)
23 case _:Invalid{}
24def signed(valid:Bool,magnitude:Nat) -> Checked:
25 match valid:
26 case True{}:Value{U32.from_nat(magnitude)}
27 case False{}:Invalid{}
28def checked(raw:D.Raw) -> Checked:
29 match raw:
30 case D.Number{value}:Value{value}
31 case D.SignedInteger{negative,+magnitude}:signed((Bool.not(negative) || Nat.is_eq(magnitude,0n)) && Nat.is_le(magnitude,4294967295n),magnitude)
32 case D.Float{value}:normalized(D.float_numeric(F32.bits(value)))
33 case D.Binary64{high,low}:normalized(D.binary_numeric(high,low))
34 case _:Invalid{}