diff options
Diffstat (limited to 'Language.hs')
-rw-r--r-- | Language.hs | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/Language.hs b/Language.hs new file mode 100644 index 0000000..ae38916 --- /dev/null +++ b/Language.hs | |||
@@ -0,0 +1,236 @@ | |||
1 | {-# LANGUAGE RankNTypes, OverloadedStrings, DeriveGeneric, LambdaCase #-} | ||
2 | module Language where | ||
3 | |||
4 | import GHC.Generics | ||
5 | import Data.Aeson (ToJSON(..),FromJSON(..)) | ||
6 | import Control.Monad.Writer | ||
7 | import Data.String | ||
8 | import Data.List | ||
9 | |||
10 | instance IsString Type where | ||
11 | fromString a = Data a | ||
12 | |||
13 | data DataDef | ||
14 | = DataDef | ||
15 | { dataName :: String | ||
16 | , constructors :: [ConstructorDef] | ||
17 | } | ||
18 | | TypeAlias | ||
19 | { aliasName :: String | ||
20 | , aliasType :: Type | ||
21 | } | ||
22 | deriving (Show,Generic) | ||
23 | |||
24 | data ConstructorDef | ||
25 | = ConstructorDef | ||
26 | { name :: String | ||
27 | , fields :: [Field] | ||
28 | } | ||
29 | deriving (Show,Generic) | ||
30 | |||
31 | data Field | ||
32 | = Field | ||
33 | { fieldName :: String | ||
34 | , fieldType :: Type | ||
35 | } | ||
36 | deriving (Show,Generic) | ||
37 | |||
38 | data Type | ||
39 | = Int | ||
40 | | Int32 | ||
41 | | Word | ||
42 | | Word32 | ||
43 | | Float | ||
44 | | Bool | ||
45 | | String | ||
46 | | V2 Type | ||
47 | | V3 Type | ||
48 | | V4 Type | ||
49 | -- higher order types | ||
50 | | Array Type | ||
51 | | List Type | ||
52 | | Tuple [Type] | ||
53 | | Maybe Type | ||
54 | | Map Type Type | ||
55 | -- user defined | ||
56 | | Data String | ||
57 | deriving (Show,Generic) | ||
58 | |||
59 | parens :: String -> String | ||
60 | parens a | ||
61 | | 1 == length (words a) = a | ||
62 | | otherwise = "(" ++ a ++ ")" | ||
63 | |||
64 | psType :: Type -> String | ||
65 | psType = \case | ||
66 | Int -> "Int" | ||
67 | Int32 -> "Int32" | ||
68 | Word -> "Word" | ||
69 | Word32 -> "Word32" | ||
70 | Float -> "Float" | ||
71 | Bool -> "Bool" | ||
72 | String -> "String" | ||
73 | |||
74 | V2 Int -> "V2I" | ||
75 | V2 Word -> "V2U" | ||
76 | V2 Float -> "V2F" | ||
77 | V2 Bool -> "V2B" | ||
78 | V2 (V2 Float) -> "M22F" | ||
79 | V2 (V3 Float) -> "M32F" | ||
80 | V2 (V4 Float) -> "M42F" | ||
81 | |||
82 | V3 Int -> "V3I" | ||
83 | V3 Word -> "V3U" | ||
84 | V3 Float -> "V3F" | ||
85 | V3 Bool -> "V3B" | ||
86 | V3 (V2 Float) -> "M23F" | ||
87 | V3 (V3 Float) -> "M33F" | ||
88 | V3 (V4 Float) -> "M43F" | ||
89 | |||
90 | V4 Int -> "V4I" | ||
91 | V4 Word -> "V4U" | ||
92 | V4 Float -> "V4F" | ||
93 | V4 Bool -> "V4B" | ||
94 | V4 (V2 Float) -> "M24F" | ||
95 | V4 (V3 Float) -> "M34F" | ||
96 | V4 (V4 Float) -> "M44F" | ||
97 | |||
98 | Array t -> "Array " ++ parens (hsType t) | ||
99 | List t -> "List " ++ parens (hsType t) | ||
100 | Tuple l -> "(" ++ intercalate "," (map hsType l) ++ ")" | ||
101 | Maybe t -> "Maybe " ++ parens (hsType t) | ||
102 | Map String v -> "StrMap " ++ parens (hsType v) | ||
103 | Map k v -> "Map " ++ parens (hsType k) ++ " " ++ parens (hsType v) | ||
104 | -- user defined | ||
105 | Data t -> t | ||
106 | x -> error $ "unknown type: " ++ show x | ||
107 | |||
108 | hsType :: Type -> String | ||
109 | hsType = \case | ||
110 | Int -> "Int" | ||
111 | Int32 -> "Int32" | ||
112 | Word -> "Word" | ||
113 | Word32 -> "Word32" | ||
114 | Float -> "Float" | ||
115 | Bool -> "Bool" | ||
116 | String -> "String" | ||
117 | |||
118 | V2 Int -> "V2I" | ||
119 | V2 Word -> "V2U" | ||
120 | V2 Float -> "V2F" | ||
121 | V2 Bool -> "V2B" | ||
122 | V2 (V2 Float) -> "M22F" | ||
123 | V2 (V3 Float) -> "M32F" | ||
124 | V2 (V4 Float) -> "M42F" | ||
125 | |||
126 | V3 Int -> "V3I" | ||
127 | V3 Word -> "V3U" | ||
128 | V3 Float -> "V3F" | ||
129 | V3 Bool -> "V3B" | ||
130 | V3 (V2 Float) -> "M23F" | ||
131 | V3 (V3 Float) -> "M33F" | ||
132 | V3 (V4 Float) -> "M43F" | ||
133 | |||
134 | V4 Int -> "V4I" | ||
135 | V4 Word -> "V4U" | ||
136 | V4 Float -> "V4F" | ||
137 | V4 Bool -> "V4B" | ||
138 | V4 (V2 Float) -> "M24F" | ||
139 | V4 (V3 Float) -> "M34F" | ||
140 | V4 (V4 Float) -> "M44F" | ||
141 | |||
142 | Array t -> "[" ++ hsType t ++ "]" | ||
143 | List t -> "[" ++ hsType t ++ "]" | ||
144 | Tuple l -> "(" ++ intercalate "," (map hsType l) ++ ")" | ||
145 | Maybe t -> "Maybe " ++ parens (hsType t) | ||
146 | Map k v -> "Map " ++ parens (hsType k) ++ " " ++ parens (hsType v) | ||
147 | -- user defined | ||
148 | Data t -> t | ||
149 | x -> error $ "unknown type: " ++ show x | ||
150 | |||
151 | hasFieldNames :: [Field] -> Bool | ||
152 | hasFieldNames [] = False | ||
153 | hasFieldNames l = all (not . null . fieldName) l | ||
154 | |||
155 | constType :: DataDef -> String | ||
156 | constType = head . words . show | ||
157 | |||
158 | instance ToJSON ConstructorDef | ||
159 | instance ToJSON DataDef | ||
160 | instance ToJSON Field | ||
161 | instance ToJSON Type | ||
162 | |||
163 | instance FromJSON ConstructorDef | ||
164 | instance FromJSON DataDef | ||
165 | instance FromJSON Field | ||
166 | instance FromJSON Type | ||
167 | |||
168 | type DDef = Writer [DataDef] | ||
169 | type CDef = Writer [ConstructorDef] | ||
170 | |||
171 | data_ :: forall a . String -> CDef () -> DDef () | ||
172 | data_ n l = tell [DataDef n $ execWriter l] | ||
173 | |||
174 | alias_ :: String -> Type -> DDef () | ||
175 | alias_ n t = tell [TypeAlias n t] | ||
176 | |||
177 | a #= b = alias_ a b | ||
178 | |||
179 | class IsField a where | ||
180 | toField :: a -> Field | ||
181 | |||
182 | instance IsField Field where | ||
183 | toField a = a | ||
184 | |||
185 | instance IsField Type where | ||
186 | toField a = Field "" a | ||
187 | |||
188 | const_ :: String -> [Type] -> CDef () | ||
189 | const_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]] | ||
190 | |||
191 | constR_ :: String -> [Field] -> CDef () | ||
192 | constR_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]] | ||
193 | |||
194 | enum_ :: String -> CDef () | ||
195 | enum_ n = tell [ConstructorDef n []] | ||
196 | |||
197 | v2b = V2 Bool | ||
198 | v3b = V3 Bool | ||
199 | v4b = V4 Bool | ||
200 | v2u = V2 Word | ||
201 | v3u = V3 Word | ||
202 | v4u = V4 Word | ||
203 | v2i = V2 Int | ||
204 | v3i = V3 Int | ||
205 | v4i = V4 Int | ||
206 | v2f = V2 Float | ||
207 | v3f = V3 Float | ||
208 | v4f = V4 Float | ||
209 | m22 = V2 v2f | ||
210 | m23 = V3 v2f | ||
211 | m24 = V4 v2f | ||
212 | m32 = V2 v3f | ||
213 | m33 = V3 v3f | ||
214 | m34 = V4 v3f | ||
215 | m42 = V2 v4f | ||
216 | m43 = V3 v4f | ||
217 | m44 = V4 v4f | ||
218 | |||
219 | (#::) :: String -> Type -> Field | ||
220 | a #:: b = Field a b | ||
221 | |||
222 | {- | ||
223 | definitions: | ||
224 | ADT | ||
225 | Record | ||
226 | Vector | ||
227 | |||
228 | instances: | ||
229 | Show | ||
230 | Eq | ||
231 | Ord | ||
232 | |||
233 | serialization: | ||
234 | json: encode/decode | ||
235 | other? | ||
236 | -} \ No newline at end of file | ||