diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/lux/data/number/i64.lux | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/stdlib/source/lux/data/number/i64.lux b/stdlib/source/lux/data/number/i64.lux index 79bf7632d..249ae9046 100644 --- a/stdlib/source/lux/data/number/i64.lux +++ b/stdlib/source/lux/data/number/i64.lux @@ -143,25 +143,33 @@ [conjunction ..true ..and] ) -(type: #export (Sub size) - {#narrow (-> I64 (I64 size)) - #wide (-> (I64 size) I64) - #equivalence (Equivalence (I64 size))}) +(signature: #export (Sub size) + (: (Equivalence (I64 size)) + &equivalence) + (: Nat + width) + (: (-> I64 (I64 size)) + narrow) + (: (-> (I64 size) I64) + widen)) (def: #export (sub width) (Ex [size] (-> Nat (Maybe (Sub size)))) (if (.and (n.> 0 width) (n.< ..width width)) - (let [top (dec width) - shift (n.- width ..width) - sign (..bit top) - number (..mask (dec width))] - (#.Some {#narrow (function (narrow value) - (..or (|> value (..and ..sign) (..logic-right-shift shift)) - (|> value (..and number)))) - #wide (function (wide value) - (|> (..or (|> value (..and sign) (..left-shift shift)) - (|> value (..clear top))) - .i64)) - #equivalence ..equivalence})) + (let [sign-shift (n.- width ..width) + sign (..bit (dec width)) + mantissa (..mask (dec width)) + co-mantissa (..xor (.i64 -1) mantissa)] + (#.Some (: Sub + (structure + (def: &equivalence ..equivalence) + (def: width width) + (def: (narrow value) + (..or (|> value (..and ..sign) (..logic-right-shift sign-shift)) + (|> value (..and mantissa)))) + (def: (widen value) + (.i64 (case (.nat (..and sign value)) + 0 value + _ (..or co-mantissa value)))))))) #.None)) |