diff options
Diffstat (limited to 'Language.hs')
-rw-r--r-- | Language.hs | 56 |
1 files changed, 38 insertions, 18 deletions
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 |