summaryrefslogtreecommitdiff
path: root/Language.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Language.hs')
-rw-r--r--Language.hs236
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 #-}
2module Language where
3
4import GHC.Generics
5import Data.Aeson (ToJSON(..),FromJSON(..))
6import Control.Monad.Writer
7import Data.String
8import Data.List
9
10instance IsString Type where
11 fromString a = Data a
12
13data DataDef
14 = DataDef
15 { dataName :: String
16 , constructors :: [ConstructorDef]
17 }
18 | TypeAlias
19 { aliasName :: String
20 , aliasType :: Type
21 }
22 deriving (Show,Generic)
23
24data ConstructorDef
25 = ConstructorDef
26 { name :: String
27 , fields :: [Field]
28 }
29 deriving (Show,Generic)
30
31data Field
32 = Field
33 { fieldName :: String
34 , fieldType :: Type
35 }
36 deriving (Show,Generic)
37
38data 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
59parens :: String -> String
60parens a
61 | 1 == length (words a) = a
62 | otherwise = "(" ++ a ++ ")"
63
64psType :: Type -> String
65psType = \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
108hsType :: Type -> String
109hsType = \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
151hasFieldNames :: [Field] -> Bool
152hasFieldNames [] = False
153hasFieldNames l = all (not . null . fieldName) l
154
155constType :: DataDef -> String
156constType = head . words . show
157
158instance ToJSON ConstructorDef
159instance ToJSON DataDef
160instance ToJSON Field
161instance ToJSON Type
162
163instance FromJSON ConstructorDef
164instance FromJSON DataDef
165instance FromJSON Field
166instance FromJSON Type
167
168type DDef = Writer [DataDef]
169type CDef = Writer [ConstructorDef]
170
171data_ :: forall a . String -> CDef () -> DDef ()
172data_ n l = tell [DataDef n $ execWriter l]
173
174alias_ :: String -> Type -> DDef ()
175alias_ n t = tell [TypeAlias n t]
176
177a #= b = alias_ a b
178
179class IsField a where
180 toField :: a -> Field
181
182instance IsField Field where
183 toField a = a
184
185instance IsField Type where
186 toField a = Field "" a
187
188const_ :: String -> [Type] -> CDef ()
189const_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]]
190
191constR_ :: String -> [Field] -> CDef ()
192constR_ n t = tell [ConstructorDef n [Field a b | Field a b <- map toField t]]
193
194enum_ :: String -> CDef ()
195enum_ n = tell [ConstructorDef n []]
196
197v2b = V2 Bool
198v3b = V3 Bool
199v4b = V4 Bool
200v2u = V2 Word
201v3u = V3 Word
202v4u = V4 Word
203v2i = V2 Int
204v3i = V3 Int
205v4i = V4 Int
206v2f = V2 Float
207v3f = V3 Float
208v4f = V4 Float
209m22 = V2 v2f
210m23 = V3 v2f
211m24 = V4 v2f
212m32 = V2 v3f
213m33 = V3 v3f
214m34 = V4 v3f
215m42 = V2 v4f
216m43 = V3 v4f
217m44 = V4 v4f
218
219(#::) :: String -> Type -> Field
220a #:: 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