restore_raw_number.bend

bendvy-ecs-core@0.1.0.1 · 34 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/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{}