0 | module JS.Number
  1 |
  2 | import Data.DPair
  3 | import Data.Bits
  4 | import JS.Inheritance
  5 | import JS.Marshall
  6 | import JS.Util
  7 |
  8 | %default total
  9 |
 10 | --------------------------------------------------------------------------------
 11 | --          Primitives
 12 | --------------------------------------------------------------------------------
 13 |
 14 | %foreign "javascript:lambda:(a,b)=>a % b"
 15 | prim__mod : Double -> Double -> Double
 16 |
 17 | %foreign "javascript:lambda:(a,b)=>Math.trunc(a / b)"
 18 | prim__div : Double -> Double -> Double
 19 |
 20 | %foreign "javascript:lambda:v=>Number.isInteger(v)?v:Math.trunc(v)"
 21 | prim__toIntegral : AnyPtr -> AnyPtr
 22 |
 23 | %foreign "javascript:lambda:(v,b)=>v >= b || v < (-b)?v%b:v"
 24 | prim__truncSigned : Double -> Double -> Double
 25 |
 26 | %foreign "javascript:lambda:(v,b)=>v >= b || v < 0?Math.abs(v)%b:v"
 27 | prim__truncUnsigned : Double -> Double -> Double
 28 |
 29 | %foreign "javascript:lambda:(a,b)=>a & b"
 30 | prim__and : Double -> Double -> Double
 31 |
 32 | %foreign "javascript:lambda:(a,b)=>a | b"
 33 | prim__or : Double -> Double -> Double
 34 |
 35 | %foreign "javascript:lambda:(a,b)=>a ^ b"
 36 | prim__xor : Double -> Double -> Double
 37 |
 38 | %foreign "javascript:lambda:(a,b)=>a >> b"
 39 | prim__shr : Double -> Double -> Double
 40 |
 41 | %foreign "javascript:lambda:(a,x,b)=>{ res = a << b; res & x ? res | (-x) : res & (x-1) }"
 42 | prim__shlSigned : Double -> Double -> Double -> Double
 43 |
 44 | %foreign "javascript:lambda:(a,x,b)=> (a << b) & x"
 45 | prim__shlUnsigned : Double -> Double -> Double -> Double
 46 |
 47 | %foreign "javascript:lambda:x=> Number.isInteger(x)?1:0"
 48 | prim__isInteger : AnyPtr -> Double
 49 |
 50 | --------------------------------------------------------------------------------
 51 | --          JSInt64
 52 | --------------------------------------------------------------------------------
 53 |
 54 | ||| A 64-bit signed integer in the range [-9223372036854775808,9223372036854775807]
 55 | |||
 56 | ||| This corresponds to the `Long Long` WebIDL type.
 57 | ||| Internally, the number is represented by a
 58 | ||| Javascript `Number`.
 59 | ||| Note, that arithmetic operations on this type might result
 60 | ||| in rounding errors, since values might be outside the range
 61 | ||| of safe integral arithmetics (up to 2^53). Use this type only for
 62 | ||| interacting with external API requiring values of this type.
 63 | export
 64 | data JSInt64 : Type where [external]
 65 |
 66 | export
 67 | fromJSInt64 : JSInt64 -> Double
 68 | fromJSInt64 = believe_me
 69 |
 70 | -- internal precondition: v is an integer
 71 | toJSInt64 : Double -> JSInt64
 72 | toJSInt64 = believe_me
 73 |
 74 | -- internal precondition: v is an integer
 75 | truncToJSInt64 : Double -> JSInt64
 76 | truncToJSInt64 v = toJSInt64 (prim__truncSigned v 9223372036854775808.0)
 77 |
 78 | export
 79 | Show JSInt64 where
 80 |   show = jsShow
 81 |
 82 | export
 83 | Eq JSInt64 where
 84 |   (==) = (==) `on` fromJSInt64
 85 |
 86 | export
 87 | Ord JSInt64 where
 88 |   compare = compare `on` fromJSInt64
 89 |
 90 | export
 91 | Num JSInt64 where
 92 |   a + b = truncToJSInt64 $ fromJSInt64 a + fromJSInt64 b
 93 |   a * b = truncToJSInt64 $ fromJSInt64 a * fromJSInt64 b
 94 |   fromInteger = truncToJSInt64 . fromInteger
 95 |
 96 | export
 97 | Neg JSInt64 where
 98 |   negate = truncToJSInt64 . negate . fromJSInt64
 99 |   a - b  = truncToJSInt64 $ fromJSInt64 a - fromJSInt64 b
100 |
101 | export
102 | Integral JSInt64 where
103 |   a `div` b = toJSInt64 $ prim__div (fromJSInt64 a) (fromJSInt64 b)
104 |   a `mod` b = toJSInt64 $ prim__mod (fromJSInt64 a) (fromJSInt64 b)
105 |
106 | export
107 | ToFFI JSInt64 JSInt64 where toFFI = id
108 |
109 | export
110 | FromFFI JSInt64 JSInt64 where fromFFI = Just
111 |
112 | export
113 | SafeCast JSInt64 where
114 |   safeCast = bounded (-9223372036854775808) 9223372036854775808
115 |
116 |
117 | --------------------------------------------------------------------------------
118 | --          JSBits64
119 | --------------------------------------------------------------------------------
120 |
121 | ||| A 64-bit unsigned integer in the range [0,18446744073709551615].
122 | |||
123 | ||| This corresponds to the `Unsigned Long Long` WebIDL type.
124 | ||| Internally, the number is represented by a Javascript `Number`.
125 | ||| Note, that this type is therefore susceptible to
126 | ||| rounding errors, since values might be outside the range
127 | ||| of safe integral arithmetics (up to 2^53). Use this type only for
128 | ||| interacting with external API requiring values of this type.
129 | export
130 | data JSBits64 : Type where [external]
131 |
132 | export
133 | fromUInt64 : JSBits64 -> Double
134 | fromUInt64 = believe_me
135 |
136 | -- internal precondition: v is a non-negative integer
137 | toUInt64 : Double -> JSBits64
138 | toUInt64 = believe_me
139 |
140 | -- internal precondition: v is an integer
141 | truncToUInt64 : Double -> JSBits64
142 | truncToUInt64 v = toUInt64 (prim__truncUnsigned v 18446744073709551616.0)
143 |
144 | export
145 | Show JSBits64 where
146 |   show = jsShow
147 |
148 | export
149 | Eq JSBits64 where
150 |   (==) = (==) `on` fromUInt64
151 |
152 | export
153 | Ord JSBits64 where
154 |   compare = compare `on` fromUInt64
155 |
156 | export
157 | Num JSBits64 where
158 |   a + b = truncToUInt64 $ fromUInt64 a + fromUInt64 b
159 |   a * b = truncToUInt64 $ fromUInt64 a * fromUInt64 b
160 |   fromInteger = truncToUInt64 . fromInteger
161 |
162 | export
163 | Integral JSBits64 where
164 |   a `div` b = toUInt64 $ prim__div (fromUInt64 a) (fromUInt64 b)
165 |   a `mod` b = toUInt64 $ prim__mod (fromUInt64 a) (fromUInt64 b)
166 |
167 | export
168 | ToFFI JSBits64 JSBits64 where toFFI = id
169 |
170 | export
171 | FromFFI JSBits64 JSBits64 where fromFFI = Just
172 |
173 | export
174 | SafeCast JSBits64 where
175 |   safeCast = bounded 0 18446744073709551615
176 |