diff options
-rw-r--r-- | Definitions.hs | 3 | ||||
-rw-r--r-- | Generate.hs | 25 | ||||
-rw-r--r-- | Language.hs | 56 | ||||
-rw-r--r-- | templates/data.purs.ede | 20 |
4 files changed, 73 insertions, 31 deletions
diff --git a/Definitions.hs b/Definitions.hs index 0423123..743c233 100644 --- a/Definitions.hs +++ b/Definitions.hs | |||
@@ -236,6 +236,7 @@ ir = execWriter $ do | |||
236 | enum_ "Triangles" | 236 | enum_ "Triangles" |
237 | enum_ "LinesAdjacency" | 237 | enum_ "LinesAdjacency" |
238 | enum_ "TrianglesAdjacency" | 238 | enum_ "TrianglesAdjacency" |
239 | deriving_ [Show,Eq] | ||
239 | 240 | ||
240 | data_ "OutputPrimitive" $ do | 241 | data_ "OutputPrimitive" $ do |
241 | enum_ "TrianglesOutput" | 242 | enum_ "TrianglesOutput" |
@@ -247,6 +248,7 @@ ir = execWriter $ do | |||
247 | enum_ "RG" | 248 | enum_ "RG" |
248 | enum_ "RGB" | 249 | enum_ "RGB" |
249 | enum_ "RGBA" | 250 | enum_ "RGBA" |
251 | deriving_ [Show] | ||
250 | 252 | ||
251 | data_ "Blending" $ do | 253 | data_ "Blending" $ do |
252 | enum_ "NoBlending" | 254 | enum_ "NoBlending" |
@@ -282,6 +284,7 @@ ir = execWriter $ do | |||
282 | const_ "IntT" ["ColorArity"] | 284 | const_ "IntT" ["ColorArity"] |
283 | const_ "WordT" ["ColorArity"] | 285 | const_ "WordT" ["ColorArity"] |
284 | enum_ "ShadowT" | 286 | enum_ "ShadowT" |
287 | deriving_ [Show] | ||
285 | 288 | ||
286 | data_ "TextureType" $ do | 289 | data_ "TextureType" $ do |
287 | const_ "Texture1D" ["TextureDataType", Int] | 290 | const_ "Texture1D" ["TextureDataType", Int] |
diff --git a/Generate.hs b/Generate.hs index d4946fb..a701b22 100644 --- a/Generate.hs +++ b/Generate.hs | |||
@@ -4,8 +4,9 @@ import Text.EDE | |||
4 | import Text.EDE.Filters | 4 | import Text.EDE.Filters |
5 | 5 | ||
6 | import Data.HashMap.Strict (HashMap) | 6 | import Data.HashMap.Strict (HashMap) |
7 | import qualified Data.HashMap.Strict as Map | 7 | import qualified Data.HashMap.Strict as HashMap |
8 | import Data.Text (Text) | 8 | import Data.Text (Text) |
9 | import qualified Data.Map as Map | ||
9 | 10 | ||
10 | import Data.Time.Clock | 11 | import Data.Time.Clock |
11 | 12 | ||
@@ -18,17 +19,6 @@ instance Quote [Char] | |||
18 | instance Unquote DataDef | 19 | instance Unquote DataDef |
19 | instance Unquote Type | 20 | instance Unquote Type |
20 | 21 | ||
21 | mylib :: HashMap Text Term | ||
22 | mylib = Map.fromList | ||
23 | -- boolean | ||
24 | [ "hasFieldNames" @: hasFieldNames | ||
25 | , "parens" @: parens | ||
26 | , "constType" @: constType | ||
27 | , "hsType" @: hsType | ||
28 | , "psType" @: psType | ||
29 | ] | ||
30 | |||
31 | |||
32 | main :: IO () | 22 | main :: IO () |
33 | main = do | 23 | main = do |
34 | irHs <- eitherParseFile "templates/data.hs.ede" | 24 | irHs <- eitherParseFile "templates/data.hs.ede" |
@@ -45,6 +35,17 @@ main = do | |||
45 | , "moduleName" .= name | 35 | , "moduleName" .= name |
46 | , "dateTime" .= dt | 36 | , "dateTime" .= dt |
47 | ] | 37 | ] |
38 | aliasMap = Map.fromList [(n,t) | TypeAlias n t <- def] | ||
39 | mylib :: HashMap Text Term | ||
40 | mylib = HashMap.fromList | ||
41 | -- boolean | ||
42 | [ "hasFieldNames" @: hasFieldNames | ||
43 | , "parens" @: parens | ||
44 | , "constType" @: constType | ||
45 | , "hsType" @: hsType aliasMap | ||
46 | , "psType" @: psType aliasMap | ||
47 | ] | ||
48 | |||
48 | -- Haskell | 49 | -- Haskell |
49 | either error (\x -> writeFile ("out/" ++ name ++ ".hs") $ LText.unpack x) $ irHs >>= (\t -> eitherRenderWith mylib t env) | 50 | either error (\x -> writeFile ("out/" ++ name ++ ".hs") $ LText.unpack x) $ irHs >>= (\t -> eitherRenderWith mylib t env) |
50 | either error (\x -> writeFile ("out/" ++ name ++ "Encode.hs") $ LText.unpack x) $ irEncodeHs >>= (\t -> eitherRenderWith mylib t env) | 51 | either error (\x -> writeFile ("out/" ++ name ++ "Encode.hs") $ LText.unpack x) $ irEncodeHs >>= (\t -> eitherRenderWith mylib t env) |
diff --git a/Language.hs b/Language.hs index 1950c6e..d4cd1b6 100644 --- a/Language.hs +++ b/Language.hs | |||
@@ -6,6 +6,8 @@ import Data.Aeson (ToJSON(..),FromJSON(..)) | |||
6 | import Control.Monad.Writer | 6 | import Control.Monad.Writer |
7 | import Data.String | 7 | import Data.String |
8 | import Data.List | 8 | import Data.List |
9 | import Data.Map (Map) | ||
10 | import qualified Data.Map as Map | ||
9 | 11 | ||
10 | instance IsString Type where | 12 | instance IsString Type where |
11 | fromString a = Data a | 13 | fromString a = Data a |
@@ -14,6 +16,7 @@ data DataDef | |||
14 | = DataDef | 16 | = DataDef |
15 | { dataName :: String | 17 | { dataName :: String |
16 | , constructors :: [ConstructorDef] | 18 | , constructors :: [ConstructorDef] |
19 | , instances :: [Instance] | ||
17 | } | 20 | } |
18 | | TypeAlias | 21 | | TypeAlias |
19 | { aliasName :: String | 22 | { aliasName :: String |
@@ -35,6 +38,11 @@ data Field | |||
35 | } | 38 | } |
36 | deriving (Show,Generic) | 39 | deriving (Show,Generic) |
37 | 40 | ||
41 | data Instance | ||
42 | = Show | ||
43 | | Eq | ||
44 | deriving (Show,Generic) | ||
45 | |||
38 | data Type | 46 | data Type |
39 | = Int | 47 | = Int |
40 | | Int32 | 48 | | Int32 |
@@ -60,8 +68,14 @@ parens a | |||
60 | | 1 == length (words a) = a | 68 | | 1 == length (words a) = a |
61 | | otherwise = "(" ++ a ++ ")" | 69 | | otherwise = "(" ++ a ++ ")" |
62 | 70 | ||
63 | psType :: Type -> String | 71 | type AliasMap = Map String Type |
64 | psType = \case | 72 | |
73 | normalize :: AliasMap -> Type -> Type | ||
74 | normalize aliasMap t@(Data n) = Map.findWithDefault t n aliasMap | ||
75 | normalize _ t = t | ||
76 | |||
77 | psType :: AliasMap -> Type -> String | ||
78 | psType aliasMap = \case | ||
65 | Int -> "Int" | 79 | Int -> "Int" |
66 | Int32 -> "Int32" | 80 | Int32 -> "Int32" |
67 | Word -> "Word" | 81 | Word -> "Word" |
@@ -94,17 +108,18 @@ psType = \case | |||
94 | V4 (V3 Float) -> "M34F" | 108 | V4 (V3 Float) -> "M34F" |
95 | V4 (V4 Float) -> "M44F" | 109 | V4 (V4 Float) -> "M44F" |
96 | 110 | ||
97 | Array t -> "Array " ++ parens (hsType t) | 111 | Array t -> "Array " ++ parens (psType aliasMap t) |
98 | List t -> "List " ++ parens (hsType t) | 112 | List t -> "List " ++ parens (psType aliasMap t) |
99 | Maybe t -> "Maybe " ++ parens (hsType t) | 113 | Maybe t -> "Maybe " ++ parens (psType aliasMap t) |
100 | Map String v -> "StrMap " ++ parens (hsType v) | 114 | Map k v |
101 | Map k v -> "Map " ++ parens (hsType k) ++ " " ++ parens (hsType v) | 115 | | String <- normalize aliasMap k -> "StrMap " ++ parens (psType aliasMap v) |
116 | | otherwise -> "Map " ++ parens (psType aliasMap k) ++ " " ++ parens (psType aliasMap v) | ||
102 | -- user defined | 117 | -- user defined |
103 | Data t -> t | 118 | Data t -> t |
104 | x -> error $ "unknown type: " ++ show x | 119 | x -> error $ "unknown type: " ++ show x |
105 | 120 | ||
106 | hsType :: Type -> String | 121 | hsType :: AliasMap -> Type -> String |
107 | hsType = \case | 122 | hsType aliasMap = \case |
108 | Int -> "Int" | 123 | Int -> "Int" |
109 | Int32 -> "Int32" | 124 | Int32 -> "Int32" |
110 | Word -> "Word" | 125 | Word -> "Word" |
@@ -137,10 +152,10 @@ hsType = \case | |||
137 | V4 (V3 Float) -> "M34F" | 152 | V4 (V3 Float) -> "M34F" |
138 | V4 (V4 Float) -> "M44F" | 153 | V4 (V4 Float) -> "M44F" |
139 | 154 | ||
140 | Array t -> "[" ++ hsType t ++ "]" | 155 | Array t -> "[" ++ hsType aliasMap t ++ "]" |
141 | List t -> "[" ++ hsType t ++ "]" | 156 | List t -> "[" ++ hsType aliasMap t ++ "]" |
142 | Maybe t -> "Maybe " ++ parens (hsType t) | 157 | Maybe t -> "Maybe " ++ parens (hsType aliasMap t) |
143 | Map k v -> "Map " ++ parens (hsType k) ++ " " ++ parens (hsType v) | 158 | Map k v -> "Map " ++ parens (hsType aliasMap k) ++ " " ++ parens (hsType aliasMap v) |
144 | -- user defined | 159 | -- user defined |
145 | Data t -> t | 160 | Data t -> t |
146 | x -> error $ "unknown type: " ++ show x | 161 | x -> error $ "unknown type: " ++ show x |
@@ -154,19 +169,21 @@ constType = head . words . show | |||
154 | 169 | ||
155 | instance ToJSON ConstructorDef | 170 | instance ToJSON ConstructorDef |
156 | instance ToJSON DataDef | 171 | instance ToJSON DataDef |
172 | instance ToJSON Instance | ||
157 | instance ToJSON Field | 173 | instance ToJSON Field |
158 | instance ToJSON Type | 174 | instance ToJSON Type |
159 | 175 | ||
160 | instance FromJSON ConstructorDef | 176 | instance FromJSON ConstructorDef |
161 | instance FromJSON DataDef | 177 | instance FromJSON DataDef |
178 | instance FromJSON Instance | ||
162 | instance FromJSON Field | 179 | instance FromJSON Field |
163 | instance FromJSON Type | 180 | instance FromJSON Type |
164 | 181 | ||
165 | type DDef = Writer [DataDef] | 182 | type DDef = Writer [DataDef] |
166 | type CDef = Writer [ConstructorDef] | 183 | type CDef = Writer ([ConstructorDef],[Instance]) |
167 | 184 | ||
168 | data_ :: forall a . String -> CDef () -> DDef () | 185 | data_ :: forall a . String -> CDef () -> DDef () |
169 | data_ n l = tell [DataDef n $ execWriter l] | 186 | data_ n l = tell [let (c,i) = execWriter l in DataDef n c i] |
170 | 187 | ||
171 | alias_ :: String -> Type -> DDef () | 188 | alias_ :: String -> Type -> DDef () |
172 | alias_ n t = tell [TypeAlias n t] | 189 | alias_ n t = tell [TypeAlias n t] |
@@ -182,14 +199,17 @@ instance IsField Field where | |||
182 | instance IsField Type where | 199 | instance IsField Type where |
183 | toField a = Field "" a | 200 | toField a = Field "" a |
184 | 201 | ||
202 | deriving_ :: [Instance] -> CDef () | ||
203 | deriving_ l = tell (mempty,l) | ||
204 | |||
185 | const_ :: String -> [Type] -> CDef () | 205 | const_ :: String -> [Type] -> CDef () |
186 | const_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]] | 206 | const_ n t = tell ([ConstructorDef n [Field a b | Field a b <- map toField t]],mempty) |
187 | 207 | ||
188 | constR_ :: String -> [Field] -> CDef () | 208 | constR_ :: String -> [Field] -> CDef () |
189 | constR_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]] | 209 | constR_ n t = tell ([ConstructorDef n [Field a b | Field a b <- map toField t]],mempty) |
190 | 210 | ||
191 | enum_ :: String -> CDef () | 211 | enum_ :: String -> CDef () |
192 | enum_ n = tell [ConstructorDef n []] | 212 | enum_ n = tell ([ConstructorDef n []],mempty) |
193 | 213 | ||
194 | v2b = V2 Bool | 214 | v2b = V2 Bool |
195 | v3b = V3 Bool | 215 | v3b = V3 Bool |
diff --git a/templates/data.purs.ede b/templates/data.purs.ede index ccaa7de..a26f292 100644 --- a/templates/data.purs.ede +++ b/templates/data.purs.ede | |||
@@ -2,8 +2,17 @@ | |||
2 | -- {{ dateTime }} | 2 | -- {{ dateTime }} |
3 | 3 | ||
4 | module {{ moduleName }} where | 4 | module {{ moduleName }} where |
5 | import Prelude | ||
6 | import Data.Generic | ||
7 | import Data.Maybe (Maybe(..)) | ||
8 | import Data.StrMap (StrMap(..)) | ||
9 | import Data.Map (Map(..)) | ||
10 | import Data.List (List(..)) | ||
11 | import Linear | ||
5 | 12 | ||
6 | {% for t in definitions %} | 13 | {% for t in dataAndType %} |
14 | {% case t.value | constType %} | ||
15 | {% when "DataDef" %} | ||
7 | data {{ t.value.dataName }}{% for c in t.value.constructors %} | 16 | data {{ t.value.dataName }}{% for c in t.value.constructors %} |
8 | {% if c.value.fields | hasFieldNames %} | 17 | {% if c.value.fields | hasFieldNames %} |
9 | {% if c.first %}={% else %}|{% endif %} {{ c.value.name }} | 18 | {% if c.first %}={% else %}|{% endif %} {{ c.value.name }} |
@@ -13,4 +22,13 @@ data {{ t.value.dataName }}{% for c in t.value.constructors %} | |||
13 | {% else %} | 22 | {% else %} |
14 | {% if c.first %}={% else %}|{% endif %} {{ c.value.name }}{% for f in c.value.fields %} {{ f.value.fieldType | psType | parens }}{% endfor %}{% endif %}{% endfor %} | 23 | {% if c.first %}={% else %}|{% endif %} {{ c.value.name }}{% for f in c.value.fields %} {{ f.value.fieldType | psType | parens }}{% endfor %}{% endif %}{% endfor %} |
15 | 24 | ||
25 | {% when "TypeAlias" %} | ||
26 | type {{ t.value.aliasName }} = {{ t.value.aliasType | psType }} | ||
27 | |||
28 | {% endcase %} | ||
16 | {% endfor %} | 29 | {% endfor %} |
30 | {% for t in definitions %}{% let l = t.value.instances | length %}{% if l > 0 %}{# FIXME!!! #} | ||
31 | derive instance generic{{ t.value.dataName }} :: Generic {{ t.value.dataName }} | ||
32 | instance show{{ t.value.dataName }} :: Show {{ t.value.dataName }} where show = gShow | ||
33 | instance eq{{ t.value.dataName }} :: Eq {{ t.value.dataName }} where eq = gEq | ||
34 | {% endif %}{% endlet %}{% endfor %} | ||