module Language.Hakaru.CodeGen.Libs
(
expE, expm1E, logE, log1pE, sqrtE,
infinityE,negInfinityE,
printfE, sscanfE, fopenE, fcloseE, fileT, feofE, fgetsE, rewindE,
randE, srandE, mallocE, freeE,
gcHeader, gcInit, gcMalloc,
openMpHeader, ompGetNumThreads, ompGetThreadNum, OMP(..), Directive(..),
ompToPP
) where
import Language.Hakaru.CodeGen.AST
import Language.Hakaru.CodeGen.Pretty
import Text.PrettyPrint (render)
expE,expm1E,logE,log1pE,sqrtE :: CExpr -> CExpr
expE = mkUnaryE "exp"
expm1E = mkUnaryE "expm1"
logE = mkUnaryE "log"
log1pE = mkUnaryE "log1p"
sqrtE = mkUnaryE "sqrt"
infinityE,negInfinityE :: CExpr
infinityE = (intE 1) ./. (intE 0)
negInfinityE = logE (intE 0)
randE :: CExpr
randE = mkCallE "rand" []
srandE :: CExpr -> CExpr
srandE e = mkCallE "srand" [e]
mallocE :: CExpr -> CExpr
mallocE = mkUnaryE "malloc"
freeE :: CExpr -> CExpr
freeE = mkUnaryE "free"
printfE,sscanfE :: [CExpr] -> CExpr
printfE = mkCallE "printf"
sscanfE = mkCallE "sscanf"
fopenE :: CExpr -> CExpr -> CExpr
fopenE e0 e1 = mkCallE "fopen" [e0,e1]
fcloseE,feofE,rewindE :: CExpr -> CExpr
fcloseE e = mkCallE "fclose" [e]
feofE e = mkCallE "feof" [e]
rewindE e = mkCallE "rewind" [e]
fgetsE :: CExpr -> CExpr -> CExpr -> CExpr
fgetsE e0 e1 e2 = mkCallE "fgets" [e0,e1,e2]
fileT :: CTypeSpec
fileT = CTypeDefType (Ident "FILE")
gcHeader :: Preprocessor
gcHeader = PPInclude "gc.h"
gcInit :: CExpr
gcInit = mkCallE "GC_INIT" []
gcMalloc :: CExpr -> CExpr
gcMalloc e = mkCallE "GC_MALLOC" [e]
openMpHeader :: Preprocessor
openMpHeader = PPInclude "omp.h"
ompGetNumThreads :: CExpr
ompGetNumThreads = mkCallE "omp_get_num_threads" []
ompGetThreadNum :: CExpr
ompGetThreadNum = mkCallE "omp_get_thread_num" []
data OMP = OMP Directive
data Directive
= Parallel [Directive]
| For
| Critical
| Reduction (Either CBinaryOp Ident) [CExpr]
| DeclareRed Ident CTypeSpec CExpr CExpr
ompToPP :: OMP -> Preprocessor
ompToPP (OMP d) = PPPragma $ "omp":(showDirective d)
where showDirective :: Directive -> [String]
showDirective (Parallel ds) = "parallel":(concatMap showDirective ds)
showDirective For = ["for"]
showDirective Critical = ["critical"]
showDirective (Reduction eop vs) =
let op = case eop of
Left binop -> render . pretty $ binop
Right (Ident s) -> s
in ["reduction(",op,":",unwords . fmap (render. pretty) $ vs,")"]
showDirective (DeclareRed (Ident name) typ mul unit) =
let typ' = render . pretty $ typ
mul' = render . pretty $ mul
unit' = render . pretty $ unit
in ["declare","reduction(",name,":",typ',":",mul',") initializer ("
,unit',")"]