gengen
authorMart Lubbers <mart@martlubbers.net>
Thu, 9 Jul 2020 13:28:30 +0000 (15:28 +0200)
committerMart Lubbers <mart@martlubbers.net>
Thu, 9 Jul 2020 13:28:30 +0000 (15:28 +0200)
gengen/Data/GenType.dcl [new file with mode: 0644]
gengen/Data/GenType.icl [new file with mode: 0644]
gengen/Data/GenType/CType.dcl [new file with mode: 0644]
gengen/Data/GenType/CType.icl [new file with mode: 0644]
gengen/gen.icl [deleted file]
gengen/gengen.hs [new file with mode: 0644]
gengen/test.hs [new file with mode: 0644]
gengen/test.icl

diff --git a/gengen/Data/GenType.dcl b/gengen/Data/GenType.dcl
new file mode 100644 (file)
index 0000000..8bef27a
--- /dev/null
@@ -0,0 +1,90 @@
+definition module Data.GenType
+
+import StdGeneric
+from StdMaybe import :: Maybe
+
+:: Box b a =: Box b
+derive bimap Box
+unBox (Box b) :== b
+box b :== Box b
+reBox x :== box (unBox x)
+
+:: GType
+       = GTyBasic BasicType
+       | GTyRef String
+       | GTyArrow GType GType
+       | GTyArray ArrayType GType
+       | GTyUList UListType GType
+       | GTyUnit
+       | GTyEither GType GType
+       | GTyPair GType GType
+       | GTyCons GenericConsDescriptor GType
+       | GTyField GenericFieldDescriptor GType
+       | GTyObject GenericTypeDefDescriptor GType
+       | GTyRecord GenericRecordDescriptor GType
+
+:: Type
+       = TyBasic BasicType
+       | TyRef String
+       | TyArrow Type Type
+       | TyArray ArrayType Type
+       | TyUList UListType Type
+       | TyNewType GenericTypeDefDescriptor GenericConsDescriptor Type
+       | TyObject GenericTypeDefDescriptor [(GenericConsDescriptor, [Type])]
+       | TyRecord GenericRecordDescriptor [(GenericFieldDescriptor, Type)]
+
+:: BasicType = BTInt | BTChar | BTReal | BTBool | BTDynamic | BTFile | BTWorld
+:: ArrayType = AStrict | ALazy | AUnboxed | APacked
+:: UListType = ULLazy | ULStrict
+
+instance == GType, Type, BasicType, ArrayType, UListType, GenType
+instance toString GType, Type, BasicType, ArrayType, UListType, GenType
+
+/**
+ * Removes recursive types by replacing them with references
+ *
+ * @param gtype
+ * @result the main type
+ * @result all the separate types grouped in the strongly connected components
+ */
+flattenGType :: GType -> [[GType]]
+
+/**
+ * Convert a GType to a Type. This always returns a Just if the GType was
+ * constructed using the gType generic function
+ *
+ * @param gtype
+ * @result a type on success
+ */
+gTypeToType :: GType -> Maybe Type
+
+/**
+ * Gives the name for the type
+ */
+typeName :: Type -> String
+
+/**
+ * Predicate whether the outer type is a builtin type
+ */
+class isBuiltin a :: a -> Bool
+instance isBuiltin Type
+instance isBuiltin GType
+
+/**
+ * Replace builtin constructors with their pretty names
+ */
+class replaceBuiltins a :: a -> a
+instance replaceBuiltins Type
+instance replaceBuiltins GType
+instance replaceBuiltins GenType
+
+/**
+ * Creates a deep representation of the type
+ */
+generic gType a :: Box GType a
+derive gType UNIT, EITHER, PAIR, CONS of gcd, FIELD of gfd, OBJECT of gtd, RECORD of grd
+derive gType Int, Bool, Real, Char, World, Dynamic, File
+derive gType (->)
+derive gType /*?#,*/ ?, ?^
+derive gType [], [! ], [ !], [!!], [#], [#!], {}, {!}, {#}, {32#}
+derive gType (), (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)
diff --git a/gengen/Data/GenType.icl b/gengen/Data/GenType.icl
new file mode 100644 (file)
index 0000000..64b804d
--- /dev/null
@@ -0,0 +1,354 @@
+implementation module Data.GenType
+
+import StdEnv, StdGeneric, StdMaybe
+import Control.Applicative
+
+import Control.Monad => qualified join
+import Control.Monad.State
+import Data.GenEq
+import Control.Monad.Writer
+import Control.Monad.Trans
+import Data.Func
+import Data.Functor
+import Data.Functor.Identity
+import Data.Generics
+import Data.List
+import Data.Maybe
+import Text
+
+derive bimap Box
+derive gEq BasicType, UListType, ArrayType, GenType
+instance == BasicType where (==) a b = a === b
+instance == UListType where (==) a b = a === b
+instance == ArrayType where (==) a b = a === b
+instance == GenType where (==) a b = a === b
+instance == GType where (==) x y = gTypeEqShallow (2<<30-1) x y
+
+/**
+ * Compares two GTypes only up to a given depth
+ *
+ * @param depth
+ * @param lhs
+ * @param rhs
+ * @return equality
+ */
+gTypeEqShallow :: Int GType GType -> Bool
+gTypeEqShallow i _ _
+       | i < 0 = True
+gTypeEqShallow _ (GTyBasic i) (GTyBasic j) = i == j
+gTypeEqShallow _ (GTyRef i) (GTyRef j) = i == j
+gTypeEqShallow _ (GTyRef i) (GTyObject j _) = i == j.gtd_name
+gTypeEqShallow _ (GTyRef i) (GTyRecord j _) = i == j.grd_name
+gTypeEqShallow _ (GTyObject j _) (GTyRef i) = i == j.gtd_name
+gTypeEqShallow _ (GTyRecord j _) (GTyRef i) = i == j.grd_name
+gTypeEqShallow i (GTyArrow l1 r1) (GTyArrow l2 r2) = gTypeEqShallow (dec i) l1 l2 && gTypeEqShallow (dec i) r1 r2
+gTypeEqShallow i (GTyArray s1 a1) (GTyArray s2 a2) = s1 == s2 && gTypeEqShallow (dec i) a1 a2
+gTypeEqShallow i (GTyUList s1 a1) (GTyUList s2 a2) = s1 == s2 && gTypeEqShallow (dec i) a1 a2
+gTypeEqShallow _ GTyUnit GTyUnit = True
+gTypeEqShallow i (GTyEither l1 r1) (GTyEither l2 r2) = gTypeEqShallow i l1 l2 && gTypeEqShallow i r1 r2
+gTypeEqShallow i (GTyPair l1 r1) (GTyPair l2 r2) = gTypeEqShallow i l1 l2 && gTypeEqShallow i r1 r2
+gTypeEqShallow i (GTyCons i1 a1) (GTyCons i2 a2) = i1.gcd_name == i2.gcd_name && gTypeEqShallow i a1 a2
+gTypeEqShallow i (GTyField i1 a1) (GTyField i2 a2)
+       = i1.gfd_name == i2.gfd_name && i1.gfd_cons.grd_name == i2.gfd_cons.grd_name && gTypeEqShallow i a1 a2
+gTypeEqShallow i (GTyObject i1 a1) (GTyObject i2 a2)
+       = i1.gtd_name == i2.gtd_name && gTypeEqShallow (dec i) a1 a2
+gTypeEqShallow i (GTyRecord i1 a1) (GTyRecord i2 a2)
+       = i1.grd_name == i2.grd_name && gTypeEqShallow (dec i) a1 a2
+gTypeEqShallow _ _ _ = False
+
+instance == Type
+where
+       (==) (TyBasic a1) (TyBasic a2) = a1 == a2
+       (==) (TyRef a1) (TyRef a2) = a1 == a2
+       (==) (TyArrow l1 r1) (TyArrow l2 r2) = l1 == l2 && r1 == r2
+       (==) (TyArray s1 a1) (TyArray s2 a2) = s1 == s2 && a1 == a2
+       (==) (TyUList s1 a1) (TyUList s2 a2) = s1 == s2 && a1 == a2
+       (==) (TyNewType i1 j1 a1) (TyNewType i2 j2 a2)
+               = i1.gtd_name == i2.gtd_name && a1 == a2
+       (==) (TyObject i1 a1) (TyObject i2 a2)
+               = i1.gtd_name == i2.gtd_name && length a1 == length a2
+               && and [l1.gcd_name == l2.gcd_name && t1 == t2\\(l1, t1)<-a1 & (l2, t2)<-a2]
+       (==) (TyRecord i1 a1) (TyRecord i2 a2)
+               = i1.grd_name == i2.grd_name && length a1 == length a2
+               && and [l1.gfd_name == l2.gfd_name && t1 == t2\\(l1, t1)<-a1 & (l2, t2)<-a2]
+       (==) _ _ = False
+
+class print a :: a [String] -> [String]
+instance print Bool where print s c = [toString s:c]
+instance print Int where print s c = [toString s:c]
+instance print Char where print s c = [toString s:c]
+instance print String where print s c = [s:c]
+instance print BasicType
+where
+       print BTInt c = ["Int":c]
+       print BTChar c = ["Char":c]
+       print BTReal c = ["Real":c]
+       print BTBool c = ["Bool":c]
+       print BTDynamic c = ["Dynamic":c]
+       print BTFile c = ["File":c]
+       print BTWorld c = ["World":c]
+instance print UListType
+where
+       print ULStrict c = ["!":c]
+       print ULLazy c = c
+instance print ArrayType
+where
+       print AStrict c = ["!":c]
+       print AUnboxed c = ["#":c]
+       print APacked c = ["32#":c]
+       print ALazy c = c
+instance print GType
+where
+       print (GTyBasic s) c = print s c
+       print (GTyRef s) c = [s:c]
+       print (GTyArrow l r) c = ["((->)":print l [" ":print r [")":c]]]
+       print (GTyArray s a) c = ["{":print s $ print a ["}":c]]
+       print (GTyUList s a) c = ["[#":print s $ print s ["]":c]]
+       print GTyUnit c = ["UNIT":c]
+       print (GTyEither l r) c = ["(EITHER ":print l [" ":print r [")":c]]]
+       print (GTyPair l r) c = ["(PAIR ":print l [")":c]]
+       print (GTyCons i a) c = ["(CONS ", i.gcd_name, " ":print a [")":c]]
+       print (GTyField i a) c = ["(FIELD ", i.gfd_name, " ":print a [")":c]]
+       print (GTyObject i a) c = ["(OBJECT ", i.gtd_name, " ":print a [")":c]]
+       print (GTyRecord i a) c = ["(RECORD ", i.grd_name, " ":print a [")":c]]
+instance print Type
+where
+       print (TyBasic s) c = print s c
+       print (TyRef s) c = [s:c]
+       print (TyArrow l r) c = print l [" -> ":print r c]
+       print (TyArray s a) c = ["{":print s ["}":print a c]]
+       print (TyUList s a) c = ["[#":print s ["]":print a c]]
+       print (TyNewType i j cons) c = pTyVars i.gtd_name i.gtd_arity
+               [": ", j.gcd_name, " ":print (nttype j.gcd_type) c]
+       where
+               nttype (GenTypeArrow l r) = l
+       print (TyRecord i fields) c = pTyVars i.grd_name i.grd_type_arity
+               [" {":isperse ", " (pField (\i c->[i.gfd_name, " :: ":c]) fields i.grd_type) ["}":c]]
+       print (TyObject i conses) c = pTyVars i.gtd_name i.gtd_arity
+                       $ [" ":isperse " | " (map pCons conses) c]
+       where
+               pCons :: (GenericConsDescriptor, [Type]) [String] -> [String]
+               pCons (i, ts) c = n [" ":isperse " " (pField (\_->id) [(i, t)\\t<-ts] i.gcd_type) c]
+               where
+                       n c = case i.gcd_prio of
+                               GenConsNoPrio = [i.gcd_name:c]
+                               GenConsPrio a s = ["(",i.gcd_name,") infix",case a of
+                                       GenConsAssocRight = "r";
+                                       GenConsAssocLeft = "l"
+                                       _ = "", " ":print s c]
+
+pTyVars :: String Int [String] -> [String]
+pTyVars ty arity c = [":: ", ty, " ":isperse " " (map print ['a'..'a'+toChar (arity-1)]) [" =":c]]
+
+pField :: (a [String] -> [String]) [(a, Type)] GenType -> [[String] -> [String]]
+pField pre [] _ = []
+pField pre [(i, t):xs] (GenTypeArrow l r) = [pre i o print l:pField pre xs r]
+
+instance print GenType
+where
+       print (GenTypeVar i) c = print (['a'..] !! i) c
+       print t=:(GenTypeApp _ _) c = ["(":isperse " " (collectApps t []) [")":c]]
+       where
+               collectApps (GenTypeApp l r) c = collectApps l [print r:c]
+               collectApps a c = [print a:c]
+       print (GenTypeCons s) c = [s:c]
+       print (GenTypeArrow l r) c = ["(":print l [" -> ":print r [")":c]]]
+
+instance toString GType where toString a = concat $ print a []
+instance toString Type where toString a = concat $ print a []
+instance toString BasicType where toString a = concat $ print a []
+instance toString ArrayType where toString a = concat $ print a []
+instance toString UListType where toString a = concat $ print a []
+instance toString GenType where toString a = concat $ print a []
+
+isperse :: a [[a] -> [a]] [a] -> [a]
+isperse s m c = foldr id c $ intersperse (\c->[s:c]) m
+
+gTypeToType :: GType -> Maybe Type
+gTypeToType (GTyBasic a) = pure $ TyBasic a
+gTypeToType (GTyRef a) = pure $ TyRef a
+gTypeToType (GTyArrow l r) = TyArrow <$> gTypeToType l <*> gTypeToType r
+gTypeToType (GTyArray s a) = TyArray s <$> gTypeToType a
+gTypeToType (GTyUList s a) = TyUList s <$> gTypeToType a
+gTypeToType (GTyRecord i t) = TyRecord i <$> gtrec t
+where
+       gtrec (GTyField i t) = (\x->[(i, x)]) <$> gTypeToType t
+       gtrec (GTyPair l r) = (++) <$> gtrec l <*> gtrec r
+       gtrec _ = Nothing
+gTypeToType (GTyObject i=:{gtd_num_conses=0} t)
+       = TyNewType i (hd i.gtd_conses) <$> gTypeToType t
+gTypeToType (GTyObject i t) = TyObject i <$> gtobj t
+where
+       gtobj :: GType -> Maybe [(GenericConsDescriptor, [Type])]
+       gtobj (GTyEither l r) = (++) <$> gtobj l <*> gtobj r
+       gtobj (GTyCons i a) = (\x->[(i, x)]) <$> gtcons a
+       gtobj _ = Nothing
+       
+       gtcons :: GType -> Maybe [Type]
+       gtcons GTyUnit = pure []
+       gtcons (GTyPair l r) = (++) <$> gtcons l <*> gtcons r
+       gtcons t = (\x->[x]) <$> gTypeToType t
+
+:: FlatMonad :== State FMState GType
+:: FMState = { objects :: [String], types :: [GType], otypes :: [GType], depth :: Int }
+flattenGType :: GType -> [[GType]]
+flattenGType ot
+       # {types} = execState (mkf ot) {objects=[], otypes=[], types=[], depth=10}
+       = scc [(t, refs t [])\\t<-types]
+where
+       refs (GTyObject _ a) c = refs a c
+       refs (GTyRecord _ a) c = refs a c
+       refs (GTyEither l r) c = refs l $ refs r c
+       refs (GTyPair l r) c = refs l $ refs r c
+       refs (GTyCons _ a) c = refs a c
+       refs (GTyField _ a) c = refs a c
+       refs GTyUnit c = c
+       refs (GTyArrow l r) c = refs l $ refs r c
+       refs (GTyArray _ a) c = refs a c
+       refs (GTyUList _ a) c = refs a c
+       refs (GTyBasic _) c = c
+       refs a=:(GTyRef _) c = [a:c]
+
+       write :: (a GType -> GType) a GType -> FlatMonad | genericDescriptorName a
+       write cons t a = getState >>= \s
+               //We have seen the type but it might've had different arguments
+               | isMember name s.objects
+                       //We have not seen this configuration
+                       | isEmpty [ot \\ ot<-s.otypes | gTypeEqShallow s.depth ot a]
+                               = modify (\x->{x & depth=dec x.depth}) *> mkf a *> pure (GTyRef name)
+                       //If not, just return the basictype
+                               = pure $ GTyRef name
+               //We have not seen the type so we add, calculate and output it
+               = cons t <$ modify (\x->{x & otypes=[a:x.otypes], objects=[name:x.objects]}) <*> mkf a
+                       >>= \ty->addIfNotThere ty >>| pure (GTyRef name)
+       where
+               name = genericDescriptorName t
+
+       addIfNotThere :: GType -> FlatMonad
+       addIfNotThere ty = getState >>= \s
+               | isMember ty s.types
+                       = pure ty
+                       = modify (\s->{s & types=[ty:s.types]}) >>| pure ty
+
+       mkf :: GType -> FlatMonad
+       mkf (GTyObject t a) = write GTyObject t a
+       mkf (GTyRecord t a) = write GTyRecord t a
+       mkf (GTyEither l r) = GTyEither <$> mkf l <*> mkf r
+       mkf (GTyPair l r) = GTyPair <$> mkf l <*> mkf r
+       mkf (GTyCons i a) = GTyCons i <$> mkf a
+       mkf (GTyField i a) = GTyField i <$> mkf a
+       mkf GTyUnit = pure GTyUnit
+       mkf (GTyArrow l r) = GTyArrow <$> mkf l <*> mkf r
+       mkf (GTyArray s a) = GTyArray s <$> mkf a
+       mkf (GTyUList s a) = GTyUList s <$> mkf a
+       mkf a=:(GTyBasic _) = addIfNotThere a
+       mkf a=:(GTyRef _) = pure a
+
+typeName :: Type -> String
+typeName (TyBasic a) = toString a
+typeName (TyRef a) = a
+typeName (TyArrow l r) = typeName l +++ "->" +++ typeName r
+typeName (TyArray s a) = "{" +++ toString s +++ typeName a +++ "}"
+typeName (TyUList s a) = "{" +++ toString s +++ typeName a +++ "}"
+typeName (TyNewType i _ _) = i.gtd_name
+typeName (TyObject i _) = i.gtd_name
+typeName (TyRecord i _) = i.grd_name
+
+instance isBuiltin String
+where
+       isBuiltin s = [()\\(l, r)<-predef | l == s || r == s] =: [_:_]
+instance isBuiltin Type
+where
+       isBuiltin (TyObject i a) = isBuiltin i.gtd_name
+       isBuiltin (TyRecord i a) = isBuiltin i.grd_name
+       isBuiltin (TyRef a) = isBuiltin a
+       isBuiltin _ = True
+instance isBuiltin GType
+where
+       isBuiltin (GTyObject i a) = isBuiltin i.gtd_name
+       isBuiltin (GTyRecord i a) = isBuiltin i.grd_name
+       isBuiltin (GTyRef a) = isBuiltin a
+       isBuiltin _ = True
+
+instance replaceBuiltins GenericFieldDescriptor
+where
+       replaceBuiltins s = {s & gfd_name=replaceBuiltins s.gfd_name}
+instance replaceBuiltins GenericConsDescriptor
+where
+       replaceBuiltins s = {s & gcd_name=replaceBuiltins s.gcd_name, gcd_type=replaceBuiltins s.gcd_type}
+instance replaceBuiltins GenericTypeDefDescriptor
+where
+       replaceBuiltins s = {s & gtd_name=replaceBuiltins s.gtd_name}
+instance replaceBuiltins GenericRecordDescriptor
+where
+       replaceBuiltins s = {s & grd_name=replaceBuiltins s.grd_name, grd_type=replaceBuiltins s.grd_type}
+instance replaceBuiltins String
+where
+       replaceBuiltins a = fromMaybe a $ lookup a predef
+instance replaceBuiltins Type
+where
+       replaceBuiltins (TyRef a) = TyRef (replaceBuiltins a)
+       replaceBuiltins (TyArrow l r) = TyArrow (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins (TyArray s a) = TyArray s (replaceBuiltins a)
+       replaceBuiltins (TyUList s a) = TyUList s (replaceBuiltins a)
+       replaceBuiltins (TyNewType i j a) = TyNewType (replaceBuiltins i) (replaceBuiltins j) (replaceBuiltins a)
+       replaceBuiltins (TyObject i cs) = TyObject (replaceBuiltins i) [(replaceBuiltins i, map replaceBuiltins fs)\\(i, fs)<-cs]
+       replaceBuiltins (TyRecord j fs) = TyRecord (replaceBuiltins j) [(replaceBuiltins i, replaceBuiltins a)\\(i, a)<-fs]
+       replaceBuiltins t = t
+instance replaceBuiltins GType
+where
+       replaceBuiltins (GTyEither l r) = GTyEither (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins (GTyPair l r) = GTyPair (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins (GTyArrow l r) = GTyArrow (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins (GTyArray s a) = GTyArray s (replaceBuiltins a)
+       replaceBuiltins (GTyUList s a) = GTyUList s (replaceBuiltins a)
+       replaceBuiltins (GTyObject i a) = GTyObject (replaceBuiltins i) (replaceBuiltins a)
+       replaceBuiltins (GTyRecord i a) = GTyRecord (replaceBuiltins i) (replaceBuiltins a)
+       replaceBuiltins (GTyCons i a) = GTyCons (replaceBuiltins i) (replaceBuiltins a)
+       replaceBuiltins (GTyField i a) = GTyField (replaceBuiltins i) (replaceBuiltins a)
+       replaceBuiltins (GTyRef a) = GTyRef (replaceBuiltins a)
+       replaceBuiltins a = a
+instance replaceBuiltins GenType
+where
+       replaceBuiltins (GenTypeCons a) = GenTypeCons (replaceBuiltins a)
+       replaceBuiltins (GenTypeApp l r) = GenTypeApp (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins (GenTypeArrow l r) = GenTypeArrow (replaceBuiltins l) (replaceBuiltins r)
+       replaceBuiltins a = a
+
+predef :: [(String, String)]
+predef =:
+       [ ("_List", "[]"), ("_Cons", "(:)"), ("_Nil", "[]")
+       , ("_!List", "[! ]"), ("_!Cons", "(:)"), ("_!Nil", "[! ]")
+       , ("_List!", "[ !]"), ("_Cons!", "(:)"), ("_Nil!", "[ !]")
+       , ("_!List!", "[!!]"), ("_!Cons!", "(:)"), ("_!Nil!", "[ !]")
+       , ("_#List", "[#]"), ("_#Cons", "(:)"), ("_#Nil", "[#]")
+       , ("_#List!", "[#!]"), ("_#Cons!", "(:)"), ("_#Nil!", "[#!]")
+       , ("_Array", "{}"), ("_!Array", "{!}"), ("_#Array", "{#}"), ("_32#Array", "{32#}")
+       , ("_Unit", "()")
+       :[("_Tuple" +++ toString i, "(" +++ createArray i ',' +++")")\\i<-[2..32]]]
+
+generic type a :: Box GType a
+gType{|UNIT|} = box GTyUnit
+gType{|EITHER|} l r = box $ GTyEither (unBox l) (unBox r)
+gType{|PAIR|} l r = box $ GTyPair (unBox l) (unBox r)
+gType{|CONS of gcd|} a = box $ GTyCons gcd $ unBox a
+gType{|FIELD of gfd|} a = box $ GTyField gfd $ unBox a
+gType{|OBJECT of gtd|} a = box $ GTyObject gtd $ unBox a
+gType{|RECORD of grd|} a = box $ GTyRecord grd $ unBox a
+gType{|Int|} = box $ GTyBasic BTInt
+gType{|Bool|} = box $ GTyBasic BTBool
+gType{|Real|} = box $ GTyBasic BTReal
+gType{|Char|} = box $ GTyBasic BTChar
+gType{|World|} = box $ GTyBasic BTWorld
+gType{|Dynamic|} = box $ GTyBasic BTDynamic
+gType{|File|} = box $ GTyBasic BTFile
+gType{|(->)|} l r = box $ GTyArrow (unBox l) (unBox r)
+gType{|[#]|} a = box $ GTyUList ULLazy $ unBox a
+gType{|[#!]|} a = box $ GTyUList ULStrict $ unBox a
+gType{|{}|} a = box $ GTyArray ALazy $ unBox a
+gType{|{!}|} a = box $ GTyArray AStrict $ unBox a
+gType{|{#}|} a = box $ GTyArray AUnboxed $ unBox a
+gType{|{32#}|} a = box $ GTyArray APacked $ unBox a
+derive gType ?#, ?, ?^
+derive gType [], [! ], [ !], [!!]
+derive gType (), (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)
diff --git a/gengen/Data/GenType/CType.dcl b/gengen/Data/GenType/CType.dcl
new file mode 100644 (file)
index 0000000..b79c58e
--- /dev/null
@@ -0,0 +1,9 @@
+definition module Data.GenType.CType
+
+from Data.Either import :: Either
+from Data.GenType import :: Type
+
+/**
+ * generate typedefs for the types grouped by strongly connected components
+ */
+typedefs :: [[Type]] -> Either String [String]
diff --git a/gengen/Data/GenType/CType.icl b/gengen/Data/GenType/CType.icl
new file mode 100644 (file)
index 0000000..d8ba99b
--- /dev/null
@@ -0,0 +1,126 @@
+implementation module Data.GenType.CType
+
+import Control.Applicative
+import Control.Monad => qualified join
+import Control.Monad.State
+import Control.Monad.Trans
+import Data.Either
+import Data.Maybe
+import Data.Func
+import Data.Functor
+import Data.List
+import StdEnv
+import Data.GenType
+import Text
+
+typedefs :: [[Type]] -> Either String [String]
+typedefs ts = flatten <$> evalStateT (mapM typedefgroup ts) { tinfo = [] }
+
+:: TDMonad :== StateT TDState (Either String) [String]
+:: TDState = { tinfo :: [(String, Bool)] }
+
+typedefgroup :: [Type] -> TDMonad
+typedefgroup ts
+       =   flatten
+       <$  mapM (\t->modify \s->{s & tinfo=[(typeName t, if (ts =: [_]) (maybeInfinite t) True):s.tinfo]}) ts
+       <*> mapM (\t->typedef t >>= post ["\n"]) ts
+where
+       maybeInfinite :: Type -> Bool
+       maybeInfinite t = False
+
+printTypeName :: String -> TDMonad
+printTypeName tname = maybe [tname] (\b->[tname, " ", if b "*" ""])
+       <$> gets \s->lookup tname s.tinfo
+
+pre :: [String] (m [String]) -> m [String] | Monad m
+pre t s = ((++)t) <$> s
+
+post :: [String] [String] -> m [String] | pure m
+post t s = pure (s ++ t)
+
+import StdDebug
+typedef :: Type -> TDMonad
+typedef (TyRef s) = printTypeName s
+typedef (TyBasic BTInt) = pure [IF_INT_64_OR_32 "int64_t" "int32_t"]
+typedef (TyBasic BTChar) = pure ["char"]
+typedef (TyBasic BTReal) = pure ["double"]
+typedef (TyBasic BTBool) = pure ["bool"]
+typedef (TyArray _ a) = pre ["*"] $ typedef a
+typedef t=:(TyNewType ti ci a)
+       = pre ["// ", toString t, "\n", "typedef ", ti.gtd_name, " "] $ fmtFields 0 ci.gcd_type [""]
+typedef t=:(TyRecord ti fs) = pre
+       [ "// ", toString t, "\n", "struct ", ti.grd_name, " {\n"]
+       $ fmtFields 1 ti.grd_type [fi.gfd_name\\(fi, _)<-fs]
+       >>= post ["};\n"]
+//Enumeration
+typedef t=:(TyObject ti fs)
+       | and [t =: [] \\ (_, t)<-fs] = pure
+               [ "// ", toString t, "\n", "enum ", ti.gtd_name, " {"
+               , join ", " [ci.gcd_name\\(ci, _)<-fs], "};\n"]
+//Single constructor, single field (box)
+typedef t=:(TyObject ti [(ci, [ty])]) = pre
+       ["// ", toString t, "\n", "typedef ", ti.gtd_name, " "] $ fmtFields 0 ci.gcd_type [""]
+//Single constructor
+typedef t=:(TyObject ti [(ci, ts)]) = pre
+       [ "// ", toString t, "\n", "struct ", ti.gtd_name, " {\n"]
+       $ fmtFields 1 ci.gcd_type ["f" +++ toString i\\i<-indexList ts]
+       >>= post ["};\n"]
+//Complex adt
+typedef t=:(TyObject ti fs) = pre
+       [ "// ", toString t, "\nstruct ", ti.gtd_name, " {\n"
+       , "\tenum {", join ", " [ci.gcd_name\\(ci, _)<-fs], "} cons;\n"
+       , "\tstruct {\n"]
+       $ mapM fmtCons fs
+       >>= post ["\t} data;\n};\n"] o flatten
+where
+       fmtCons :: (GenericConsDescriptor, [Type]) -> TDMonad
+       fmtCons (ci, []) = pure []
+       fmtCons (ci, ts) = pre ["\t\tstruct {\n"]
+               $ fmtFields 3 ci.gcd_type ["f" +++ toString i\\i<-indexList ts]
+               >>= post ["\t\t} ", ci.gcd_name, ";\n"]
+typedef t = pure []//liftT $ Left $ toString t +++ " not implemented"
+
+fmtFields :: Int GenType [String] -> TDMonad
+fmtFields i _ [] = pure []
+fmtFields i (GenTypeArrow l r) [x:xs] = fmtField i x l >>= flip pre (fmtFields i r xs)
+
+fmtField :: Int String GenType -> TDMonad
+fmtField i x (GenTypeCons a) = pre [createArray i '\t'] $ printTypeName a >>= post [x,";\n"]
+fmtField i x (GenTypeVar a) = fmtField i x (GenTypeCons "void *")
+fmtField i x (GenTypeApp l r) = fmtField i x l
+fmtField i x t=:(GenTypeArrow _ _) = liftT $ Left $ toString t +++ " unsupported"
+//typedef t=:(TyRecord ti fs) = pre
+//     [ "// ", toString t, "\n", "struct ", i.grd_name, " {\n"]
+//     $ mapM (fmtField 1) [(i.gfd_name, t)\\(i, t)<-fs]
+//     >>= post ["};\n"] o flatten
+////Enumeration
+//typedef t=:(TyObject i fs)
+//     | and [t =: [] \\ (_, t)<-fs] = pure
+//             [ "// ", toString t, "\n", "enum ", i.gtd_name, " {"
+//             , join ", " [i.gcd_name\\(i, _)<-fs], "};\n"]
+////Single constructor, single field (box)
+//typedef t=:(TyObject i [(j, [ty])]) = pre
+//     ["// ", toString t, "\n", "typedef ", i.gtd_name, " "] $ typedef ty
+////Single constructor
+//typedef t=:(TyObject i [(j, ts)]) = pre
+//     [ "// ", toString t, "\n", "struct ", i.gtd_name, " {\n"]
+//     $ mapM (fmtField 1) (numberConsData ts)
+//     >>= post ["};\n"] o flatten
+////Complex adt
+//typedef t=:(TyObject i fs) = pre
+//     [ "// ", toString t, "\nstruct ", i.gtd_name, " {\n"
+//     , "\tenum {", join ", " [i.gcd_name\\(i, _)<-fs], "} cons;\n"
+//     , "\tstruct {\n"]
+//     $ mapM fmtCons fs
+//     >>= post ["\t} data;\n};\n"] o flatten
+//where
+//     fmtCons :: (GenericConsDescriptor, [Type]) -> TDMonad
+//     fmtCons (i, []) = pure []
+//     fmtCons (i, ts) = pre ["\t\tstruct {\n"]
+//             $ mapM (fmtField 3) (numberConsData ts)
+//             >>= post ["\t\t} ", i.gcd_name, ";\n"] o flatten
+
+numberConsData ts = [("f"+++toString i, t)\\i<-[0..] & t<-ts]
+
+//fmtField :: Int (String, Type) -> TDMonad
+//fmtField indent (i, t) = pre [createArray indent '\t'] $ typedef t >>= post [" ", i, ";\n"]
diff --git a/gengen/gen.icl b/gengen/gen.icl
deleted file mode 100644 (file)
index ac1d0b3..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-module gen
-
-import Control.Applicative
-import Control.Monad => qualified join
-import Control.Monad.State
-import Control.Monad.Writer
-:mport Control.Monad.Trans
-import Data.Either
-import Data.Func
-import Data.Functor
-import Data.Functor.Identity
-import Data.Generics
-import Data.List
-import Data.Maybe
-import Data.Monoid
-import Data.Tuple
-import StdEnv, StdGeneric
-import Text
-
-:: Box b a =: Box b
-derive bimap Box
-unBox (Box b) :== b
-box b :== Box b
-reBox x :== box (unBox x)
-
-:: GType
-       = GTyBasic String
-       | GTyArrow GType GType
-       | GTyArray ArrayType GType
-       | GTyUList UListType GType
-       | GTyUnit
-       | GTyEither GType GType
-       | GTyPair GType GType
-       | GTyCons GenericConsDescriptor GType
-       | GTyField GenericFieldDescriptor GType
-       | GTyObject GenericTypeDefDescriptor GType
-       | GTyRecord GenericRecordDescriptor GType
-:: ArrayType = AStrict | ALazy | AUnboxed | A32Unboxed
-:: UListType = ULLazy | ULStrict
-instance == UListType
-where
-       (==) ULLazy ULLazy = True
-       (==) ULStrict ULStrict = True
-       (==) _ _ = False
-instance == ArrayType
-where
-       (==) AStrict AStrict = True
-       (==) ALazy ALazy = True
-       (==) AUnboxed AUnboxed = True
-       (==) A32Unboxed A32Unboxed = True
-       (==) _ _ = False
-
-instance == GType where (==) x y = gTypeEqShallow 999 x y
-gTypeEqShallow :: Int GType GType -> Bool
-gTypeEqShallow i _ _
-       | i < 0 = True
-gTypeEqShallow _ (GTyBasic i) (GTyBasic j) = i == j
-gTypeEqShallow i (GTyArrow l1 r1) (GTyArrow l2 r2) = gTypeEqShallow (dec i) l1 l2 && gTypeEqShallow (dec i) r1 r2
-gTypeEqShallow i (GTyArray s1 a1) (GTyArray s2 a2) = s1 == s2 && gTypeEqShallow (dec i) a1 a2
-gTypeEqShallow i (GTyUList s1 a1) (GTyUList s2 a2) = s1 == s2 && gTypeEqShallow (dec i) a1 a2
-gTypeEqShallow _ GTyUnit GTyUnit = True
-gTypeEqShallow i (GTyEither l1 r1) (GTyEither l2 r2) = gTypeEqShallow i l1 l2 && gTypeEqShallow i r1 r2
-gTypeEqShallow i (GTyPair l1 r1) (GTyPair l2 r2) = gTypeEqShallow i l1 l2 && gTypeEqShallow i r1 r2
-gTypeEqShallow i (GTyCons i1 a1) (GTyCons i2 a2) = i1.gcd_name == i2.gcd_name && gTypeEqShallow i a1 a2
-gTypeEqShallow i (GTyField i1 a1) (GTyField i2 a2)
-       = i1.gfd_name == i2.gfd_name && i1.gfd_cons.grd_name == i2.gfd_cons.grd_name && gTypeEqShallow i a1 a2
-gTypeEqShallow i (GTyObject i1 a1) (GTyObject i2 a2)
-       = i1.gtd_name == i2.gtd_name && gTypeEqShallow (dec i) a1 a2
-gTypeEqShallow i (GTyRecord i1 a1) (GTyRecord i2 a2)
-       = i1.grd_name == i2.grd_name && gTypeEqShallow (dec i) a1 a2
-gTypeEqShallow _ _ _ = False
-
-class print a :: a [String] -> [String]
-instance print Bool where print s c = [toString s:c]
-instance print Int where print s c = [toString s:c]
-instance print Char where print s c = [toString s:c]
-instance print String where print s c = [s:c]
-instance print UListType
-where
-       print ULStrict c = ["!":c]
-       print ULLazy c = c
-instance print ArrayType
-where
-       print AStrict c = ["!":c]
-       print AUnboxed c = ["#":c]
-       print A32Unboxed c = ["32#":c]
-       print ALazy c = c
-instance print GType
-where
-       print (GTyBasic s) c = [s:c]
-       print (GTyArrow l r) c = ["((->)":print l [" ":print r [")":c]]]
-       print (GTyArray s a) c = ["{":print s $ print a ["}":c]]
-       print (GTyUList s a) c = ["[#":print s $ print s ["]":c]]
-       print GTyUnit c = ["UNIT":c]
-       print (GTyEither l r) c = ["(EITHER ":print l [" ":print r [")":c]]]
-       print (GTyPair l r) c = ["(PAIR ":print l [")":c]]
-       print (GTyCons i a) c = ["(CONS ", i.gcd_name, " ":print a [")":c]]
-       print (GTyField i a) c = ["(FIELD ", i.gfd_name, " ":print a [")":c]]
-       print (GTyObject i a) c = ["(OBJECT ", i.gtd_name, " ":print a [")":c]]
-       print (GTyRecord i a) c = ["(RECORD ", i.grd_name, " ":print a [")":c]]
-
-:: Type
-       = TyBasic String
-       | TyArrow Type Type
-       | TyArray ArrayType Type
-       | TyUList UListType Type
-       | TyNewType GenericTypeDefDescriptor GenericConsDescriptor Type
-       | TyObject GenericTypeDefDescriptor [(GenericConsDescriptor, [Type])]
-       | TyRecord GenericRecordDescriptor [(GenericFieldDescriptor, Type)]
-instance == Type
-where
-       (==) (TyBasic a1) (TyBasic a2) = a1 == a2
-       (==) (TyArrow l1 r1) (TyArrow l2 r2) = l1 == l2 && r1 == r2
-       (==) (TyArray s1 a1) (TyArray s2 a2) = s1 == s2 && a1 == a2
-       (==) (TyUList s1 a1) (TyUList s2 a2) = s1 == s2 && a1 == a2
-       (==) (TyNewType i1 j1 a1) (TyNewType i2 j2 a2)
-               = i1.gtd_name == i2.gtd_name && a1 == a2
-       (==) (TyObject i1 a1) (TyObject i2 a2)
-               = i1.gtd_name == i2.gtd_name && length a1 == length a2
-               && and [l1.gcd_name == l2.gcd_name && t1 == t2\\(l1, t1)<-a1 & (l2, t2)<-a2]
-       (==) (TyRecord i1 a1) (TyRecord i2 a2)
-               = i1.grd_name == i2.grd_name && length a1 == length a2
-               && and [l1.gfd_name == l2.gfd_name && t1 == t2\\(l1, t1)<-a1 & (l2, t2)<-a2]
-       (==) _ _ = False
-
-predef :: [(String, String)]
-predef =:
-       [("_List", "[]"), ("_!List", "[! ]"), ("_List!", "[ !]"), ("_!List!", "[!!]")
-       ,("_#List", "[#]"), ("_#List!", "[#!]")
-       ,("_Array", "{}"), ("_!Array", "{!}"), ("_#Array", "{#}")
-       :[("_Tuple" +++ toString i, "(" +++ createArray i ',' +++")")\\i<-[2..32]]]
-
-translateType :: String -> String
-translateType s = maybe s id $ lookup s predef
-
-instance print Type
-where
-       print (TyBasic s) c = [translateType s:c]
-       print (TyArrow l r) c = print l [" -> ":print r c]
-       print (TyArray s a) c = ["{":print s ["}":print a c]]
-       print (TyUList s a) c = ["[#":print s ["]":print a c]]
-       print (TyNewType i j cons) c = pTyVars i.gtd_name i.gtd_arity
-               [": ", j.gcd_name, " ":print (nttype j.gcd_type) c]
-       where nttype (GenTypeArrow l r) = l
-       print (TyRecord i fields) c = pTyVars i.grd_name i.grd_type_arity
-               [" {":isperse ", " (pField (\i c->[i.gfd_name, " :: ":c]) fields i.grd_type) ["}":c]]
-       print (TyObject i conses) c = pTyVars i.gtd_name i.gtd_arity
-                       $ [" ":isperse " | " (map pCons conses) c]
-       where
-               pCons :: (GenericConsDescriptor, [Type]) [String] -> [String]
-               pCons (i, ts) c = n [" ":isperse " " (pField (\_->id) [(i, t)\\t<-ts] i.gcd_type) c]
-               where
-                       n c = case i.gcd_prio of
-                               GenConsNoPrio = [i.gcd_name:c]
-                               GenConsPrio a s = ["(",i.gcd_name,") infix",case a of
-                                       GenConsAssocRight = "r";
-                                       GenConsAssocLeft = "l"
-                                       _ = "", " ":print s c]
-
-pTyVars :: String Int [String] -> [String]
-pTyVars ty arity c = [":: ", ty, " ":isperse " " (map print ['a'..'a'+toChar (arity-1)]) [" =":c]]
-
-pField :: (a [String] -> [String]) [(a, Type)] GenType -> [[String] -> [String]]
-pField pre [] _ = []
-pField pre [(i, t):xs] (GenTypeArrow l r) = [pre i o print l:pField pre xs r]
-
-instance == GenType
-where
-       (==) (GenTypeVar i) (GenTypeVar j) = i == j
-       (==) (GenTypeApp l1 r1) (GenTypeApp l2 r2) = l1 == l2 && r1 == r2
-       (==) (GenTypeCons i) (GenTypeCons j) = i == j
-       (==) (GenTypeArrow l1 r1) (GenTypeArrow l2 r2) = l1 == l2 && r1 == r2
-       (==) _ _ = False
-instance print GenType
-where
-       print (GenTypeVar i) c = print (['a'..] !! i) c
-       print t=:(GenTypeApp _ _) c = ["(":isperse " " (collectApps t []) [")":c]]
-       where
-               collectApps (GenTypeApp l r) c = collectApps l [print r:c]
-               collectApps a c = [print a:c]
-       print (GenTypeCons s) c = [translateType s:c]
-       print (GenTypeArrow l r) c = ["(":print l [" -> ":print r [")":c]]]
-
-isperse :: a [[a] -> [a]] [a] -> [a]
-isperse s m c = foldr id c $ intersperse (\c->[s:c]) m
-
-gTypeToType :: GType -> Maybe Type
-gTypeToType (GTyBasic a) = pure $ TyBasic a
-gTypeToType (GTyArrow l r) = TyArrow <$> gTypeToType l <*> gTypeToType r
-gTypeToType (GTyArray s a) = TyArray s <$> gTypeToType a
-gTypeToType (GTyUList s a) = TyUList s <$> gTypeToType a
-gTypeToType (GTyRecord i t) = TyRecord i <$> gtrec t
-where
-       gtrec (GTyField i t) = (\x->[(i, x)]) <$> gTypeToType t
-       gtrec (GTyPair l r) = (++) <$> gtrec l <*> gtrec r
-       gtrec _ = Nothing
-gTypeToType (GTyObject i t)
-       | i.gtd_num_conses == 0 = TyNewType i (hd i.gtd_conses) <$> gTypeToType t
-                               = TyObject i <$> gtobj t
-where
-       gtobj :: GType -> Maybe [(GenericConsDescriptor, [Type])]
-       gtobj (GTyEither l r) = (++) <$> gtobj l <*> gtobj r
-       gtobj (GTyCons i a) = (\x->[(i, x)]) <$> gtcons a
-       gtobj _ = Nothing
-       
-       gtcons :: GType -> Maybe [Type]
-       gtcons GTyUnit = pure []
-       gtcons (GTyPair l r) = (++) <$> gtcons l <*> gtcons r
-       gtcons t = (\x->[x]) <$> gTypeToType t
-
-:: FlatMonad :== State FMState GType
-:: FMState = { objects :: [String], otypes :: [GType], types :: [GType], depth :: Int}
-flattenGType :: GType -> (GType, [GType])
-flattenGType ot = appSnd (\x->x.types) $ runState (mkf ot) {objects=[], types=[], otypes=[], depth=10}
-where
-       write :: (a GType -> GType) a GType -> FlatMonad | genericDescriptorName a
-       write cons t a = modify (\x->{x & depth=dec x.depth}) >>| getState >>= \s
-               //We have seen the type but it might've had different arguments
-               | isMember name s.objects
-                       //We have not seen this configuration
-                       | isEmpty [ot \\ ot<-s.otypes | gTypeEqShallow s.depth ot a]
-                               = mkf a *> r
-                       //If not, just return the basictype
-                               = r
-               //We have not seen the type so we add, calculate and output it
-               = cons t <$ modify (\x->{x & otypes=[a:x.otypes], objects=[name:x.objects]}) <*> mkf a
-                       >>= \ty->modify (\x->{x & types=[ty:x.types]}) >>| r
-       where
-               name = genericDescriptorName t
-               r = pure $ GTyBasic name
-
-       mkf :: GType -> FlatMonad
-       mkf (GTyObject t a) = write GTyObject t a
-       mkf (GTyRecord t a) = write GTyRecord t a
-       mkf (GTyEither l r) = GTyEither <$> mkf l <*> mkf r
-       mkf (GTyPair l r) = GTyPair <$> mkf l <*> mkf r
-       mkf (GTyCons i a) = GTyCons i <$> mkf a
-       mkf (GTyField i a) = GTyField i <$> mkf a
-       mkf (GTyArrow l r) = GTyArrow <$> mkf l <*> mkf r
-       mkf (GTyArray s a) = GTyArray s <$> mkf a
-       mkf (GTyUList s a) = GTyUList s <$> mkf a
-       mkf GTyUnit = pure GTyUnit
-       mkf a=:(GTyBasic _) = pure a
-
-generic type a :: Box GType a
-type{|Int|} = box $ GTyBasic "Int"
-type{|Bool|} = box $ GTyBasic "Bool"
-type{|Real|} = box $ GTyBasic "Real"
-type{|Char|} = box $ GTyBasic "Char"
-type{|World|} = box $ GTyBasic "World"
-type{|Dynamic|} = box $ GTyBasic "Dynamic"
-type{|(->)|} l r = box $ GTyArrow (unBox l) (unBox r)
-type{|[#]|} a = box $ GTyUList ULLazy $ unBox a
-type{|[#!]|} a = box $ GTyUList ULStrict $ unBox a
-type{|{}|} a = box $ GTyArray ALazy $ unBox a
-type{|{!}|} a = box $ GTyArray AStrict $ unBox a
-type{|{#}|} a = box $ GTyArray AUnboxed $ unBox a
-type{|{32#}|} a = box $ GTyArray A32Unboxed $ unBox a
-
-type{|UNIT|} = box GTyUnit
-type{|EITHER|} l r = box $ GTyEither (unBox l) (unBox r)
-type{|PAIR|} l r = box $ GTyPair (unBox l) (unBox r)
-type{|CONS of gcd|} a = box $ GTyCons gcd $ unBox a
-type{|FIELD of gfd|} a = box $ GTyField gfd $ unBox a
-type{|OBJECT of gtd|} a = box $ GTyObject gtd $ unBox a
-type{|RECORD of grd|} a = box $ GTyRecord grd $ unBox a
-
-derive type ?#, ?, ?^
-derive type [], [! ], [ !], [!!]
-derive type (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)
-derive type Either, Maybe, T, R, Frac, Tr, Fix
-
-:: T a =: T2 a
-:: R a = {f1 :: Maybe (R a), f2 :: Bool, f3 :: T a, f4 :: Char -> Dynamic,
-       f5 :: [[([#Int], [#Int!], [!Int!], [!Int], [Int!], {!Int}, {R Bool}, {#Char})]]/*({!Int}, {#Char}, {R Bool})*/}
-
-:: Tr m b= Tr (m Int b)
-
-:: Frac a = (/.) infixl 7 a a 
-
-//Start :: [String]
-//Start = foldr (\i c->print i ["\n":c]) [] $ catMaybes $ map gTypeToType $ flattenGType $ unBox t
-Start = foldr (\i c->print i ["\n":c]) []
-       $ catMaybes
-       $ map gTypeToType
-       $ snd $ flattenGType
-       $ unBox t
-
-:: Fix f = Fix (f (Fix f))
-
-//t :: Box GType (?# Int)
-//t :: Box GType (Maybe [Maybe (Either Bool String)])
-//t :: Box GType [Either [[!Int]] [[![Bool]]]]
-t :: Box GType ([Either (R (T *World)) (Frac Real)], Tr Either Bool, Fix Maybe)
-t = type{|*|}
diff --git a/gengen/gengen.hs b/gengen/gengen.hs
new file mode 100644 (file)
index 0000000..7b44a72
--- /dev/null
@@ -0,0 +1,12 @@
+{-# LANGUAGE GADTs, DeriveGeneric, DefaultSignatures, TypeOperators #-}
+module Main where
+
+import GHC.Generics
+
+data GType a where
+    Unit :: GType (U1 p)
+    Product :: (GType a) (GType b) -> GType ((a :*: b) p)
+    Sum :: (GType a) (GType b) -> GType (a :+: b)
+
+
+main = putStrLn ""
diff --git a/gengen/test.hs b/gengen/test.hs
new file mode 100644 (file)
index 0000000..72985ff
--- /dev/null
@@ -0,0 +1,10 @@
+{-# LANGUAGE GADTs #-}
+module Main where
+
+data GType 
+data GType a where
+    Unit :: GType UNIT
+    Add :: (Num a, Eq a) => Expr a -> Expr a -> Expr a
+    Ext :: (Eval v, Print v, Opt v, Typeable v) => v a -> Expr a
+
+main = putStrLn ""
index 86a0281..27fcd7d 100644 (file)
@@ -2,52 +2,127 @@ module test
 
 import StdEnv, StdGeneric, StdMaybe
 
-import Data.Either, Data.Func
-
-:: Box b a =: Box b
-derive bimap Box
-unBox (Box b) :== b
-box b :== Box b
-reBox x :== box (unBox x)
-
-:: GGFuns st a =
-       { int    :: st -> Either String (Int, st)
-       , bool   :: st -> Either String (Bool, st)
-       , real   :: st -> Either String (Real, st)
-       , char   :: st -> Either String (Char, st)
-
-       , unit   :: st -> Either String (UNIT, st)
-//     , cons   :: (st -> Either String (a, st)) GenericConsDescriptor st -> Either String (CONS b, st)
-//     , field  :: (st -> Either String (a, st)) GenericFieldDescriptor st -> Either String (FIELD b, st)
-//     , record :: (st -> Either String (a, st)) GenericRecordDescriptor st -> Either String (RECORD b, st)
-//     , object :: (st -> Either String (a, st)) GenericTypeDefDescriptor st -> Either String (OBJECT b, st)
-//     , pair   :: (st -> Either String (al, st)) (st -> Either String (br, st)) st -> Either String (PAIR bl br, st)
-//     , either :: (st -> Either String (al, st)) (st -> Either String (br, st)) st -> Either String (EITHER bl br, st)
-       }
-
-ggcast :: (GGFuns st a) -> GGFuns st c
-ggcast d = {d & int=d.int}
-
-generic gGeneric a :: (GGFuns st a) st -> Either String (a, st)
-
-gGeneric{|Int|} d st = d.int st
-gGeneric{|Bool|} d st = d.bool st
-gGeneric{|Real|} d st = d.real st
-gGeneric{|Char|} d st = d.char st
-
-gGeneric{|UNIT|} d st = d.unit st
-//gGeneric{|CONS of gcd|} f d st = d.cons (f (ggcast d)) gcd st
-//gGeneric{|FIELD of gfd|} f d st = d.field (f (ggcast d)) gfd st
-//gGeneric{|OBJECT of gtd|} f d st = d.object (f (ggcast d)) gtd st
-//gGeneric{|RECORD of grd|} f d st = d.record (f (ggcast d)) grd st
-//gGeneric{|PAIR|} fl fr d st = d.pair (fl (ggcast d)) (fr (ggcast d)) st
-//gGeneric{|EITHER|} fl fr d st = d.either (fl (ggcast d)) (fr (ggcast d)) st
-
-gDefault :: a | gGeneric{|*|} a
-gDefault = fromRight o snd $
-       { int=basic 0, bool=basic True, real=basic 0.0, char=basic 'a', unit=basic UNIT
-       }
-where
-       basic c = \_->Right (c, ())
-
-Start = 42
+import Data.Func
+import Data.Functor
+import Data.List
+import Data.Tuple
+import Data.Bifunctor
+import Control.GenBimap
+import Data.Maybe
+import Data.Either
+
+import Data.GenType
+import Data.GenType.CType
+
+derive gType Either, Maybe, T, R, Frac, Tr, Fix, Odd, Even, SR, List, Enum, NT
+
+:: T a =: T2 a
+:: NT =: NT Int
+:: SR = {f1 :: Int, f2 :: Bool}
+:: R a = {f1 :: Maybe (R a), f2 :: Bool, f3 :: T a, f4 :: Char -> Dynamic,
+       f5 :: [([#Int], [#Int!], [!Int!], [!Int], [Int!])],
+       f6 :: ({!Int}, {R Bool}, {#Char}, {32#Int})/*({!Int}, {#Char}, {R Bool})*/}
+:: Tr m b= Tr (m Int b)
+:: Frac a = (/.) infixl 7 a a 
+:: Fix f = Fix (f (Fix f))
+
+:: List a = Cons a (List a) | Nil
+
+////Start :: [String]
+////Start = foldr (\i c->print i ["\n":c]) [] $ catMaybes $ map gTypeToType $ flattenGType $ unBox t
+//:: Pair a b = Pair a b
+//instance == (Pair a b) | == a where (==) (Pair a1 _) (Pair a2 _) = a1 == a2
+//instance < (Pair a b) | < a where (<) (Pair a1 _) (Pair a2 _) = a1 < a2
+:: Odd a = Odd (Even a) | OddBlurp
+:: Even a = Even (Odd a) | EvenBlurp
+:: Enum = A | B | C
+Start = typedefs
+//     $ map (/*filter (not o isBuiltin) o*/ catMaybes o map gTypeToType)
+//     $ flattenGType
+       $ (\x->[[fromJust x]])
+       $ gTypeToType
+       $ unBox t
+//
+//
+//t :: Box GType (?# Int)
+//t :: Box GType (Maybe [Maybe (Either Bool String)])
+t :: Box GType ([SR], Enum, T Int, NT)
+//t :: Box GType (Tr Either Enum)
+//t :: Box GType (Odd Int, (), [Either (R (T *World)) (Frac Real)], Tr Either Bool, Fix Maybe)
+t = gType{|*|}
+
+//Start = toString t
+//
+//t :: GGType [Int]
+//t = ggType{|*|}
+//
+//:: BM a b =
+//     { ab :: a -> b
+//     , ba :: b -> a
+////   , mab :: A.m: (m a) -> m b
+////   , mba :: A.m: (m b) -> m a
+//     }
+//bm :: BM a a
+//bm = {ab=id, ba=id}//, mab=id, mba=id}
+//
+//:: GGType a
+//     = GGBasicType BasicType
+//     | GGTyRef String
+//     | GGUnit
+//     | E.e:   GGObject (BM a (OBJECT e))   GenericTypeDefDescriptor (GGType e)
+//     | E.e:   GGRecord (BM a (RECORD e))   GenericRecordDescriptor  (GGType e)
+//     | E.e:   GGCons   (BM a (CONS e))     GenericConsDescriptor    (GGType e)
+//     | E.e:   GGField  (BM a (FIELD e))    GenericFieldDescriptor   (GGType e)
+//     | E.l r: GGEither (BM a (EITHER l r)) (GGType l) (GGType r)
+//     | E.l r: GGPair   (BM a (PAIR l r))   (GGType l) (GGType r)
+//     | E.l r: GGArrow  (BM a (l -> r))     (GGType l) (GGType r)
+//
+//instance toString (GGType a)
+//where
+//     toString (GGBasicType t) = toString t
+//     toString GGUnit = "UNIT"
+//     toString (GGObject bm i e) = "(OBJECT " +++ i.gtd_name +++ " " +++ toString e +++ ")"
+//     toString (GGRecord bm i e) = "(RECORD " +++ i.grd_name +++ " " +++ toString e +++ ")"
+//     toString (GGCons bm i e) = "(CONS " +++ i.gcd_name +++ " " +++ toString e +++ ")"
+//     toString (GGField bm i e) = "(FIELD " +++ i.gfd_name +++ " " +++ toString e +++ ")"
+//     toString (GGEither bm l r) = "(EITHER " +++ toString l +++ " " +++ toString r +++ ")"
+//     toString (GGPair bm l r) = "(PAIR " +++ toString l +++ " " +++ toString r +++ ")"
+//
+//ggtypemap :: (.a -> .b) (.b -> .a) u:(GGType .a) -> u:GGType .b
+//ggtypemap ab ba (GGBasicType t) = (GGBasicType t)
+//ggtypemap ab ba GGUnit = GGUnit
+//ggtypemap ab ba (GGObject bm i a) = GGObject {bm & ab=bm.ab o ba, ba=ab o bm.ba} i a
+//ggtypemap ab ba (GGRecord bm i a) = GGRecord {bm & ab=bm.ab o ba, ba=ab o bm.ba} i a
+//ggtypemap ab ba (GGCons bm i a) = GGCons {bm & ab=bm.ab o ba, ba=ab o bm.ba} i a
+//ggtypemap ab ba (GGField bm i a) = GGField {bm & ab=bm.ab o ba, ba=ab o bm.ba} i a
+//ggtypemap ab ba (GGEither bm l r) = GGEither {bm & ab=bm.ab o ba, ba=ab o bm.ba} l r
+//ggtypemap ab ba (GGPair bm l r) = GGPair {bm & ab=bm.ab o ba, ba=ab o bm.ba} l r
+//ggtypemap ab ba (GGArrow bm l r) = GGArrow {bm & ab=bm.ab o ba, ba=ab o bm.ba} l r
+//
+//bimap{|GGType|} ab ba t = ggtypemap ab ba t
+//
+//generic ggType a :: GGType a
+//ggType{|UNIT|} = GGUnit
+//ggType{|OBJECT of gtd|} f = GGObject bm gtd f
+//ggType{|CONS of gcd|} f = GGCons bm gcd f
+//ggType{|RECORD of grd|} f = GGRecord bm grd f
+//ggType{|FIELD of gfd|} f = GGField bm gfd f
+//ggType{|EITHER|} fl fr = GGEither bm fl fr
+//ggType{|PAIR|} fl fr = GGPair bm fl fr
+//
+//ggType{|Int|} = GGBasicType BTInt
+//ggType{|Bool|} =  GGBasicType BTBool
+//ggType{|Real|} = GGBasicType BTReal
+//ggType{|Char|} = GGBasicType BTChar
+//ggType{|World|} = GGBasicType BTWorld
+//ggType{|Dynamic|} = GGBasicType BTDynamic
+//ggType{|File|} = GGBasicType BTFile
+//
+//ggType{|(->)|} fl fr = GGArrow bm fl fr
+////ggType{|[#]|} f = GGUList ULLazy f
+////ggType{|[#!]|} f = GGUList ULStrict f
+////ggType{|{}|} f = GGArray ALazy f
+////ggType{|{!}|} f = GGAray AStrict f
+////ggType{|{#}|} f = GGArray AUnboxed f
+////ggType{|{32#}|} f = GGArray APacked f
+//derive ggType []