-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTypes.hs
284 lines (204 loc) · 8.59 KB
/
Types.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
-- | Common types and functions
{-# LANGUAGE NoImplicitPrelude, MagicHash #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
{-# LANGUAGE OverloadedStrings, OverloadedLists #-}
module Types where
--------------------------------------------------------------------------------
import Prelude ( Int , Char , Eq , Show )
import PrimGHC
--------------------------------------------------------------------------------
import Base
import Containers
{-% include "Base.hs" %-}
{-% include "Containers.hs" %-}
--------------------------------------------------------------------------------
-- * Some common types
-- | Names
type Name = String
-- | Arity
type Arity = Int
-- | De Bruijn level
type Level = Int
-- | De Bruijn index
type Idx = Int
-- | Constructor index
type Con = Int
-- | Size
type Size = Int
-- | Top-level index
type TopIdx = Int
-- | Static function index
type Static = Int
-- | Mapping constructor names to constructor tags
type DataConTable = Trie Con
-- | Are we compiling or interpreting? This is relevant with primops,
-- where the two behaves differently...
data Mode
= Compile
| Interpret
deriving Show
-- | Sometimes we need some fake argument for recursive definitions... (?!?)
data Fake = Fake
--------------------------------------------------------------------------------
-- ** Named things
-- | We want to keep names for debugging \/ pretty printing
data Named a = Named Name a deriving Show
nfmap :: (a -> b) -> Named a -> Named b
nfmap f named = case named of { Named name x -> Named name (f x) }
forgetName :: Named a -> a
forgetName x = case x of { Named _ y -> y }
nameOf :: Named a -> String
nameOf x = case x of { Named n _ -> n }
--------------------------------------------------------------------------------
-- ** Definitions
-- | Definitions
data Defin a = Defin Name a deriving Show
fmapDefin :: (a -> b) -> Defin a -> Defin b
fmapDefin f defin = case defin of { Defin n x -> Defin n (f x) }
definedName :: Defin a -> Name
definedName defin = case defin of { Defin n _ -> n }
definedWhat :: Defin a -> a
definedWhat defin = case defin of { Defin _ e -> e }
definToPair :: Defin a -> Pair Name a
definToPair def = case def of { Defin n rhs -> Pair n rhs }
definToNamed :: Defin a -> Named a
definToNamed def = case def of { Defin n rhs -> Named n rhs }
namedToDefin :: Named a -> Defin a
namedToDefin named = case named of { Named n x -> Defin n x }
ldefinToPair :: LDefin a -> Pair Name (Located a)
ldefinToPair ldef = case ldef of { Located loc def -> case def of { Defin n rhs -> Pair n (Located loc rhs) } }
--------------------------------------------------------------------------------
type LDefin a = Located (Defin a)
fmapLDefin :: (a -> b) -> LDefin a -> LDefin b
fmapLDefin f = lfmap (fmapDefin f)
ldefinedName :: LDefin a -> Name
ldefinedName = compose definedName located
nameAndLoc :: LDefin a -> Pair Name Location
nameAndLoc ldefin = case ldefin of { Located loc defin -> case defin of { Defin name _ -> Pair name loc }}
showNameAndLoc :: LDefin a -> String
showNameAndLoc ldefin = case nameAndLoc ldefin of { Pair name loc -> append3 (quoteString name) " at " (showLocation loc) }
--------------------------------------------------------------------------------
-- * Programs
-- | We partition our programs into non-recursive definitions and mutually recursive blocks
data Block a
= NonRecursive (LDefin a)
| Recursive (List (LDefin a))
deriving Show
type Program a = List (Block a)
forgetBlockStructure :: Program a -> List (LDefin a)
forgetBlockStructure prg = go prg where
{ go blocks = case blocks of { Nil -> Nil ; Cons this rest -> case this of
{ NonRecursive defin -> Cons defin (go rest)
; Recursive defins -> append defins (go rest) } } }
--------------------------------------------------------------------------------
-- ** Literals
data Literal
= IntL Int
| ChrL Char
| StrL String
deriving (Eq,Show)
showLiteral :: Literal -> String
showLiteral lit = case lit of
{ IntL n -> showInt n
; ChrL c -> showChar c
; StrL s -> doubleQuoteString s }
--------------------------------------------------------------------------------
-- ** Variables
-- | Variables can be a de Bruijn index, or level, or a top-level definition, or a static string index
data Var
= IdxV Idx
| LevV Level
| TopV Static
| StrV Int
deriving Show
prettyVar :: Var -> String
prettyVar var = case var of
{ IdxV i -> concat [ "$" , showInt i ]
; LevV j -> concat [ "#" , showInt j ]
; TopV k -> concat [ "statfun(" , showInt k , ")" ]
; StrV m -> concat [ "str<" , showInt m , ">" ]}
--------------------------------------------------------------------------------
-- ** Atoms
-- | Things which can be applied, case-branched, passed to primops
data Atom
= VarA (Named Var)
| ConA (Named Con)
| KstA Literal
deriving Show
prettyAtom :: Atom -> String
prettyAtom atom = case atom of
{ VarA nvar -> append (nameOf nvar) (prettyVar (forgetName nvar))
; KstA lit -> showLiteral lit
; ConA ncon -> nameOf ncon }
-- ; ConA ncon -> case ncon of { Named name con -> append3 name ":" (showNat con) }
--------------------------------------------------------------------------------
-- ** Source positions and locations
-- | @SrcPos row col@; starting from (1,1)
data SrcPos = SrcPos Int Int deriving Show
startSrcPos :: SrcPos
startSrcPos = SrcPos 1 1
startCol :: SrcPos -> SrcPos
startCol pos = case pos of { SrcPos row col -> SrcPos row 1 }
nextCol :: SrcPos -> SrcPos
nextCol pos = case pos of { SrcPos row col -> SrcPos row (inc col) }
nextRow :: SrcPos -> SrcPos
nextRow pos = case pos of { SrcPos row col -> SrcPos (inc row) 1 }
nextSrcPos :: Char -> SrcPos -> SrcPos
nextSrcPos ch pos
= ifte (ceq ch newlineC ) (nextRow pos)
( ifte (ceq ch carriageReturnC) (startCol pos) (nextCol pos) )
showSrcPos :: SrcPos -> String
showSrcPos pos = case pos of { SrcPos row col ->
append ("line ") (append3 (showNat row) (", column ") (showNat col)) }
showSrcPos_ :: SrcPos -> String
showSrcPos_ pos = case pos of { SrcPos row col -> (append3 (showNat row) ":" (showNat col)) }
showSrcPos' :: FilePath -> SrcPos -> String
showSrcPos' fname pos = append3 "file " (doubleQuoteString fname) (append ", " (showSrcPos pos))
showLocation :: Location -> String
showLocation loc = case loc of { Loc fname pos1 pos2 -> concat
[ "file " , doubleQuoteString fname , ", " , showSrcPos_ pos1 , "--" , showSrcPos_ pos2 ] }
-- | Note: For stringy code-gen, we have to escape double quotes, because the became string literals
escapedShowLocation :: Location -> String
escapedShowLocation loc = case loc of { Loc fname pos1 pos2 -> concat
[ "file " , escapedDoubleQuoteString fname , ", " , showSrcPos_ pos1 , "--" , showSrcPos_ pos2 ] }
data Location = Loc FilePath SrcPos SrcPos deriving Show
data Located a = Located Location a deriving Show
type LName = Located Name
type LAtom = Located Atom
lfmap :: (a -> b) -> Located a -> Located b
lfmap f located = case located of { Located loc x -> Located loc (f x) }
locFn loc = case loc of { Loc fn _ _ -> fn }
locStart loc = case loc of { Loc _ pos1 _ -> pos1 }
locEnd loc = case loc of { Loc _ _ pos2 -> pos2 }
location lx = case lx of { Located loc _ -> loc }
located lx = case lx of { Located _ x -> x }
locatedStart = compose locStart location
locatedEnd = compose locEnd location
fakeLocation = Loc "<source>" (SrcPos 0 0) (SrcPos 0 0)
fakeLocated x = Located fakeLocation x
--------------------------------------------------------------------------------
-- ** Tokens
data Special
= LParen | RParen | LBrace | RBrace | LBracket | RBracket | Dot
| Comma | Semicolon | EqualSign | Lambda | Pipe | Arrow | DArrow | HasType
deriving (Eq,Show)
data Token
= VarTok Name
| LitTok Literal
| SpecTok Special
| WhiteTok
deriving (Eq,Show)
-- | Token wiht a location
type LToken = Located Token
--------------------------------------------------------------------------------
-- * matching on short lists
nullary :: List a -> b -> b
unary :: List a -> (a -> b) -> b
binary :: List a -> (a -> a -> b) -> b
ternary :: List a -> (a -> a -> a -> b) -> b
nullary args f = case args of { _ -> f }
unary args f = case args of { Cons x xs -> f x ; _ -> error "unary: not enough arguments" }
binary args f = case args of { Cons x xs -> unary xs (f x) ; _ -> error "binary: not enough arguments" }
ternary args f = case args of { Cons x xs -> binary xs (f x) ; _ -> error "ternary: not enough arguments" }
--------------------------------------------------------------------------------