@@ -30,9 +30,10 @@ import qualified IR.Types as I
30
30
31
31
import Control.Monad (unless )
32
32
import Data.Bifunctor (Bifunctor (.. ))
33
+ import Data.Generics (everything , mkQ )
33
34
import Data.Maybe (fromMaybe )
34
35
import qualified Data.Set as S
35
- import IR.Types.Type (tempTupleId )
36
+ import IR.Types.Type (tupleId )
36
37
37
38
38
39
-- | Unannotated terms appear as an empty stack.
@@ -52,9 +53,9 @@ annType = ann . I.AnnType
52
53
53
54
-- | Lower an AST 'Program' into IR.
54
55
lowerProgram :: A. Program -> Compiler. Pass (I. Program I. Annotations )
55
- lowerProgram (A. Program ds) = do
56
+ lowerProgram p @ (A. Program ds) = do
56
57
let (tds, cds, xds, dds) = A. getTops ds
57
- tds' <- mapM lowerTypeDef tds
58
+ tds' <- (++) <$> lowerTupleDefs p <*> mapM lowerTypeDef tds
58
59
xds' <- mapM lowerExternDecl xds
59
60
dds' <- mapM lowerDef dds
60
61
return $
@@ -66,21 +67,58 @@ lowerProgram (A.Program ds) = do
66
67
, I. cDefs = concat cds
67
68
, I. symTable = I. uninitializedSymTable
68
69
}
70
+
71
+
72
+ lowerTypeDef :: A. TypeDef -> Compiler. Pass (I. TConId , I. TypeDef )
73
+ lowerTypeDef td = do
74
+ tds <- mapM lowerTypeVariant $ A. typeVariants td
75
+ return
76
+ ( fromId $ A. typeName td
77
+ , I. TypeDef {I. targs = map TVarId $ A. typeParams td, I. variants = tds}
78
+ )
79
+ where
80
+ lowerTypeVariant ::
81
+ A. TypeVariant -> Compiler. Pass (I. DConId , I. TypeVariant )
82
+ lowerTypeVariant (A. VariantUnnamed vn ts) =
83
+ (fromId vn,) . I. VariantUnnamed <$> mapM lowerType ts
84
+
85
+
86
+ lowerTupleDefs :: A. Program -> Compiler. Pass [(I. TConId , I. TypeDef )]
87
+ lowerTupleDefs dds = return $ map lowerTupleDef $ S. toList tupleSizes
69
88
where
70
- lowerTypeDef :: A. TypeDef -> Compiler. Pass (I. TConId , I. TypeDef )
71
- lowerTypeDef td = do
72
- tds <- mapM lowerTypeVariant $ A. typeVariants td
73
- return
74
- ( fromId $ A. typeName td
75
- , I. TypeDef {I. targs = map TVarId $ A. typeParams td, I. variants = tds}
76
- )
77
- where
78
- lowerTypeVariant
79
- :: A. TypeVariant -> Compiler. Pass (I. DConId , I. TypeVariant )
80
- lowerTypeVariant (A. VariantUnnamed vn ts) =
81
- (fromId vn,) . I. VariantUnnamed <$> mapM lowerType ts
82
- lowerExternDecl :: A. ExternDecl -> Compiler. Pass (I. VarId , I. Type )
83
- lowerExternDecl (A. ExternDecl i t) = (fromId i,) <$> lowerType t
89
+ tupleSizes :: S. Set Int
90
+ tupleSizes =
91
+ -- This is so hilariously inefficient but I tell myself it's ok
92
+ everything S. union (mkQ S. empty dconTupleLen) dds
93
+ `S.union` everything S. union (mkQ S. empty patTupleLen) dds
94
+ `S.union` everything S. union (mkQ S. empty typeTupleLen) dds
95
+
96
+ dconTupleLen :: A. Expr -> S. Set Int
97
+ dconTupleLen (A. Tuple es) = S. singleton $ length es
98
+ dconTupleLen (A. Par es) = S. singleton $ length es
99
+ dconTupleLen _ = S. empty
100
+
101
+ patTupleLen :: A. Pat -> S. Set Int
102
+ patTupleLen (A. PatTup es) = S. singleton $ length es
103
+ patTupleLen _ = S. empty
104
+
105
+ typeTupleLen :: A. Typ -> S. Set Int
106
+ typeTupleLen (A. TTuple tys) = S. singleton $ length tys
107
+ typeTupleLen _ = S. empty
108
+
109
+ lowerTupleDef :: Int -> (I. TConId , I. TypeDef )
110
+ lowerTupleDef i =
111
+ let targs = map (TVarId . fromString . ((" tup" ++ show i ++ " arg" ) ++ ) . show ) [1 .. i]
112
+ in ( tupleId i
113
+ , I. TypeDef
114
+ { I. targs = targs
115
+ , I. variants = [(tupleId i, I. VariantUnnamed $ map I. TVar targs)]
116
+ }
117
+ )
118
+
119
+
120
+ lowerExternDecl :: A. ExternDecl -> Compiler. Pass (I. VarId , I. Type )
121
+ lowerExternDecl (A. ExternDecl i t) = (fromId i,) <$> lowerType t
84
122
85
123
86
124
-- | Lower an 'A.Definition' into a name and bound expression.
@@ -207,7 +245,7 @@ lowerExpr (A.Match s ps) =
207
245
where
208
246
lowerArm (a, e) = (,) <$> lowerPatAlt a <*> lowerExpr e
209
247
lowerExpr (A. Tuple es) =
210
- apply_recurse (I. Data (I. DConId (tempTupleId $ length es)) untyped) <$> mapM lowerExpr es
248
+ apply_recurse (I. Data (I. DConId (tupleId $ length es)) untyped) <$> mapM lowerExpr es
211
249
where
212
250
apply_recurse e [] = e
213
251
apply_recurse e (x : xs) = apply_recurse (I. App e x untyped) xs
@@ -223,7 +261,7 @@ lowerPatAlt (A.PatId i)
223
261
| otherwise = return $ I. AltData (I. DConId i) [] untyped
224
262
lowerPatAlt (A. PatLit l) = I. AltLit <$> lowerLit l <*> pure untyped
225
263
lowerPatAlt (A. PatTup ps) =
226
- I. AltData (I. tempTupleId $ length ps) <$> mapM lowerPatAlt ps <*> pure untyped
264
+ I. AltData (I. tupleId $ length ps) <$> mapM lowerPatAlt ps <*> pure untyped
227
265
lowerPatAlt p@ (A. PatApp _) = case A. collectPApp p of
228
266
(A. PatId i, ps) | isCons i -> I. AltData (fromId i) <$> mapM lowerPatAlt ps <*> pure untyped
229
267
_ -> Compiler. unexpected " lowerPatAlt: app head should be a data constructor"
0 commit comments