1 implementation module Data.GenType.CType
3 import Control.Applicative
4 import Control.Monad => qualified join
5 import Control.Monad.State
6 import Control.Monad.Trans
12 import qualified Data.Map
13 from Data.Map import :: Map(..), putList, alter, get, union, fromList
18 typedefs :: [[Type]] -> Either String [String]
19 typedefs ts = flatten <$> evalStateT (mapM typedefgroup ts) 'Data.Map'.newMap
21 :: TDMonad :== StateT TDState (Either String) [String]
22 :: TDState :== 'Data.Map'.Map String (String, Bool)
24 typedefgroup :: [Type] -> TDMonad
27 <$ modify (putList [(typeName ty, (prefix ty, True))\\ty<-ts])
28 <*> mapM (\t->typedef t >>= post ["\n"]) ts
29 <* modify (flip (foldr $ alter (fmap (fmap \_->False)) o typeName) ts)
32 ts = mapM (\x->printTypeName x >>= post [";\n"]) (map typeName ts)
35 prefix :: Type -> String
36 prefix (TyRecord _ _) = "struct "
37 prefix (TyObject _ fs)
38 | and [t =: [] \\ (_, t)<-fs] = "enum "
39 | fs =: [(_, [_])] = ""
40 | fs =: [_] = "struct "
44 printTypeName :: String -> TDMonad
46 = gets $ maybe [safe tname, " "] (\(p, b)->[p, safe tname, if b " *" " "]) o get tname
48 safe s = concat [sf c\\c <-:s]
72 pre :: [String] (m [String]) -> m [String] | Monad m
73 pre t s = ((++)t) <$> s
75 post :: [String] [String] -> m [String] | pure m
76 post t s = pure (s ++ t)
78 typedef :: Type -> TDMonad
79 typedef (TyRef s) = printTypeName s
80 typedef (TyBasic t) = case t of
81 BTInt = printTypeName "int64_t"
82 BTChar = printTypeName "char"
83 BTReal = printTypeName "double"
84 BTBool = printTypeName "bool"
85 t = pure []//liftT $ Left $ "basic type: " +++ toString t +++ " not implemented"
86 typedef (TyArray _ a) = pre ["*"] $ typedef a
87 typedef t=:(TyNewType ti ci a)
88 = pre ["// ", toString t, "\n"] $ tydef ti.gtd_name ci.gcd_type
89 typedef t=:(TyRecord ti fs) = pre
90 [ "// ", toString t, "\n", "struct ", safe ti.grd_name, " {\n"]
91 $ fmtFields 1 ti.grd_type [fi.gfd_name\\(fi, _)<-fs] >>= post ["};\n"]
93 typedef t=:(TyObject ti fs)
94 | and [t =: [] \\ (_, t)<-fs] = pure
95 [ "// ", toString t, "\n", "enum ", safe ti.gtd_name, " {"
96 , join ", " [safe ci.gcd_name\\(ci, _)<-fs], "};\n"]
97 //Single constructor, single field (box)
98 typedef t=:(TyObject ti [(ci, [ty])]) = pre
99 ["// ", toString t, "\n"] $ tydef ti.gtd_name ci.gcd_type
101 typedef t=:(TyObject ti [(ci, ts)]) = pre
102 [ "// ", toString t, "\n", "struct ", safe ti.gtd_name, " {\n"]
103 $ fmtFields 1 ci.gcd_type ["f" +++ toString i\\i<-indexList ts] >>= post ["};\n"]
105 typedef t=:(TyObject ti fs) = pre
106 [ "// ", toString t, "\nstruct ", safe ti.gtd_name, " {\n"
107 , "\tenum {", join ", " [safe ci.gcd_name\\(ci, _)<-fs], "} cons;\n"
110 >>= post ["\t} data;\n};\n"] o flatten
112 fmtCons :: (GenericConsDescriptor, [Type]) -> TDMonad
113 fmtCons (ci, []) = pure []
114 fmtCons (ci, ts) = pre ["\t\tstruct {\n"]
115 $ fmtFields 3 ci.gcd_type ["f" +++ toString i\\i<-indexList ts]
116 >>= post ["\t\t} ", safe ci.gcd_name, ";\n"]
117 typedef t = liftT $ Left $ toString t +++ " not implemented"
119 tydef name (GenTypeArrow l r) = pre ["typedef "] $ fmtField "" l >>= post [safe name,";\n"]
121 fmtFields :: Int GenType [String] -> TDMonad
122 fmtFields i _ [] = pure []
123 fmtFields i (GenTypeArrow l r) [x:xs] = pre [createArray i '\t'] $ fmtField x l >>= \c->pre (c ++ [";\n"]) $ fmtFields i r xs
125 fmtField :: String GenType -> TDMonad
126 fmtField x (GenTypeCons a) = printTypeName a >>= post [x]
127 fmtField x (GenTypeVar a) = pure ["void *",x]
128 fmtField x (GenTypeApp l r) = fmtField x l
129 fmtField x t=:(GenTypeArrow _ r)
130 = map concat <$> mapM (fmtField "") (collectArgs t [])
131 >>= \[r:as]->pure [r, " (*",x,")(",join ", " as, ")"]
133 collectArgs (GenTypeArrow l r) c = collectArgs r (c ++ [l])
134 collectArgs t c = [t:c]