1{-# LANGUAGE RankNTypes, ScopedTypeVariables, PatternGuards #-}
3module Idris.Primitives(primitives, Prim(..)) where
10import Idris.Core.Evaluate
15import Data.Function (on)
16import Data.Vector.Unboxed (Vector)
17import qualified Data.Vector.Unboxed as V
19data Prim = Prim { p_name :: Name,
22 p_def :: [Const] -> Maybe Const,
23 p_lexp :: (Int, PrimFn),
27ty :: [Const] -> Const -> Type
29ty (t:ts) x = Bind (sMN 0 "T") (Pi (Constant t) (TType (UVar (-3)))) (ty ts x)
31total, partial, iopartial :: Totality
33partial = Partial NotCovering
34iopartial = Partial ExternalIO
39 [iCoerce (ITFixed IT8) (ITFixed IT16) "zext" zext LZExt,
40 iCoerce (ITFixed IT8) (ITFixed IT32) "zext" zext LZExt,
41 iCoerce (ITFixed IT8) (ITFixed IT64) "zext" zext LZExt,
42 iCoerce (ITFixed IT8) ITBig "zext" zext LZExt,
43 iCoerce (ITFixed IT8) ITNative "zext" zext LZExt,
44 iCoerce (ITFixed IT16) (ITFixed IT32) "zext" zext LZExt,
45 iCoerce (ITFixed IT16) (ITFixed IT64) "zext" zext LZExt,
46 iCoerce (ITFixed IT16) ITBig "zext" zext LZExt,
47 iCoerce (ITFixed IT16) ITNative "zext" zext LZExt,
48 iCoerce (ITFixed IT32) (ITFixed IT64) "zext" zext LZExt,
49 iCoerce (ITFixed IT32) ITBig "zext" zext LZExt,
50 iCoerce (ITFixed IT32) ITNative "zext" zext LZExt,
51 iCoerce (ITFixed IT64) ITBig "zext" zext LZExt,
52 iCoerce ITNative ITBig "zext" zext LZExt,
53 iCoerce ITNative (ITFixed IT64) "zext" zext LZExt,
54 iCoerce ITNative (ITFixed IT32) "zext" zext LZExt,
55 iCoerce ITNative (ITFixed IT16) "zext" zext LZExt,
56 iCoerce ITChar ITBig "zext" zext LZExt,
58 iCoerce (ITFixed IT8) (ITFixed IT16) "sext" sext LSExt,
59 iCoerce (ITFixed IT8) (ITFixed IT32) "sext" sext LSExt,
60 iCoerce (ITFixed IT8) (ITFixed IT64) "sext" sext LSExt,
61 iCoerce (ITFixed IT8) ITBig "sext" sext LSExt,
62 iCoerce (ITFixed IT8) ITNative "sext" sext LSExt,
63 iCoerce (ITFixed IT16) (ITFixed IT32) "sext" sext LSExt,
64 iCoerce (ITFixed IT16) (ITFixed IT64) "sext" sext LSExt,
65 iCoerce (ITFixed IT16) ITBig "sext" sext LSExt,
66 iCoerce (ITFixed IT16) ITNative "sext" sext LSExt,
67 iCoerce (ITFixed IT32) (ITFixed IT64) "sext" sext LSExt,
68 iCoerce (ITFixed IT32) ITBig "sext" sext LSExt,
69 iCoerce (ITFixed IT32) ITNative "sext" sext LSExt,
70 iCoerce (ITFixed IT64) ITBig "sext" sext LSExt,
71 iCoerce ITNative ITBig "sext" sext LSExt,
72 iCoerce ITNative ITBig "sext" sext LSExt,
73 iCoerce ITNative (ITFixed IT64) "sext" sext LSExt,
74 iCoerce ITNative (ITFixed IT32) "sext" sext LSExt,
75 iCoerce ITNative (ITFixed IT16) "sext" sext LSExt,
76 iCoerce ITChar ITBig "sext" sext LSExt,
78 iCoerce (ITFixed IT16) (ITFixed IT8) "trunc" trunc LTrunc,
79 iCoerce (ITFixed IT32) (ITFixed IT8) "trunc" trunc LTrunc,
80 iCoerce (ITFixed IT64) (ITFixed IT8) "trunc" trunc LTrunc,
81 iCoerce ITBig (ITFixed IT8) "trunc" trunc LTrunc,
82 iCoerce ITNative (ITFixed IT8) "trunc" trunc LTrunc,
83 iCoerce (ITFixed IT32) (ITFixed IT16) "trunc" trunc LTrunc,
84 iCoerce (ITFixed IT64) (ITFixed IT16) "trunc" trunc LTrunc,
85 iCoerce ITBig (ITFixed IT16) "trunc" trunc LTrunc,
86 iCoerce ITNative (ITFixed IT16) "trunc" trunc LTrunc,
87 iCoerce (ITFixed IT64) (ITFixed IT32) "trunc" trunc LTrunc,
88 iCoerce ITBig (ITFixed IT32) "trunc" trunc LTrunc,
89 iCoerce ITNative (ITFixed IT32) "trunc" trunc LTrunc,
90 iCoerce ITBig (ITFixed IT64) "trunc" trunc LTrunc,
91 iCoerce (ITFixed IT16) ITNative "trunc" trunc LTrunc,
92 iCoerce (ITFixed IT32) ITNative "trunc" trunc LTrunc,
93 iCoerce (ITFixed IT64) ITNative "trunc" trunc LTrunc,
94 iCoerce ITBig ITNative "trunc" trunc LTrunc,
95 iCoerce ITNative (ITFixed IT64) "trunc" trunc LTrunc,
96 iCoerce ITBig ITChar "trunc" trunc LTrunc,
98 Prim (sUN "prim__addFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType ATFloat)) 2 (fBin (+))
99 (2, LPlus ATFloat) total,
100 Prim (sUN "prim__subFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType ATFloat)) 2 (fBin (-))
101 (2, LMinus ATFloat) total,
102 Prim (sUN "prim__mulFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType ATFloat)) 2 (fBin (*))
103 (2, LTimes ATFloat) total,
104 Prim (sUN "prim__divFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType ATFloat)) 2 (fBin (/))
105 (2, LSDiv ATFloat) total,
106 Prim (sUN "prim__eqFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType (ATInt ITNative))) 2 (bfBin (==))
107 (2, LEq ATFloat) total,
108 Prim (sUN "prim__sltFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType (ATInt ITNative))) 2 (bfBin (<))
109 (2, LSLt ATFloat) total,
110 Prim (sUN "prim__slteFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType (ATInt ITNative))) 2 (bfBin (<=))
111 (2, LSLe ATFloat) total,
112 Prim (sUN "prim__sgtFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType (ATInt ITNative))) 2 (bfBin (>))
113 (2, LSGt ATFloat) total,
114 Prim (sUN "prim__sgteFloat") (ty [(AType ATFloat), (AType ATFloat)] (AType (ATInt ITNative))) 2 (bfBin (>=))
115 (2, LSGe ATFloat) total,
116 Prim (sUN "prim__concat") (ty [StrType, StrType] StrType) 2 (sBin (++))
117 (2, LStrConcat) total,
118 Prim (sUN "prim__eqString") (ty [StrType, StrType] (AType (ATInt ITNative))) 2 (bsBin (==))
120 Prim (sUN "prim__ltString") (ty [StrType, StrType] (AType (ATInt ITNative))) 2 (bsBin (<))
122 Prim (sUN "prim_lenString") (ty [StrType] (AType (ATInt ITNative))) 1 (p_strLen)
125 Prim (sUN "prim__charToInt") (ty [(AType (ATInt ITChar))] (AType (ATInt ITNative))) 1 (c_charToInt)
126 (1, LChInt ITNative) total,
127 Prim (sUN "prim__intToChar") (ty [(AType (ATInt ITNative))] (AType (ATInt ITChar))) 1 (c_intToChar)
128 (1, LIntCh ITNative) total,
129 Prim (sUN "prim__strToFloat") (ty [StrType] (AType ATFloat)) 1 (c_strToFloat)
130 (1, LStrFloat) total,
131 Prim (sUN "prim__floatToStr") (ty [(AType ATFloat)] StrType) 1 (c_floatToStr)
132 (1, LFloatStr) total,
134 Prim (sUN "prim__floatExp") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatExp)
136 Prim (sUN "prim__floatLog") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatLog)
138 Prim (sUN "prim__floatSin") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatSin)
140 Prim (sUN "prim__floatCos") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatCos)
142 Prim (sUN "prim__floatTan") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatTan)
144 Prim (sUN "prim__floatASin") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatASin)
146 Prim (sUN "prim__floatACos") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatACos)
148 Prim (sUN "prim__floatATan") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatATan)
150 Prim (sUN "prim__floatSqrt") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatSqrt)
152 Prim (sUN "prim__floatFloor") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatFloor)
154 Prim (sUN "prim__floatCeil") (ty [(AType ATFloat)] (AType ATFloat)) 1 (p_floatCeil)
156 Prim (sUN "prim__negFloat") (ty [(AType ATFloat)] (AType ATFloat)) 1 (c_negFloat)
159 Prim (sUN "prim__strHead") (ty [StrType] (AType (ATInt ITChar))) 1 (p_strHead)
160 (1, LStrHead) partial,
161 Prim (sUN "prim__strTail") (ty [StrType] StrType) 1 (p_strTail)
162 (1, LStrTail) partial,
163 Prim (sUN "prim__strCons") (ty [(AType (ATInt ITChar)), StrType] StrType) 2 (p_strCons)
165 Prim (sUN "prim__strIndex") (ty [StrType, (AType (ATInt ITNative))] (AType (ATInt ITChar))) 2 (p_strIndex)
166 (2, LStrIndex) partial,
167 Prim (sUN "prim__strRev") (ty [StrType] StrType) 1 (p_strRev)
169 Prim (sUN "prim__readString") (ty [PtrType] StrType) 1 (p_cantreduce)
170 (1, LReadStr) iopartial,
171 Prim (sUN "prim__vm") (ty [] PtrType) 0 (p_cantreduce)
174 Prim (sUN "prim__stdin") (ty [] PtrType) 0 (p_cantreduce)
175 (0, LStdIn) iopartial,
176 Prim (sUN "prim__stdout") (ty [] PtrType) 0 (p_cantreduce)
177 (0, LStdOut) iopartial,
178 Prim (sUN "prim__stderr") (ty [] PtrType) 0 (p_cantreduce)
179 (0, LStdErr) iopartial,
180 Prim (sUN "prim__null") (ty [] PtrType) 0 (p_cantreduce)
182 -- Managed pointer registration
183 Prim (sUN "prim__registerPtr") (ty [PtrType, AType (ATInt ITNative)] ManagedPtrType) 2 (p_cantreduce)
184 (2, LRegisterPtr) total,
186 Prim (sUN "prim__allocate") (ty [AType (ATInt (ITFixed IT64))] BufferType) 1 (p_allocate)
187 (1, LAllocate) total,
188 Prim (sUN "prim__appendBuffer") (ty [BufferType, AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), BufferType] BufferType) 6 (p_appendBuffer)
189 (6, LAppendBuffer) partial,
190 Prim (sUN "prim__systemInfo") (ty [AType (ATInt ITNative)] StrType) 1 (p_cantreduce)
191 (1, LSystemInfo) total
192 ] ++ concatMap intOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64, ITBig, ITNative, ITChar]
193 ++ concatMap vecOps vecTypes
194 ++ concatMap fixedOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64] -- ITNative, ITChar, ATFloat ] ++ vecTypes
195 ++ vecBitcasts vecTypes
198vecTypes = [ITVec IT8 16, ITVec IT16 8, ITVec IT32 4, ITVec IT64 2]
200intOps :: IntTy -> [Prim]
201intOps ity = intCmps ity ++ intArith ity ++ intConv ity
203intSCmps :: IntTy -> [Prim]
205 [ iCmp ity "slt" False (bCmp ity (sCmpOp ity (<))) (LSLt . ATInt) total
206 , iCmp ity "slte" False (bCmp ity (sCmpOp ity (<=))) (LSLe . ATInt) total
207 , iCmp ity "eq" False (bCmp ity (==)) (LEq . ATInt) total
208 , iCmp ity "sgte" False (bCmp ity (sCmpOp ity (>=))) (LSGe . ATInt) total
209 , iCmp ity "sgt" False (bCmp ity (sCmpOp ity (>))) (LSGt . ATInt) total
212intCmps :: IntTy -> [Prim]
213intCmps ITNative = intSCmps ITNative
216 [ iCmp ity "lt" False (bCmp ity (cmpOp ity (<))) LLt total
217 , iCmp ity "lte" False (bCmp ity (cmpOp ity (<=))) LLe total
218 , iCmp ity "gte" False (bCmp ity (cmpOp ity (>=))) LGe total
219 , iCmp ity "gt" False (bCmp ity (cmpOp ity (>))) LGt total
222intArith :: IntTy -> [Prim]
224 [ iBinOp ity "add" (bitBin ity (+)) (LPlus . ATInt) total
225 , iBinOp ity "sub" (bitBin ity (-)) (LMinus . ATInt) total
226 , iBinOp ity "mul" (bitBin ity (*)) (LTimes . ATInt) total
227 , iBinOp ity "udiv" (bitBin ity div) LUDiv partial
228 , iBinOp ity "sdiv" (bsdiv ity) (LSDiv . ATInt) partial
229 , iBinOp ity "urem" (bitBin ity rem) LURem partial
230 , iBinOp ity "srem" (bsrem ity) (LSRem . ATInt) partial
231 , iBinOp ity "shl" (bitBin ity (\x y -> shiftL x (fromIntegral y))) LSHL total
232 , iBinOp ity "lshr" (bitBin ity (\x y -> shiftR x (fromIntegral y))) LLSHR total
233 , iBinOp ity "ashr" (bashr ity) LASHR total
234 , iBinOp ity "and" (bitBin ity (.&.)) LAnd total
235 , iBinOp ity "or" (bitBin ity (.|.)) LOr total
236 , iBinOp ity "xor" (bitBin ity (xor)) LXOr total
237 , iUnOp ity "compl" (bUn ity complement) LCompl total
240intConv :: IntTy -> [Prim]
242 [ Prim (sUN $ "prim__toStr" ++ intTyName ity) (ty [AType . ATInt $ ity] StrType) 1 intToStr
243 (1, LIntStr ity) total
244 , Prim (sUN $ "prim__fromStr" ++ intTyName ity) (ty [StrType] (AType . ATInt $ ity)) 1 (strToInt ity)
245 (1, LStrInt ity) total
246 , Prim (sUN $ "prim__toFloat" ++ intTyName ity) (ty [AType . ATInt $ ity] (AType ATFloat)) 1 intToFloat
247 (1, LIntFloat ity) total
248 , Prim (sUN $ "prim__fromFloat" ++ intTyName ity) (ty [AType ATFloat] (AType . ATInt $ ity)) 1 (floatToInt ity)
249 (1, LFloatInt ity) total
252vecCmps :: IntTy -> [Prim]
254 [ iCmp ity "slt" True (bCmp ity (<)) (LSLt . ATInt) total
255 , iCmp ity "slte" True (bCmp ity (<=)) (LSLe . ATInt) total
256 , iCmp ity "eq" True (bCmp ity (==)) (LEq . ATInt) total
257 , iCmp ity "sgte" True (bCmp ity (>=)) (LSGe . ATInt) total
258 , iCmp ity "sgt" True (bCmp ity (>)) (LSGt . ATInt) total
259 , iCmp ity "lt" True (bCmp ity (<)) LLt total
260 , iCmp ity "lte" True (bCmp ity (<=)) LLe total
261 , iCmp ity "gte" True (bCmp ity (>=)) LGe total
262 , iCmp ity "gt" True (bCmp ity (>)) LGt total
265-- The TODOs in this function are documented as Issue #1617 on the issue tracker.
267-- https://github.com/idris-lang/Idris-dev/issues/1617
268vecOps :: IntTy -> [Prim]
269vecOps ity@(ITVec elem count) =
270 [ Prim (sUN $ "prim__mk" ++ intTyName ity)
271 (ty (replicate count . AType . ATInt . ITFixed $ elem) (AType . ATInt $ ity))
272 count (mkVecCon elem count) (count, LMkVec elem count) total
273 , Prim (sUN $ "prim__index" ++ intTyName ity)
274 (ty [AType . ATInt $ ity, AType (ATInt (ITFixed IT32))] (AType . ATInt . ITFixed $ elem))
275 2 (mkVecIndex count) (2, LIdxVec elem count) partial -- TODO: Ensure this reduces
276 , Prim (sUN $ "prim__update" ++ intTyName ity)
277 (ty [AType . ATInt $ ity, AType (ATInt (ITFixed IT32)), AType . ATInt . ITFixed $ elem]
278 (AType . ATInt $ ity))
279 3 (mkVecUpdate elem count) (3, LUpdateVec elem count) partial -- TODO: Ensure this reduces
280 ] ++ intArith ity ++ vecCmps ity
282bitcastPrim :: ArithTy -> ArithTy -> (ArithTy -> [Const] -> Maybe Const) -> PrimFn -> Prim
283bitcastPrim from to impl prim =
284 Prim (sUN $ "prim__bitcast" ++ aTyName from ++ "_" ++ aTyName to) (ty [AType from] (AType to)) 1 (impl to)
287vecBitcasts :: [IntTy] -> [Prim]
288vecBitcasts tys = [bitcastPrim from to bitcastVec (LBitCast from to)
289 | from <- map ATInt vecTypes, to <- map ATInt vecTypes, from /= to]
291fixedOps :: IntTy -> [Prim]
292fixedOps ity@(ITFixed _) =
293 map appendFun endiannesses ++
294 map peekFun endiannesses
296 endiannesses = [ Native, LE, BE ]
297 tyName = intTyName ity
298 b64 = AType (ATInt (ITFixed IT64))
299 thisTy = AType $ ATInt ity
300 appendFun en = Prim (sUN $ "prim__append" ++ tyName ++ show en)
301 (ty [BufferType, b64, b64, thisTy] BufferType)
302 4 (p_append en) (4, LAppend ity en) partial
303 peekFun en = Prim (sUN $ "prim__peek" ++ tyName ++ show en)
304 (ty [BufferType, b64] thisTy)
305 2 (p_peek ity en) (2, LPeek ity en) partial
307mapHalf :: (V.Unbox a, V.Unbox b) => ((a, a) -> b) -> Vector a -> Vector b
308mapHalf f xs = V.generate (V.length xs `div` 2) (\i -> f (xs V.! (i*2), xs V.! (i*2+1)))
310mapDouble :: (V.Unbox a, V.Unbox b) => (Bool -> a -> b) -> Vector a -> Vector b
311mapDouble f xs = V.generate (V.length xs * 2) (\i -> f (i `rem` 2 == 0) (xs V.! (i `div` 2)))
313concatWord8 :: (Word8, Word8) -> Word16
314concatWord8 (high, low) = fromIntegral high .|. (fromIntegral low `shiftL` 8)
316concatWord16 :: (Word16, Word16) -> Word32
317concatWord16 (high, low) = fromIntegral high .|. (fromIntegral low `shiftL` 16)
319concatWord32 :: (Word32, Word32) -> Word64
320concatWord32 (high, low) = fromIntegral high .|. (fromIntegral low `shiftL` 32)
322truncWord16 :: Bool -> Word16 -> Word8
323truncWord16 True x = fromIntegral (x `shiftR` 8)
324truncWord16 False x = fromIntegral x
326truncWord32 :: Bool -> Word32 -> Word16
327truncWord32 True x = fromIntegral (x `shiftR` 16)
328truncWord32 False x = fromIntegral x
330truncWord64 :: Bool -> Word64 -> Word32
331truncWord64 True x = fromIntegral (x `shiftR` 32)
332truncWord64 False x = fromIntegral x
334bitcastVec :: ArithTy -> [Const] -> Maybe Const
335bitcastVec (ATInt (ITVec IT8 n)) [x@(B8V v)]
336 | V.length v == n = Just x
337bitcastVec (ATInt (ITVec IT16 n)) [B8V v]
338 | V.length v == n*2 = Just . B16V . mapHalf concatWord8 $ v
339bitcastVec (ATInt (ITVec IT32 n)) [B8V v]
340 | V.length v == n*4 = Just . B32V . mapHalf concatWord16 . mapHalf concatWord8 $ v
341bitcastVec (ATInt (ITVec IT64 n)) [B8V v]
342 | V.length v == n*8 = Just . B64V . mapHalf concatWord32 . mapHalf concatWord16 . mapHalf concatWord8 $ v
344bitcastVec (ATInt (ITVec IT8 n)) [B16V v]
345 | V.length v * 2 == n = Just . B8V . mapDouble truncWord16 $ v
346bitcastVec (ATInt (ITVec IT16 n)) [x@(B16V v)]
347 | V.length v == n = Just x
348bitcastVec (ATInt (ITVec IT32 n)) [B16V v]
349 | V.length v == n*2 = Just . B32V . mapHalf concatWord16 $ v
350bitcastVec (ATInt (ITVec IT64 n)) [B16V v]
351 | V.length v == n*4 = Just . B64V . mapHalf concatWord32 . mapHalf concatWord16 $ v
353bitcastVec (ATInt (ITVec IT8 n)) [B32V v]
354 | V.length v * 4 == n = Just . B8V . mapDouble truncWord16 . mapDouble truncWord32 $ v
355bitcastVec (ATInt (ITVec IT16 n)) [B32V v]
356 | V.length v * 2 == n = Just . B16V . mapDouble truncWord32 $ v
357bitcastVec (ATInt (ITVec IT32 n)) [x@(B32V v)]
358 | V.length v == n = Just x
359bitcastVec (ATInt (ITVec IT64 n)) [B32V v]
360 | V.length v == n*2 = Just . B64V . mapHalf concatWord32 $ v
362bitcastVec (ATInt (ITVec IT8 n)) [B64V v]
363 | V.length v * 8 == n = Just . B8V . mapDouble truncWord16 . mapDouble truncWord32 . mapDouble truncWord64 $ v
364bitcastVec (ATInt (ITVec IT16 n)) [B64V v]
365 | V.length v * 4 == n = Just . B16V . mapDouble truncWord32 . mapDouble truncWord64 $ v
366bitcastVec (ATInt (ITVec IT32 n)) [B64V v]
367 | V.length v == n*2 = Just . B32V . mapDouble truncWord64 $ v
368bitcastVec (ATInt (ITVec IT64 n)) [x@(B64V v)]
369 | V.length v == n = Just x
371bitcastVec _ _ = Nothing
373mkVecCon :: NativeTy -> Int -> [Const] -> Maybe Const
374mkVecCon ity count args
375 | length ints == count = Just (mkVec ity count ints)
376 | otherwise = Nothing
379 mkVec :: NativeTy -> Int -> [Integer] -> Const
380 mkVec IT8 len values = B8V $ V.generate len (fromInteger . (values !!))
381 mkVec IT16 len values = B16V $ V.generate len (fromInteger . (values !!))
382 mkVec IT32 len values = B32V $ V.generate len (fromInteger . (values !!))
383 mkVec IT64 len values = B64V $ V.generate len (fromInteger . (values !!))
385mkVecIndex count [vec, B32 i] = Just (idxVec vec)
387 idxVec :: Const -> Const
388 idxVec (B8V v) = B8 $ V.unsafeIndex v (fromIntegral i)
389 idxVec (B16V v) = B16 $ V.unsafeIndex v (fromIntegral i)
390 idxVec (B32V v) = B32 $ V.unsafeIndex v (fromIntegral i)
391 idxVec (B64V v) = B64 $ V.unsafeIndex v (fromIntegral i)
392mkVecIndex _ _ = Nothing
394mkVecUpdate ity count [vec, B32 i, newElem] = updateVec vec newElem
396 updateVec :: Const -> Const -> Maybe Const
397 updateVec (B8V v) (B8 e) = Just . B8V $ V.unsafeUpdate v (V.singleton (fromIntegral i, e))
398 updateVec (B16V v) (B16 e) = Just . B16V $ V.unsafeUpdate v (V.singleton (fromIntegral i, e))
399 updateVec (B32V v) (B32 e) = Just . B32V $ V.unsafeUpdate v (V.singleton (fromIntegral i, e))
400 updateVec (B64V v) (B64 e) = Just . B64V $ V.unsafeUpdate v (V.singleton (fromIntegral i, e))
401 updateVec _ _ = Nothing
402mkVecUpdate _ _ _ = Nothing
404aTyName :: ArithTy -> String
405aTyName (ATInt t) = intTyName t
406aTyName ATFloat = "Float"
408iCmp :: IntTy -> String -> Bool -> ([Const] -> Maybe Const) -> (IntTy -> PrimFn) -> Totality -> Prim
409iCmp ity op self impl irop totality
410 = Prim (sUN $ "prim__" ++ op ++ intTyName ity)
411 (ty (replicate 2 . AType . ATInt $ ity) (AType (ATInt (if self then ity else ITNative))))
412 2 impl (2, irop ity) totality
414iBinOp, iUnOp :: IntTy -> String -> ([Const] -> Maybe Const) -> (IntTy -> PrimFn) -> Totality -> Prim
415iBinOp ity op impl irop totality
416 = Prim (sUN $ "prim__" ++ op ++ intTyName ity)
417 (ty (replicate 2 . AType . ATInt $ ity) (AType . ATInt $ ity))
418 2 impl (2, irop ity) totality
419iUnOp ity op impl irop totality
420 = Prim (sUN $ "prim__" ++ op ++ intTyName ity)
421 (ty [AType . ATInt $ ity] (AType . ATInt $ ity))
422 1 impl (1, irop ity) totality
424iCoerce :: IntTy -> IntTy -> String -> (IntTy -> IntTy -> [Const] -> Maybe Const) -> (IntTy -> IntTy -> PrimFn) -> Prim
425iCoerce from to op impl irop =
426 Prim (sUN $ "prim__" ++ op ++ intTyName from ++ "_" ++ intTyName to)
427 (ty [AType . ATInt $ from] (AType . ATInt $ to)) 1 (impl from to) (1, irop from to) total
429fBin :: (Double -> Double -> Double) -> [Const] -> Maybe Const
430fBin op [Fl x, Fl y] = Just $ Fl (op x y)
433bfBin :: (Double -> Double -> Bool) -> [Const] -> Maybe Const
434bfBin op [Fl x, Fl y] = let i = (if op x y then 1 else 0) in
438bcBin :: (Char -> Char -> Bool) -> [Const] -> Maybe Const
439bcBin op [Ch x, Ch y] = let i = (if op x y then 1 else 0) in
443bsBin :: (String -> String -> Bool) -> [Const] -> Maybe Const
444bsBin op [Str x, Str y]
445 = let i = (if op x y then 1 else 0) in
449sBin :: (String -> String -> String) -> [Const] -> Maybe Const
450sBin op [Str x, Str y] = Just $ Str (op x y)
453bsrem :: IntTy -> [Const] -> Maybe Const
454bsrem ITBig [BI x, BI y] = Just . BI $ x `rem` y
455bsrem (ITFixed IT8) [B8 x, B8 y]
456 = Just $ B8 (fromIntegral (fromIntegral x `rem` fromIntegral y :: Int8))
457bsrem (ITFixed IT16) [B16 x, B16 y]
458 = Just $ B16 (fromIntegral (fromIntegral x `rem` fromIntegral y :: Int16))
459bsrem (ITFixed IT32) [B32 x, B32 y]
460 = Just $ B32 (fromIntegral (fromIntegral x `rem` fromIntegral y :: Int32))
461bsrem (ITFixed IT64) [B64 x, B64 y]
462 = Just $ B64 (fromIntegral (fromIntegral x `rem` fromIntegral y :: Int64))
463bsrem ITNative [I x, I y] = Just $ I (x `rem` y)
464bsrem ITChar [Ch x, Ch y] = Just $ Ch (chr $ (ord x) `rem` (ord y))
465bsrem (ITVec IT8 _) [B8V x, B8V y]
467 V.zipWith (\n d -> (fromIntegral (fromIntegral n `rem` fromIntegral d :: Int8))) x y
468bsrem (ITVec IT16 _) [B16V x, B16V y]
470 V.zipWith (\n d -> (fromIntegral (fromIntegral n `rem` fromIntegral d :: Int16))) x y
471bsrem (ITVec IT32 _) [B32V x, B32V y]
473 V.zipWith (\n d -> (fromIntegral (fromIntegral n `rem` fromIntegral d :: Int64))) x y
474bsrem (ITVec IT64 _) [B64V x, B64V y]
476 V.zipWith (\n d -> (fromIntegral (fromIntegral n `rem` fromIntegral d :: Int64))) x y
479bsdiv :: IntTy -> [Const] -> Maybe Const
480bsdiv ITBig [BI x, BI y] = Just . BI $ x `div` y
481bsdiv (ITFixed IT8) [B8 x, B8 y]
482 = Just $ B8 (fromIntegral (fromIntegral x `div` fromIntegral y :: Int8))
483bsdiv (ITFixed IT16) [B16 x, B16 y]
484 = Just $ B16 (fromIntegral (fromIntegral x `div` fromIntegral y :: Int16))
485bsdiv (ITFixed IT32) [B32 x, B32 y]
486 = Just $ B32 (fromIntegral (fromIntegral x `div` fromIntegral y :: Int32))
487bsdiv (ITFixed IT64) [B64 x, B64 y]
488 = Just $ B64 (fromIntegral (fromIntegral x `div` fromIntegral y :: Int64))
489bsdiv ITNative [I x, I y] = Just $ I (x `div` y)
490bsdiv ITChar [Ch x, Ch y] = Just $ Ch (chr $ (ord x) `div` (ord y))
491bsdiv (ITVec IT8 _) [B8V x, B8V y]
493 V.zipWith (\n d -> (fromIntegral (fromIntegral n `div` fromIntegral d :: Int8))) x y
494bsdiv (ITVec IT16 _) [B16V x, B16V y]
496 V.zipWith (\n d -> (fromIntegral (fromIntegral n `div` fromIntegral d :: Int16))) x y
497bsdiv (ITVec IT32 _) [B32V x, B32V y]
499 V.zipWith (\n d -> (fromIntegral (fromIntegral n `div` fromIntegral d :: Int64))) x y
500bsdiv (ITVec IT64 _) [B64V x, B64V y]
502 V.zipWith (\n d -> (fromIntegral (fromIntegral n `div` fromIntegral d :: Int64))) x y
505bashr :: IntTy -> [Const] -> Maybe Const
506bashr ITBig [BI x, BI y] = Just $ BI (x `shiftR` fromIntegral y)
507bashr (ITFixed IT8) [B8 x, B8 y]
508 = Just $ B8 (fromIntegral (fromIntegral x `shiftR` fromIntegral y :: Int8))
509bashr (ITFixed IT16) [B16 x, B16 y]
510 = Just $ B16 (fromIntegral (fromIntegral x `shiftR` fromIntegral y :: Int16))
511bashr (ITFixed IT32) [B32 x, B32 y]
512 = Just $ B32 (fromIntegral (fromIntegral x `shiftR` fromIntegral y :: Int32))
513bashr (ITFixed IT64) [B64 x, B64 y]
514 = Just $ B64 (fromIntegral (fromIntegral x `shiftR` fromIntegral y :: Int64))
515bashr ITNative [I x, I y] = Just $ I (x `shiftR` y)
516bashr ITChar [Ch x, Ch y] = Just $ Ch (chr $ (ord x) `shiftR` (ord y))
517bashr (ITVec IT8 _) [B8V x, B8V y]
519 V.zipWith (\n d -> (fromIntegral (fromIntegral n `shiftR` fromIntegral d :: Int8))) x y
520bashr (ITVec IT16 _) [B16V x, B16V y]
522 V.zipWith (\n d -> (fromIntegral (fromIntegral n `shiftR` fromIntegral d :: Int16))) x y
523bashr (ITVec IT32 _) [B32V x, B32V y]
525 V.zipWith (\n d -> (fromIntegral (fromIntegral n `shiftR` fromIntegral d :: Int64))) x y
526bashr (ITVec IT64 _) [B64V x, B64V y]
528 V.zipWith (\n d -> (fromIntegral (fromIntegral n `shiftR` fromIntegral d :: Int64))) x y
531bUn :: IntTy -> (forall a. Bits a => a -> a) -> [Const] -> Maybe Const
532bUn (ITFixed IT8) op [B8 x] = Just $ B8 (op x)
533bUn (ITFixed IT16) op [B16 x] = Just $ B16 (op x)
534bUn (ITFixed IT32) op [B32 x] = Just $ B32 (op x)
535bUn (ITFixed IT64) op [B64 x] = Just $ B64 (op x)
536bUn ITBig op [BI x] = Just $ BI (op x)
537bUn ITNative op [I x] = Just $ I (op x)
538bUn ITChar op [Ch x] = Just $ Ch (chr $ op (ord x))
539bUn (ITVec IT8 _) op [B8V x] = Just . B8V $ V.map op x
540bUn (ITVec IT16 _) op [B16V x] = Just . B16V $ V.map op x
541bUn (ITVec IT32 _) op [B32V x] = Just . B32V $ V.map op x
542bUn (ITVec IT64 _) op [B64V x] = Just . B64V $ V.map op x
545bitBin :: IntTy -> (forall a. (Bits a, Integral a) => a -> a -> a) -> [Const] -> Maybe Const
546bitBin (ITFixed IT8) op [B8 x, B8 y] = Just $ B8 (op x y)
547bitBin (ITFixed IT16) op [B16 x, B16 y] = Just $ B16 (op x y)
548bitBin (ITFixed IT32) op [B32 x, B32 y] = Just $ B32 (op x y)
549bitBin (ITFixed IT64) op [B64 x, B64 y] = Just $ B64 (op x y)
550bitBin ITBig op [BI x, BI y] = Just $ BI (op x y)
551bitBin ITNative op [I x, I y] = Just $ I (op x y)
552bitBin ITChar op [Ch x, Ch y] = Just $ Ch (chr $ op (ord x) (ord y))
553bitBin (ITVec IT8 _) op [B8V x, B8V y] = Just . B8V $ V.zipWith op x y
554bitBin (ITVec IT16 _) op [B16V x, B16V y] = Just . B16V $ V.zipWith op x y
555bitBin (ITVec IT32 _) op [B32V x, B32V y] = Just . B32V $ V.zipWith op x y
556bitBin (ITVec IT64 _) op [B64V x, B64V y] = Just . B64V $ V.zipWith op x y
557bitBin _ _ _ = Nothing
559bCmp :: IntTy -> (forall a. (Integral a, Ord a) => a -> a -> Bool) -> [Const] -> Maybe Const
560bCmp (ITFixed IT8) op [B8 x, B8 y] = Just $ I (if (op x y) then 1 else 0)
561bCmp (ITFixed IT16) op [B16 x, B16 y] = Just $ I (if (op x y) then 1 else 0)
562bCmp (ITFixed IT32) op [B32 x, B32 y] = Just $ I (if (op x y) then 1 else 0)
563bCmp (ITFixed IT64) op [B64 x, B64 y] = Just $ I (if (op x y) then 1 else 0)
564bCmp ITBig op [BI x, BI y] = Just $ I (if (op x y) then 1 else 0)
565bCmp ITNative op [I x, I y] = Just $ I (if (op x y) then 1 else 0)
566bCmp ITChar op [Ch x, Ch y] = Just $ I (if (op (ord x) (ord y)) then 1 else 0)
567bCmp (ITVec IT8 _) op [B8V x, B8V y]
568 = Just . B8V . V.map (\b -> if b then -1 else 0) $ V.zipWith op x y
569bCmp (ITVec IT16 _) op [B16V x, B16V y]
570 = Just . B16V . V.map (\b -> if b then -1 else 0) $ V.zipWith op x y
571bCmp (ITVec IT32 _) op [B32V x, B32V y]
572 = Just . B32V . V.map (\b -> if b then -1 else 0) $ V.zipWith op x y
573bCmp (ITVec IT64 _) op [B64V x, B64V y]
574 = Just . B64V . V.map (\b -> if b then -1 else 0) $ V.zipWith op x y
578cmpOp :: (Ord a, Integral a) => IntTy -> (forall b. Ord b => b -> b -> Bool) -> a -> a -> Bool
579cmpOp (ITFixed _) f = f
580cmpOp (ITNative) f = f `on` (fromIntegral :: Integral a => a -> Word)
581cmpOp (ITChar) f = f `on` ((fromIntegral :: Integral a => a -> Word))
582cmpOp _ f = let xor = (/=) in (\ x y -> (f x y) `xor` (x < 0) `xor` (y < 0))
584sCmpOp :: (Ord a, Integral a) => IntTy -> (forall b. Ord b => b -> b -> Bool) -> a -> a -> Bool
585sCmpOp (ITFixed IT8) f = f `on` (fromIntegral :: Integral a => a -> Int8)
586sCmpOp (ITFixed IT16) f = f `on` (fromIntegral :: Integral a => a -> Int16)
587sCmpOp (ITFixed IT32) f = f `on` (fromIntegral :: Integral a => a -> Int32)
588sCmpOp (ITFixed IT64) f = f `on` (fromIntegral :: Integral a => a -> Int64)
591toInt :: Integral a => IntTy -> a -> Const
592toInt (ITFixed IT8) x = B8 (fromIntegral x)
593toInt (ITFixed IT16) x = B16 (fromIntegral x)
594toInt (ITFixed IT32) x = B32 (fromIntegral x)
595toInt (ITFixed IT64) x = B64 (fromIntegral x)
596toInt ITBig x = BI (fromIntegral x)
597toInt ITNative x = I (fromIntegral x)
598toInt ITChar x = Ch (chr $ fromIntegral x)
600intToInt :: IntTy -> IntTy -> [Const] -> Maybe Const
601intToInt (ITFixed IT8) out [B8 x] = Just $ toInt out x
602intToInt (ITFixed IT16) out [B16 x] = Just $ toInt out x
603intToInt (ITFixed IT32) out [B32 x] = Just $ toInt out x
604intToInt (ITFixed IT64) out [B64 x] = Just $ toInt out x
605intToInt ITBig out [BI x] = Just $ toInt out x
606intToInt ITNative out [I x] = Just $ toInt out x
607intToInt ITChar out [Ch x] = Just $ toInt out (ord x)
608intToInt _ _ _ = Nothing
610zext :: IntTy -> IntTy -> [Const] -> Maybe Const
611zext from ITBig val = intToInt from ITBig val
612zext ITBig _ _ = Nothing
613zext f@(ITFixed from) t@(ITFixed to) val
614 | nativeTyWidth from < nativeTyWidth to = intToInt f t val
615zext ITNative to [I x] = Just $ toInt to (fromIntegral x :: Word)
616zext from ITNative val = intToInt from ITNative val
619sext :: IntTy -> IntTy -> [Const] -> Maybe Const
620sext (ITFixed IT8) out [B8 x] = Just $ toInt out (fromIntegral x :: Int8)
621sext (ITFixed IT16) out [B16 x] = Just $ toInt out (fromIntegral x :: Int16)
622sext (ITFixed IT32) out [B32 x] = Just $ toInt out (fromIntegral x :: Int32)
623sext (ITFixed IT64) out [B64 x] = Just $ toInt out (fromIntegral x :: Int64)
624sext ITBig _ _ = Nothing
625sext from to val = intToInt from to val
627trunc :: IntTy -> IntTy -> [Const] -> Maybe Const
628trunc ITBig to val = intToInt ITBig to val
629trunc _ ITBig _ = Nothing
630trunc f@(ITFixed from) t@(ITFixed to) val | nativeTyWidth from > nativeTyWidth to = intToInt f t val
631trunc ITNative to [I x] = Just $ toInt to x
632trunc from ITNative val = intToInt from ITNative val
635intToStr :: [Const] -> Maybe Const
636intToStr val | [i] <- getInt val = Just $ Str (show i)
639getInt :: [Const] -> [Integer]
640getInt (B8 x : xs) = toInteger x : getInt xs
641getInt (B16 x : xs) = toInteger x : getInt xs
642getInt (B32 x : xs) = toInteger x : getInt xs
643getInt (B64 x : xs) = toInteger x : getInt xs
644getInt (I x : xs) = toInteger x : getInt xs
645getInt (BI x : xs) = x : getInt xs
648strToInt :: IntTy -> [Const] -> Maybe Const
649strToInt ity [Str x] = case reads x of
650 [(n,"")] -> Just $ toInt ity (n :: Integer)
652strToInt _ _ = Nothing
654intToFloat :: [Const] -> Maybe Const
655intToFloat val | [i] <- getInt val = Just $ Fl (fromIntegral i)
656intToFloat _ = Nothing
658floatToInt :: IntTy -> [Const] -> Maybe Const
659floatToInt ity [Fl x] = Just $ toInt ity (truncate x :: Integer)
660floatToInt _ _ = Nothing
662c_intToChar, c_charToInt :: [Const] -> Maybe Const
663c_intToChar [(I x)] = Just . Ch . toEnum $ x
664c_intToChar _ = Nothing
665c_charToInt [(Ch x)] = Just . I . fromEnum $ x
666c_charToInt _ = Nothing
668c_negFloat :: [Const] -> Maybe Const
669c_negFloat [Fl x] = Just $ Fl (negate x)
670c_negFloat _ = Nothing
672c_floatToStr :: [Const] -> Maybe Const
673c_floatToStr [Fl x] = Just $ Str (show x)
674c_floatToStr _ = Nothing
675c_strToFloat [Str x] = case reads x of
676 [(n,"")] -> Just $ Fl n
678c_strToFloat _ = Nothing
680p_fPrim :: (Double -> Double) -> [Const] -> Maybe Const
681p_fPrim f [Fl x] = Just $ Fl (f x)
684p_floatExp, p_floatLog, p_floatSin, p_floatCos, p_floatTan, p_floatASin, p_floatACos, p_floatATan, p_floatSqrt, p_floatFloor, p_floatCeil :: [Const] -> Maybe Const
685p_floatExp = p_fPrim exp
686p_floatLog = p_fPrim log
687p_floatSin = p_fPrim sin
688p_floatCos = p_fPrim cos
689p_floatTan = p_fPrim tan
690p_floatASin = p_fPrim asin
691p_floatACos = p_fPrim acos
692p_floatATan = p_fPrim atan
693p_floatSqrt = p_fPrim sqrt
694p_floatFloor = p_fPrim (fromInteger . floor)
695p_floatCeil = p_fPrim (fromInteger . ceiling)
697p_strLen, p_strHead, p_strTail, p_strIndex, p_strCons, p_strRev :: [Const] -> Maybe Const
698p_strLen [Str xs] = Just $ I (length xs)
700p_strHead [Str (x:xs)] = Just $ Ch x
702p_strTail [Str (x:xs)] = Just $ Str xs
704p_strIndex [Str xs, I i]
705 | i < length xs = Just $ Ch (xs!!i)
706p_strIndex _ = Nothing
707p_strCons [Ch x, Str xs] = Just $ Str (x:xs)
709p_strRev [Str xs] = Just $ Str (reverse xs)
712p_allocate, p_appendBuffer :: [Const] -> Maybe Const
713p_allocate [B64 _] = Just $ B8V V.empty
714p_allocate n = Nothing
715p_appendBuffer [B8V vect1, B64 size1, B64 count, B64 size2, B64 off, B8V vect2] =
716 Just $ B8V (foldl (V.++)
717 (V.slice 0 (fromIntegral size1) vect1)
718 (replicate (fromIntegral count) (V.slice (fromIntegral off) (fromIntegral size2) vect2)))
719p_appendBuffer n = Nothing
720p_append :: Endianness -> [Const] -> Maybe Const
721p_append en [B8V vect, B64 size, B64 count, val] =
722 let bytes = case val of
724 B16 x -> [fromIntegral x, fromIntegral (shiftR x 8)]
725 B32 x -> map (fromIntegral . shiftR x) [0,8..24]
726 B64 x -> map (fromIntegral . shiftR x) [0,8..56]
727 in Just $ B8V (foldl V.snoc
728 (V.slice 0 (fromIntegral size) vect)
729 (concat (replicate (fromIntegral count)
733p_append _ _ = Nothing
735p_peek :: IntTy -> Endianness -> [Const] -> Maybe Const
736p_peek (ITFixed IT8) _ [B8V vect, B64 offset] = Just $ B8 (vect V.! fromIntegral offset)
737p_peek (ITFixed IT16) en [B8V vect, B64 offset] =
739 in Just $ B16 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
744p_peek (ITFixed IT32) en [B8V vect, B64 offset] =
746 in Just $ B32 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
751p_peek (ITFixed IT64) en [B8V vect, B64 offset] =
753 in Just $ B64 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
758p_peek _ _ _ = Nothing
760p_cantreduce :: a -> Maybe b
761p_cantreduce _ = Nothing
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list