{-# LANGUAGE RankNTypes, ScopedTypeVariables #-} module Idris.Primitives(elabPrims) where import Idris.ElabDecls import Idris.ElabTerm import Idris.AbsSyntax import IRTS.Lang import Core.TT import Core.Evaluate import Data.Bits import Data.Word import Data.Int data Prim = Prim { p_name :: Name, p_type :: Type, p_arity :: Int, p_def :: [Value] -> Maybe Value, p_lexp :: (Int, PrimFn), p_total :: Totality } ty [] x = Constant x ty (t:ts) x = Bind (MN 0 "T") (Pi (Constant t)) (ty ts x) believeTy = Bind (UN "a") (Pi (TType (UVar (-2)))) (Bind (UN "b") (Pi (TType (UVar (-2)))) (Bind (UN "x") (Pi (V 1)) (V 1))) total = Total [] partial = Partial NotCovering primitives = -- operators [Prim (UN "prim__addInt") (ty [IType, IType] IType) 2 (iBin (+)) (2, LPlus) total, Prim (UN "prim__subInt") (ty [IType, IType] IType) 2 (iBin (-)) (2, LMinus) total, Prim (UN "prim__mulInt") (ty [IType, IType] IType) 2 (iBin (*)) (2, LTimes) total, Prim (UN "prim__divInt") (ty [IType, IType] IType) 2 (iBin div) (2, LDiv) partial, Prim (UN "prim__modInt") (ty [IType, IType] IType) 2 (iBin mod) (2, LMod) partial, Prim (UN "prim__andInt") (ty [IType, IType] IType) 2 (iBin (.&.)) (2, LAnd) partial, Prim (UN "prim__orInt") (ty [IType, IType] IType) 2 (iBin (.|.)) (2, LOr) partial, Prim (UN "prim__xorInt") (ty [IType, IType] IType) 2 (iBin xor) (2, LXOr) partial, Prim (UN "prim__shLInt") (ty [IType, IType] IType) 2 (iBin shiftL) (2, LSHL) partial, Prim (UN "prim__shRInt") (ty [IType, IType] IType) 2 (iBin shiftR) (2, LSHR) partial, Prim (UN "prim__complInt") (ty [IType] IType) 1 (iUn complement) (1, LCompl) partial, Prim (UN "prim__eqInt") (ty [IType, IType] IType) 2 (biBin (==)) (2, LEq) total, Prim (UN "prim__ltInt") (ty [IType, IType] IType) 2 (biBin (<)) (2, LLt) total, Prim (UN "prim__lteInt") (ty [IType, IType] IType) 2 (biBin (<=)) (2, LLe) total, Prim (UN "prim__gtInt") (ty [IType, IType] IType) 2 (biBin (>)) (2, LGt) total, Prim (UN "prim__gteInt") (ty [IType, IType] IType) 2 (biBin (>=)) (2, LGe) total, Prim (UN "prim__eqChar") (ty [ChType, ChType] IType) 2 (bcBin (==)) (2, LEq) total, Prim (UN "prim__ltChar") (ty [ChType, ChType] IType) 2 (bcBin (<)) (2, LLt) total, Prim (UN "prim__lteChar") (ty [ChType, ChType] IType) 2 (bcBin (<=)) (2, LLe) total, Prim (UN "prim__gtChar") (ty [ChType, ChType] IType) 2 (bcBin (>)) (2, LGt) total, Prim (UN "prim__gteChar") (ty [ChType, ChType] IType) 2 (bcBin (>=)) (2, LGe) total, Prim (UN "prim__ltB8") (ty [B8Type, B8Type] IType) 2 (b8Cmp (<)) (2, LB8Lt) total, Prim (UN "prim__lteB8") (ty [B8Type, B8Type] IType) 2 (b8Cmp (<=)) (2, LB8Lte) total, Prim (UN "prim__eqB8") (ty [B8Type, B8Type] IType) 2 (b8Cmp (==)) (2, LB8Eq) total, Prim (UN "prim__gteB8") (ty [B8Type, B8Type] IType) 2 (b8Cmp (>)) (2, LB8Gte) total, Prim (UN "prim__gtB8") (ty [B8Type, B8Type] IType) 2 (b8Cmp (>=)) (2, LB8Gt) total, Prim (UN "prim__addB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (+)) (2, LB8Plus) total, Prim (UN "prim__subB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (-)) (2, LB8Minus) total, Prim (UN "prim__mulB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (*)) (2, LB8Times) total, Prim (UN "prim__udivB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin div) (2, LB8UDiv) partial, Prim (UN "prim__sdivB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin s8div) (2, LB8SDiv) partial, Prim (UN "prim__uremB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin rem) (2, LB8URem) partial, Prim (UN "prim__sremB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin s8rem) (2, LB8SRem) partial, Prim (UN "prim__shlB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (\x y -> shiftL x (fromIntegral y))) (2, LB8Shl) total, Prim (UN "prim__lshrB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (\x y -> shiftR x (fromIntegral y))) (2, LB8AShr) total, Prim (UN "prim__ashrB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (\x y -> fromIntegral $ shiftR (fromIntegral x :: Int8) (fromIntegral y))) (2, LB8LShr) total, Prim (UN "prim__andB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (.&.)) (2, LB8And) total, Prim (UN "prim__orB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin (.|.)) (2, LB8Or) total, Prim (UN "prim__xorB8") (ty [B8Type, B8Type] B8Type) 2 (b8Bin xor) (2, LB8Xor) total, Prim (UN "prim__complB8") (ty [B8Type] B8Type) 1 (b8Un complement) (1, LB8Compl) total, Prim (UN "prim__zextB8_16") (ty [B8Type] B16Type) 1 zext8_16 (1, LB8Z16) total, Prim (UN "prim__zextB8_32") (ty [B8Type] B32Type) 1 zext8_32 (1, LB8Z32) total, Prim (UN "prim__zextB8_64") (ty [B8Type] B64Type) 1 zext8_64 (1, LB8Z64) total, Prim (UN "prim__sextB8_16") (ty [B8Type] B16Type) 1 sext8_16 (1, LB8Z16) total, Prim (UN "prim__sextB8_32") (ty [B8Type] B32Type) 1 sext8_32 (1, LB8Z32) total, Prim (UN "prim__sextB8_64") (ty [B8Type] B64Type) 1 sext8_64 (1, LB8Z64) total, Prim (UN "prim__ltB16") (ty [B16Type, B16Type] IType) 2 (b16Cmp (<)) (2, LB16Lt) total, Prim (UN "prim__lteB16") (ty [B16Type, B16Type] IType) 2 (b16Cmp (<=)) (2, LB16Lte) total, Prim (UN "prim__eqB16") (ty [B16Type, B16Type] IType) 2 (b16Cmp (==)) (2, LB16Eq) total, Prim (UN "prim__gteB16") (ty [B16Type, B16Type] IType) 2 (b16Cmp (>)) (2, LB16Gte) total, Prim (UN "prim__gtB16") (ty [B16Type, B16Type] IType) 2 (b16Cmp (>=)) (2, LB16Gt) total, Prim (UN "prim__addB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (+)) (2, LB16Plus) total, Prim (UN "prim__subB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (-)) (2, LB16Minus) total, Prim (UN "prim__mulB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (*)) (2, LB16Times) total, Prim (UN "prim__udivB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin div) (2, LB16UDiv) partial, Prim (UN "prim__sdivB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin s16div) (2, LB16SDiv) partial, Prim (UN "prim__uremB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin rem) (2, LB16URem) partial, Prim (UN "prim__sremB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin s16rem) (2, LB16SRem) partial, Prim (UN "prim__shlB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (\x y -> shiftL x (fromIntegral y))) (2, LB16Shl) total, Prim (UN "prim__lshrB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (\x y -> shiftR x (fromIntegral y))) (2, LB16AShr) total, Prim (UN "prim__ashrB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (\x y -> fromIntegral $ shiftR (fromIntegral x :: Int16) (fromIntegral y))) (2, LB16LShr) total, Prim (UN "prim__andB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (.&.)) (2, LB16And) total, Prim (UN "prim__orB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin (.|.)) (2, LB16Or) total, Prim (UN "prim__xorB16") (ty [B16Type, B16Type] B16Type) 2 (b16Bin xor) (2, LB16Xor) total, Prim (UN "prim__complB16") (ty [B16Type] B16Type) 1 (b16Un complement) (1, LB16Compl) total, Prim (UN "prim__zextB16_32") (ty [B16Type] B32Type) 1 zext16_32 (1, LB16Z32) total, Prim (UN "prim__zextB16_64") (ty [B16Type] B64Type) 1 zext16_64 (1, LB16Z64) total, Prim (UN "prim__sextB16_32") (ty [B16Type] B32Type) 1 sext16_32 (1, LB16Z32) total, Prim (UN "prim__sextB16_64") (ty [B16Type] B64Type) 1 sext16_64 (1, LB16Z64) total, Prim (UN "prim__truncB16_8") (ty [B16Type] B8Type) 1 trunc16_8 (1, LB16T8) total, Prim (UN "prim__ltB32") (ty [B32Type, B32Type] IType) 2 (b32Cmp (<)) (2, LB32Lt) total, Prim (UN "prim__lteB32") (ty [B32Type, B32Type] IType) 2 (b32Cmp (<=)) (2, LB32Lte) total, Prim (UN "prim__eqB32") (ty [B32Type, B32Type] IType) 2 (b32Cmp (==)) (2, LB32Eq) total, Prim (UN "prim__gteB32") (ty [B32Type, B32Type] IType) 2 (b32Cmp (>)) (2, LB32Gte) total, Prim (UN "prim__gtB32") (ty [B32Type, B32Type] IType) 2 (b32Cmp (>=)) (2, LB32Gt) total, Prim (UN "prim__addB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (+)) (2, LB32Plus) total, Prim (UN "prim__subB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (-)) (2, LB32Minus) total, Prim (UN "prim__mulB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (*)) (2, LB32Times) total, Prim (UN "prim__udivB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin div) (2, LB32UDiv) partial, Prim (UN "prim__sdivB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin s32div) (2, LB32SDiv) partial, Prim (UN "prim__uremB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin rem) (2, LB32URem) partial, Prim (UN "prim__sremB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin s32rem) (2, LB32SRem) partial, Prim (UN "prim__shlB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (\x y -> shiftL x (fromIntegral y))) (2, LB32Shl) total, Prim (UN "prim__lshrB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (\x y -> shiftR x (fromIntegral y))) (2, LB32AShr) total, Prim (UN "prim__ashrB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (\x y -> fromIntegral $ shiftR (fromIntegral x :: Int32) (fromIntegral y))) (2, LB32LShr) total, Prim (UN "prim__andB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (.&.)) (2, LB32And) total, Prim (UN "prim__orB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin (.|.)) (2, LB32Or) total, Prim (UN "prim__xorB32") (ty [B32Type, B32Type] B32Type) 2 (b32Bin xor) (2, LB32Xor) total, Prim (UN "prim__complB32") (ty [B32Type] B32Type) 1 (b32Un complement) (1, LB32Compl) total, Prim (UN "prim__zextB32_64") (ty [B32Type] B64Type) 1 zext32_64 (1, LB32Z64) total, Prim (UN "prim__sextB32_64") (ty [B32Type] B64Type) 1 sext32_64 (1, LB32Z64) total, Prim (UN "prim__truncB32_8") (ty [B32Type] B8Type) 1 trunc32_8 (1, LB32T8) total, Prim (UN "prim__truncB32_16") (ty [B32Type] B16Type) 1 trunc32_16 (1, LB32T16) total, Prim (UN "prim__ltB64") (ty [B64Type, B64Type] IType) 2 (b64Cmp (<)) (2, LB64Lt) total, Prim (UN "prim__lteB64") (ty [B64Type, B64Type] IType) 2 (b64Cmp (<=)) (2, LB64Lte) total, Prim (UN "prim__eqB64") (ty [B64Type, B64Type] IType) 2 (b64Cmp (==)) (2, LB64Eq) total, Prim (UN "prim__gteB64") (ty [B64Type, B64Type] IType) 2 (b64Cmp (>)) (2, LB64Gte) total, Prim (UN "prim__gtB64") (ty [B64Type, B64Type] IType) 2 (b64Cmp (>=)) (2, LB64Gt) total, Prim (UN "prim__addB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (+)) (2, LB64Plus) total, Prim (UN "prim__subB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (-)) (2, LB64Minus) total, Prim (UN "prim__mulB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (*)) (2, LB64Times) total, Prim (UN "prim__udivB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin div) (2, LB64UDiv) partial, Prim (UN "prim__sdivB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin s64div) (2, LB64SDiv) partial, Prim (UN "prim__uremB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin rem) (2, LB64URem) partial, Prim (UN "prim__sremB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin s64rem) (2, LB64SRem) partial, Prim (UN "prim__shlB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (\x y -> shiftL x (fromIntegral y))) (2, LB64Shl) total, Prim (UN "prim__lshrB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (\x y -> shiftR x (fromIntegral y))) (2, LB64AShr) total, Prim (UN "prim__ashrB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (\x y -> fromIntegral $ shiftR (fromIntegral x :: Int64) (fromIntegral y))) (2, LB64LShr) total, Prim (UN "prim__andB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (.&.)) (2, LB64And) total, Prim (UN "prim__orB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin (.|.)) (2, LB64Or) total, Prim (UN "prim__xorB64") (ty [B64Type, B64Type] B64Type) 2 (b64Bin xor) (2, LB64Xor) total, Prim (UN "prim__complB64") (ty [B64Type] B64Type) 1 (b64Un complement) (1, LB64Compl) total, Prim (UN "prim__truncB64_8") (ty [B64Type] B8Type) 1 trunc64_8 (1, LB64T8) total, Prim (UN "prim__truncB64_16") (ty [B64Type] B16Type) 1 trunc64_16 (1, LB64T16) total, Prim (UN "prim__truncB64_32") (ty [B64Type] B32Type) 1 trunc64_32 (1, LB64T32) total, Prim (UN "prim__intToB8") (ty [IType] B8Type) 1 intToBits8 (1, LIntB8) total, Prim (UN "prim__intToB16") (ty [IType] B16Type) 1 intToBits16 (1, LIntB16) total, Prim (UN "prim__intToB32") (ty [IType] B32Type) 1 intToBits32 (1, LIntB32) total, Prim (UN "prim__intToB64") (ty [IType] B64Type) 1 intToBits64 (1, LIntB64) total, Prim (UN "prim__B32ToInt") (ty [B32Type] IType) 1 bits32ToInt (1, LB32Int) total, Prim (UN "prim__addBigInt") (ty [BIType, BIType] BIType) 2 (bBin (+)) (2, LBPlus) total, Prim (UN "prim__subBigInt") (ty [BIType, BIType] BIType) 2 (bBin (-)) (2, LBMinus) total, Prim (UN "prim__mulBigInt") (ty [BIType, BIType] BIType) 2 (bBin (*)) (2, LBTimes) total, Prim (UN "prim__divBigInt") (ty [BIType, BIType] BIType) 2 (bBin div) (2, LBDiv) partial, Prim (UN "prim__modBigInt") (ty [BIType, BIType] BIType) 2 (bBin mod) (2, LBMod) partial, Prim (UN "prim__eqBigInt") (ty [BIType, BIType] IType) 2 (bbBin (==)) (2, LBEq) total, Prim (UN "prim__ltBigInt") (ty [BIType, BIType] IType) 2 (bbBin (<)) (2, LBLt) total, Prim (UN "prim__lteBigInt") (ty [BIType, BIType] IType) 2 (bbBin (<=)) (2, LBLe) total, Prim (UN "prim__gtBigInt") (ty [BIType, BIType] IType) 2 (bbBin (>)) (2, LBGt) total, Prim (UN "prim__gtBigInt") (ty [BIType, BIType] IType) 2 (bbBin (>=)) (2, LBGe) total, Prim (UN "prim__addFloat") (ty [FlType, FlType] FlType) 2 (fBin (+)) (2, LFPlus) total, Prim (UN "prim__subFloat") (ty [FlType, FlType] FlType) 2 (fBin (-)) (2, LFMinus) total, Prim (UN "prim__mulFloat") (ty [FlType, FlType] FlType) 2 (fBin (*)) (2, LFTimes) total, Prim (UN "prim__divFloat") (ty [FlType, FlType] FlType) 2 (fBin (/)) (2, LFDiv) total, Prim (UN "prim__eqFloat") (ty [FlType, FlType] IType) 2 (bfBin (==)) (2, LFEq) total, Prim (UN "prim__ltFloat") (ty [FlType, FlType] IType) 2 (bfBin (<)) (2, LFLt) total, Prim (UN "prim__lteFloat") (ty [FlType, FlType] IType) 2 (bfBin (<=)) (2, LFLe) total, Prim (UN "prim__gtFloat") (ty [FlType, FlType] IType) 2 (bfBin (>)) (2, LFGt) total, Prim (UN "prim__gteFloat") (ty [FlType, FlType] IType) 2 (bfBin (>=)) (2, LFGe) total, Prim (UN "prim__concat") (ty [StrType, StrType] StrType) 2 (sBin (++)) (2, LStrConcat) total, Prim (UN "prim__eqString") (ty [StrType, StrType] IType) 2 (bsBin (==)) (2, LStrEq) total, Prim (UN "prim__ltString") (ty [StrType, StrType] IType) 2 (bsBin (<)) (2, LStrLt) total, -- Conversions Prim (UN "prim__strToInt") (ty [StrType] IType) 1 (c_strToInt) (1, LStrInt) total, Prim (UN "prim__intToStr") (ty [IType] StrType) 1 (c_intToStr) (1, LIntStr) total, Prim (UN "prim__charToInt") (ty [ChType] IType) 1 (c_charToInt) (1, LChInt) total, Prim (UN "prim__intToChar") (ty [IType] ChType) 1 (c_intToChar) (1, LIntCh) total, Prim (UN "prim__intToBigInt") (ty [IType] BIType) 1 (c_intToBigInt) (1, LIntBig) total, Prim (UN "prim__bigIntToInt") (ty [BIType] IType) 1 (c_bigIntToInt) (1, LBigInt) total, Prim (UN "prim__strToBigInt") (ty [StrType] BIType) 1 (c_strToBigInt) (1, LStrBig) total, Prim (UN "prim__bigIntToStr") (ty [BIType] StrType) 1 (c_bigIntToStr) (1, LBigStr) total, Prim (UN "prim__strToFloat") (ty [StrType] FlType) 1 (c_strToFloat) (1, LStrFloat) total, Prim (UN "prim__floatToStr") (ty [FlType] StrType) 1 (c_floatToStr) (1, LFloatStr) total, Prim (UN "prim__intToFloat") (ty [IType] FlType) 1 (c_intToFloat) (1, LIntFloat) total, Prim (UN "prim__floatToInt") (ty [FlType] IType) 1 (c_floatToInt) (1, LFloatInt) total, Prim (UN "prim__floatExp") (ty [FlType] FlType) 1 (p_floatExp) (1, LFExp) total, Prim (UN "prim__floatLog") (ty [FlType] FlType) 1 (p_floatLog) (1, LFLog) total, Prim (UN "prim__floatSin") (ty [FlType] FlType) 1 (p_floatSin) (1, LFSin) total, Prim (UN "prim__floatCos") (ty [FlType] FlType) 1 (p_floatCos) (1, LFCos) total, Prim (UN "prim__floatTan") (ty [FlType] FlType) 1 (p_floatTan) (1, LFTan) total, Prim (UN "prim__floatASin") (ty [FlType] FlType) 1 (p_floatASin) (1, LFASin) total, Prim (UN "prim__floatACos") (ty [FlType] FlType) 1 (p_floatACos) (1, LFACos) total, Prim (UN "prim__floatATan") (ty [FlType] FlType) 1 (p_floatATan) (1, LFATan) total, Prim (UN "prim__floatSqrt") (ty [FlType] FlType) 1 (p_floatSqrt) (1, LFSqrt) total, Prim (UN "prim__floatFloor") (ty [FlType] FlType) 1 (p_floatFloor) (1, LFFloor) total, Prim (UN "prim__floatCeil") (ty [FlType] FlType) 1 (p_floatCeil) (1, LFCeil) total, Prim (UN "prim__strHead") (ty [StrType] ChType) 1 (p_strHead) (1, LStrHead) partial, Prim (UN "prim__strTail") (ty [StrType] StrType) 1 (p_strTail) (1, LStrTail) partial, Prim (UN "prim__strCons") (ty [ChType, StrType] StrType) 2 (p_strCons) (2, LStrCons) total, Prim (UN "prim__strIndex") (ty [StrType, IType] ChType) 2 (p_strIndex) (2, LStrIndex) partial, Prim (UN "prim__strRev") (ty [StrType] StrType) 1 (p_strRev) (1, LStrRev) total, Prim (UN "prim__readString") (ty [PtrType] StrType) 1 (p_cantreduce) (1, LReadStr) partial, Prim (UN "prim__vm") (ty [] PtrType) 0 (p_cantreduce) (0, LVMPtr) total, -- Streams Prim (UN "prim__stdin") (ty [] PtrType) 0 (p_cantreduce) (0, LStdIn) partial, Prim (UN "prim__believe_me") believeTy 3 (p_believeMe) (3, LNoOp) partial -- ahem ] p_believeMe [_,_,x] = Just x p_believeMe _ = Nothing iUn op [VConstant (I x)] = Just $ VConstant (I (op x)) iUn _ _ = Nothing iBin op [VConstant (I x), VConstant (I y)] = Just $ VConstant (I (op x y)) iBin _ _ = Nothing bBin op [VConstant (BI x), VConstant (BI y)] = Just $ VConstant (BI (op x y)) bBin _ _ = Nothing bBini op [VConstant (BI x), VConstant (BI y)] = Just $ VConstant (I (op x y)) bBini _ _ = Nothing biBin op = iBin (\x y -> if (op x y) then 1 else 0) bbBin op = bBini (\x y -> if (op x y) then 1 else 0) fBin op [VConstant (Fl x), VConstant (Fl y)] = Just $ VConstant (Fl (op x y)) fBin _ _ = Nothing bfBin op [VConstant (Fl x), VConstant (Fl y)] = let i = (if op x y then 1 else 0) in Just $ VConstant (I i) bfBin _ _ = Nothing bcBin op [VConstant (Ch x), VConstant (Ch y)] = let i = (if op x y then 1 else 0) in Just $ VConstant (I i) bcBin _ _ = Nothing bsBin op [VConstant (Str x), VConstant (Str y)] = let i = (if op x y then 1 else 0) in Just $ VConstant (I i) bsBin _ _ = Nothing sBin op [VConstant (Str x), VConstant (Str y)] = Just $ VConstant (Str (op x y)) sBin _ _ = Nothing s8div :: Word8 -> Word8 -> Word8 s8div x y = fromIntegral (fromIntegral x `div` fromIntegral y :: Int8) s16div :: Word16 -> Word16 -> Word16 s16div x y = fromIntegral (fromIntegral x `div` fromIntegral y :: Int16) s32div :: Word32 -> Word32 -> Word32 s32div x y = fromIntegral (fromIntegral x `div` fromIntegral y :: Int32) s64div :: Word64 -> Word64 -> Word64 s64div x y = fromIntegral (fromIntegral x `div` fromIntegral y :: Int64) s8rem :: Word8 -> Word8 -> Word8 s8rem x y = fromIntegral (fromIntegral x `rem` fromIntegral y :: Int8) s16rem :: Word16 -> Word16 -> Word16 s16rem x y = fromIntegral (fromIntegral x `rem` fromIntegral y :: Int16) s32rem :: Word32 -> Word32 -> Word32 s32rem x y = fromIntegral (fromIntegral x `rem` fromIntegral y :: Int32) s64rem :: Word64 -> Word64 -> Word64 s64rem x y = fromIntegral (fromIntegral x `rem` fromIntegral y :: Int64) b8Bin op [VConstant (B8 x), VConstant (B8 y)] = Just $ VConstant (B8 (op x y)) b8Bin _ _ = Nothing b8Un op [VConstant (B8 x)] = Just $ VConstant (B8 (op x)) b8Un _ _ = Nothing b16Bin op [VConstant (B16 x), VConstant (B16 y)] = Just $ VConstant (B16 (op x y)) b16Bin _ _ = Nothing b16Un op [VConstant (B16 x)] = Just $ VConstant (B16 (op x)) b16Un _ _ = Nothing b32Bin op [VConstant (B32 x), VConstant (B32 y)] = Just $ VConstant (B32 (op x y)) b32Bin _ _ = Nothing b32Un op [VConstant (B32 x)] = Just $ VConstant (B32 (op x)) b32Un _ _ = Nothing b64Bin op [VConstant (B64 x), VConstant (B64 y)] = Just $ VConstant (B64 (op x y)) b64Bin _ _ = Nothing b64Un op [VConstant (B64 x)] = Just $ VConstant (B64 (op x)) b64Un _ _ = Nothing b8Cmp op [VConstant (B8 x), VConstant (B8 y)] = Just $ VConstant (I (if (op x y) then 1 else 0)) b8Cmp _ _ = Nothing b16Cmp op [VConstant (B16 x), VConstant (B16 y)] = Just $ VConstant (I (if (op x y) then 1 else 0)) b16Cmp _ _ = Nothing b32Cmp op [VConstant (B32 x), VConstant (B32 y)] = Just $ VConstant (I (if (op x y) then 1 else 0)) b32Cmp _ _ = Nothing b64Cmp op [VConstant (B64 x), VConstant (B64 y)] = Just $ VConstant (I (if (op x y) then 1 else 0)) b64Cmp _ _ = Nothing toB8 x = VConstant (B8 (fromIntegral x)) toB16 x = VConstant (B16 (fromIntegral x)) toB32 x = VConstant (B32 (fromIntegral x)) toB64 x = VConstant (B64 (fromIntegral x)) zext8_16 [VConstant (B8 x)] = Just $ toB16 x zext8_16 _ = Nothing zext8_32 [VConstant (B8 x)] = Just $ toB32 x zext8_32 _ = Nothing zext8_64 [VConstant (B8 x)] = Just $ toB64 x zext8_64 _ = Nothing sext8_16 [VConstant (B8 x)] = Just $ toB16 (fromIntegral x :: Int8) sext8_16 _ = Nothing sext8_32 [VConstant (B8 x)] = Just $ toB32 (fromIntegral x :: Int8) sext8_32 _ = Nothing sext8_64 [VConstant (B8 x)] = Just $ toB64 (fromIntegral x :: Int8) sext8_64 _ = Nothing zext16_32 [VConstant (B16 x)] = Just $ toB32 x zext16_32 _ = Nothing zext16_64 [VConstant (B16 x)] = Just $ toB64 x zext16_64 _ = Nothing sext16_32 [VConstant (B16 x)] = Just $ toB32 (fromIntegral x :: Int16) sext16_32 _ = Nothing sext16_64 [VConstant (B16 x)] = Just $ toB64 (fromIntegral x :: Int16) sext16_64 _ = Nothing trunc16_8 [VConstant (B16 x)] = Just $ toB8 x trunc16_8 _ = Nothing zext32_64 [VConstant (B32 x)] = Just $ toB64 x zext32_64 _ = Nothing sext32_64 [VConstant (B32 x)] = Just $ toB64 (fromIntegral x :: Int32) sext32_64 _ = Nothing trunc32_8 [VConstant (B32 x)] = Just $ toB8 x trunc32_8 _ = Nothing trunc32_16 [VConstant (B32 x)] = Just $ toB16 x trunc32_16 _ = Nothing trunc64_8 [VConstant (B64 x)] = Just $ toB8 x trunc64_8 _ = Nothing trunc64_16 [VConstant (B64 x)] = Just $ toB16 x trunc64_16 _ = Nothing trunc64_32 [VConstant (B64 x)] = Just $ toB32 x trunc64_32 _ = Nothing intToBits8 [VConstant (I x)] = Just $ toB8 x intToBits8 _ = Nothing intToBits16 [VConstant (I x)] = Just $ toB16 x intToBits16 _ = Nothing intToBits32 [VConstant (I x)] = Just $ toB32 x intToBits32 _ = Nothing intToBits64 [VConstant (I x)] = Just $ toB64 x intToBits64 _ = Nothing bits32ToInt [VConstant (B32 x)] = Just $ VConstant (I (fromIntegral x)) bits32ToInt _ = Nothing c_intToStr [VConstant (I x)] = Just $ VConstant (Str (show x)) c_intToStr _ = Nothing c_strToInt [VConstant (Str x)] = case reads x of [(n,"")] -> Just $ VConstant (I n) _ -> Just $ VConstant (I 0) c_strToInt _ = Nothing c_intToChar [VConstant (I x)] = Just $ VConstant (Ch (toEnum x)) c_intToChar _ = Nothing c_charToInt [VConstant (Ch x)] = Just $ VConstant (I (fromEnum x)) c_charToInt _ = Nothing c_intToBigInt [VConstant (I x)] = Just $ VConstant (BI (fromIntegral x)) c_intToBigInt _ = Nothing c_bigIntToInt [VConstant (BI x)] = Just $ VConstant (I (fromInteger x)) c_bigIntToInt _ = Nothing c_bigIntToStr [VConstant (BI x)] = Just $ VConstant (Str (show x)) c_bigIntToStr _ = Nothing c_strToBigInt [VConstant (Str x)] = case reads x of [(n,"")] -> Just $ VConstant (BI n) _ -> Just $ VConstant (BI 0) c_strToBigInt _ = Nothing c_floatToStr [VConstant (Fl x)] = Just $ VConstant (Str (show x)) c_floatToStr _ = Nothing c_strToFloat [VConstant (Str x)] = case reads x of [(n,"")] -> Just $ VConstant (Fl n) _ -> Just $ VConstant (Fl 0) c_strToFloat _ = Nothing c_floatToInt [VConstant (Fl x)] = Just $ VConstant (I (truncate x)) c_floatToInt _ = Nothing c_intToFloat [VConstant (I x)] = Just $ VConstant (Fl (fromIntegral x)) c_intToFloat _ = Nothing p_fPrim f [VConstant (Fl x)] = Just $ VConstant (Fl (f x)) p_fPrim f _ = Nothing p_floatExp = p_fPrim exp p_floatLog = p_fPrim log p_floatSin = p_fPrim sin p_floatCos = p_fPrim cos p_floatTan = p_fPrim tan p_floatASin = p_fPrim asin p_floatACos = p_fPrim acos p_floatATan = p_fPrim atan p_floatSqrt = p_fPrim sqrt p_floatFloor = p_fPrim (fromInteger . floor) p_floatCeil = p_fPrim (fromInteger . ceiling) p_strHead [VConstant (Str (x:xs))] = Just $ VConstant (Ch x) p_strHead _ = Nothing p_strTail [VConstant (Str (x:xs))] = Just $ VConstant (Str xs) p_strTail _ = Nothing p_strIndex [VConstant (Str xs), VConstant (I i)] | i < length xs = Just $ VConstant (Ch (xs!!i)) p_strIndex _ = Nothing p_strCons [VConstant (Ch x), VConstant (Str xs)] = Just $ VConstant (Str (x:xs)) p_strCons _ = Nothing p_strRev [VConstant (Str xs)] = Just $ VConstant (Str (reverse xs)) p_strRev _ = Nothing p_cantreduce _ = Nothing elabPrim :: Prim -> Idris () elabPrim (Prim n ty i def sc tot) = do updateContext (addOperator n ty i def) setTotality n tot i <- getIState putIState i { idris_scprims = (n, sc) : idris_scprims i } elabPrims :: Idris () elabPrims = do mapM_ (elabDecl EAll toplevel) (map (PData "" defaultSyntax (FC "builtin" 0) False) [inferDecl, unitDecl, falseDecl, pairDecl, eqDecl]) mapM_ elabPrim primitives