use reader for indentation
[clean-tests.git] / gengen / Data / GenType / CType.icl
index 3c4ca1e..b359194 100644 (file)
@@ -5,6 +5,7 @@ import Control.Monad => qualified join
 import Control.Monad.State
 import Control.Monad.Trans
 import Control.Monad.Writer
+import Control.Monad.Reader
 import Control.Monad.Fail
 import Data.Either
 import Data.Func
@@ -40,58 +41,60 @@ prefix  _ = ""
 consName :: GenericTypeDefDescriptor -> String
 consName s = "enum " +++ safe s.gtd_name +++ "_cons"
 
-indent i c = tell [createArray i '\t':c]
+iindent = mapWriterT $ mapStateT $ local inc
+indent c = liftT (liftT ask) >>= \i->tell [createArray i '\t':c]
 
-:: FTMonad :== WriterT [String] (StateT [(String, [String])] (Either String)) ()
+:: FTMonad :== WriterT [String] (StateT [(String, [String])] (ReaderT Int (Either String))) ()
 flatTypedef :: Type -> Either String [String]
 flatTypedef t = (\(w, es)->flatten (map snd es) ++ w)
-       <$> runStateT (execWriterT (ftd t True 0)) []
+       <$> runReaderT (runStateT (execWriterT (ftd t True )) []) 0
 where
-       ftd :: Type Bool Int -> FTMonad
-       ftd (TyRef s) tl i = indent i [s]
-       ftd (TyBasic t) tl i 
+       ftd :: Type Bool -> FTMonad
+       ftd (TyRef s) tl = indent [s]
+       ftd (TyBasic t) tl
                | tl = pure ()
-                = case t of
-                       BTInt  = indent ["int64_t"]
-                       BTChar = indent ["char"]
-                       BTReal = indent ["double"]
-                       BTBool = indent ["bool"]
-                       t = fail $ "cannot flatTypedef: " +++ toString t
-//     ftd (TyArrow l r) i c = indent i ["*":ftd a i c]
-       ftd (TyNewType ti ci a) tl i = ftd a tl i
-       ftd (TyArray _ a) tl i = indent i ["*"] >>| ftd a tl i
-       ftd (TyRecord ti fs) tl i
-               = indent ["struct ", if tl (safe ti.grd_name) "", " {\n"
-               ] >>| mapM_ (fmtField $ i+1) [(fi.gfd_name, ty)\\(fi, ty)<-fs]
-               >>| indent ["}\n"]
+               = case t of
+                       BTInt  = indent ["int64_t"]
+                       BTChar = indent ["char"]
+                       BTReal = indent ["double"]
+                       BTBool = indent ["bool"]
+                       t = fail $ "flatTypedef: there is no basic type for " +++ toString t
+       ftd (TyArrow l r) tl = fail "flatTypedef: functions cannot be serialized"
+       ftd (TyNewType ti ci a) tl = ftd a tl
+       ftd (TyArray _ a) tl = indent ["*"] >>| ftd a tl
+       ftd (TyRecord ti fs) tl
+               = indent ["struct ", if tl (safe ti.grd_name) "", " {\n"
+               ] >>| mapM_ (iindent o fmtField) [(fi.gfd_name, ty)\\(fi, ty)<-fs]
+               >>| indent ["}\n"]
        //Enumeration
-       ftd (TyObject ti fs) tl i
+       ftd (TyObject ti fs) tl
                | and [t =: [] \\ (_, t)<-fs]
                        | tl = pure ()
-                       = indent [] >>| enum ti fs
+                       = indent [] >>| enum ti fs
        //Single constructor, single field (box)
-       ftd (TyObject ti [(ci, [ty])]) tl i = ftd ty tl i
+       ftd (TyObject ti [(ci, [ty])]) tl = ftd ty tl
        //Single constructor
-       ftd (TyObject ti [(ci, ts)]) tl i
-               =   indent ["struct ", if tl (safe ti.gtd_name) "", " {\n"]
-               >>| mapM_ (fmtField $ i+1) [("f" +++ toString i, ty)\\i<-[0..] & ty<-ts]
-               >>| indent ["}"]
+       ftd (TyObject ti [(ci, ts)]) tl
+               =   indent ["struct ", if tl (safe ti.gtd_name) "", " {\n"]
+               >>| mapM_ (iindent o fmtField) [("f" +++ toString i, ty)\\i<-[0..] & ty<-ts]
+               >>| indent ["}"]
        //Complex adt
-       ftd (TyObject ti fs) tl i
-               =   indent i ["struct ", if tl (safe ti.gtd_name) "", " {\n"]
-               >>| indent (i+1) [] >>| enum ti fs >>| tell [" cons;\n"]
-               >>| indent (i+1) ["struct {\n"]
-               >>| mapM_ (fmtCons $ i+2) fs
-               >>| indent (i+1) ["} data;\n"]
-               >>| indent i ["}", if tl ";" ""]
+       ftd (TyObject ti fs) tl
+               =   indent ["struct ", if tl (safe ti.gtd_name) "", " {\n"]
+               >>| iindent (indent []) >>| enum ti fs >>| tell [" cons;\n"]
+               >>| indent [] >>| enum ti fs >>| tell [" cons;\n"]
+               >>| indent ["struct {\n"]
+               >>| mapM_ (iindent o iindent o fmtCons) fs
+               >>| iindent (indent ["} data;\n"])
+               >>| indent ["}", if tl ";" ""]
        where
-               fmtCons (ci, []) = pure ()
-               fmtCons i (ci, [t]) = ftd t False i >>| tell [" ", safe ci.gcd_name, ";\n"]
-               fmtCons (ci, ts)
-                       =   indent ["struct {\n"]
-                       >>| mapM_ (fmtField $ i+1) [("f" +++ toString i, ty)\\i<-[0..] & ty<-ts]
-                       >>| indent ["} ", safe ci.gcd_name, ";\n"]
-       ftd t tl = fail $ "cannot flatTypedef: " +++ toString t
+               fmtCons (ci, []) = pure ()
+               fmtCons (ci, [t]) = ftd t False >>| tell [" ", safe ci.gcd_name, ";\n"]
+               fmtCons (ci, ts)
+                       =   indent ["struct {\n"]
+                       >>| mapM_ (iindent o fmtField) [("f" +++ toString i, ty)\\i<-[0..] & ty<-ts]
+                       >>| indent ["} ", safe ci.gcd_name, ";\n"]
+       ftd t tl = fail $ "cannot flatTypedef: " +++ toString t
 
        
        enum :: GenericTypeDefDescriptor [(GenericConsDescriptor, [Type])] -> FTMonad
@@ -99,8 +102,8 @@ where
                ?None = liftT (modify \s->[(ti.gtd_name, [consName ti, " {", join ", " [safe ci.gcd_name\\(ci, _)<-fs], "};\n"]):s]) >>| enum ti fs
                ?Just _ = tell [consName ti]
 
-       fmtField :: Int (String, Type) -> FTMonad
-       fmtField i (name, ty) = ftd ty False i >>| tell [" ", name, ";\n"]
+       fmtField :: (String, Type) -> FTMonad
+       fmtField (name, ty) = ftd ty False >>| tell [" ", name, ";\n"]
 
 :: TDMonad :== WriterT [String] (StateT TDState (Either String)) ()
 :: TDState :== 'Data.Map'.Map String (String, Bool)
@@ -171,7 +174,7 @@ where
        fmtFields :: Int GenType [String] -> TDMonad
        fmtFields i _ [] = pure ()
        fmtFields i (GenTypeArrow l r) [x:xs]
-               = indent i [] >>| fmtField x l >>| tell [";\n"] >>| fmtFields i r xs
+               = tell [createArray i '\t'] >>| fmtField x l >>| tell [";\n"] >>| fmtFields i r xs
        
        fmtField :: String GenType -> TDMonad
        fmtField x (GenTypeCons a) = printTypeName a >>| tell [x]