@@ -40,14 +40,148 @@ import qualified Language.PureScript.AST as A
4040-- Desugars a module from AST to CoreFn representation.
4141--
4242moduleToCoreFn :: Environment -> A.Module -> Module Ann
43+moduleToCoreFn _ (A.Module _ _ Nothing) =
44+ error "Module exports were not elaborated before moduleToCoreFn"
4345moduleToCoreFn env (A.Module mn decls (Just exps)) =
4446 let imports = nub $ mapMaybe importToCoreFn decls ++ findQualModules decls
4547 exps' = nub $ concatMap exportToCoreFn exps
4648 externs = nub $ mapMaybe externToCoreFn decls
47− decls' = concatMap (declToCoreFn env Nothing []) decls
49+ decls' = concatMap (declToCoreFn Nothing []) decls
4850 in Module mn imports exps' externs decls'
49−moduleToCoreFn _ (A.Module{}) =
50− error "Module exports were not elaborated before moduleToCoreFn"
51+
52+ where
53+
54+ -- |
55+ -- Desugars member declarations from AST to CoreFn representation.
56+ --
57+ declToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Declaration -> [Bind Ann]
58+ declToCoreFn ss com (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
59+ [NonRec (properToIdent ctor) $
60+ Abs (ss, com, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
61+ declToCoreFn _ _ d@(A.DataDeclaration Newtype _ _ _) =
62+ error $ "Found newtype with multiple constructors: " ++ show d
63+ declToCoreFn ss com (A.DataDeclaration Data tyName _ ctors) =
64+ flip map ctors $ \(ctor, _) ->
65+ let (_, _, _, fields) = lookupConstructor env (Qualified (Just mn) ctor)
66+ in NonRec (properToIdent ctor) $ Constructor (ss, com, Nothing, Nothing) tyName ctor fields
67+ declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
68+ declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
69+ [NonRec name (exprToCoreFn ss com Nothing e)]
70+ declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
71+ [Rec $ map (\(name, _, e) -> (name, exprToCoreFn ss [] Nothing e)) ds]
72+ declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
73+ [NonRec (properToIdent name) $ mkTypeClassConstructor ss com supers members]
74+ declToCoreFn _ com (A.PositionedDeclaration ss com1 d) =
75+ declToCoreFn (Just ss) (com ++ com1) d
76+ declToCoreFn _ _ _ = []
77+
78+ -- |
79+ -- Desugars expressions from AST to CoreFn representation.
80+ --
81+ exprToCoreFn :: Maybe SourceSpan -> [Comment] -> Maybe Type -> A.Expr -> Expr Ann
82+ exprToCoreFn ss com ty (A.NumericLiteral v) =
83+ Literal (ss, com, ty, Nothing) (NumericLiteral v)
84+ exprToCoreFn ss com ty (A.StringLiteral v) =
85+ Literal (ss, com, ty, Nothing) (StringLiteral v)
86+ exprToCoreFn ss com ty (A.BooleanLiteral v) =
87+ Literal (ss, com, ty, Nothing) (BooleanLiteral v)
88+ exprToCoreFn ss com ty (A.ArrayLiteral vs) =
89+ Literal (ss, com, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn ss [] Nothing) vs)
90+ exprToCoreFn ss com ty (A.ObjectLiteral vs) =
91+ Literal (ss, com, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn ss [] Nothing)) vs)
92+ exprToCoreFn ss com ty (A.Accessor name v) =
93+ Accessor (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
94+ exprToCoreFn ss com ty (A.ObjectUpdate obj vs) =
95+ ObjectUpdate (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing obj) $ map (second (exprToCoreFn ss [] Nothing)) vs
96+ exprToCoreFn ss com ty (A.Abs (Left name) v) =
97+ Abs (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
98+ exprToCoreFn _ _ _ (A.Abs _ _) =
99+ error "Abs with Binder argument was not desugared before exprToCoreFn mn"
100+ exprToCoreFn ss com ty (A.App v1 v2) =
101+ App (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing v1) (exprToCoreFn ss [] Nothing v2)
102+ exprToCoreFn ss com ty (A.Var ident) =
103+ Var (ss, com, ty, Nothing) ident
104+ exprToCoreFn ss com ty (A.IfThenElse v1 v2 v3) =
105+ Case (ss, com, ty, Nothing) [exprToCoreFn ss [] Nothing v1]
106+ [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
107+ (Right $ exprToCoreFn Nothing [] Nothing v2)
108+ , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
109+ (Right $ exprToCoreFn Nothing [] Nothing v3) ]
110+ exprToCoreFn ss com ty (A.Constructor name) =
111+ Var (ss, com, ty, Just $ getConstructorMeta name) $ fmap properToIdent name
112+ exprToCoreFn ss com ty (A.Case vs alts) =
113+ Case (ss, com, ty, Nothing) (map (exprToCoreFn ss [] Nothing) vs) (map (altToCoreFn ss) alts)
114+ exprToCoreFn ss com _ (A.TypedValue _ v ty) =
115+ exprToCoreFn ss com (Just ty) v
116+ exprToCoreFn ss com ty (A.Let ds v) =
117+ Let (ss, com, ty, Nothing) (concatMap (declToCoreFn ss []) ds) (exprToCoreFn ss [] Nothing v)
118+ exprToCoreFn ss com _ (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
119+ let args = map (exprToCoreFn ss [] Nothing . snd) $ sortBy (compare `on` fst) vs
120+ ctor = Var (ss, [], Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
121+ in foldl (App (ss, com, Nothing, Nothing)) ctor args
122+ exprToCoreFn ss com ty (A.TypeClassDictionaryAccessor _ ident) =
123+ Abs (ss, com, ty, Nothing) (Ident "dict")
124+ (Accessor nullAnn (runIdent ident) (Var nullAnn $ Qualified Nothing (Ident "dict")))
125+ exprToCoreFn _ com ty (A.PositionedValue ss com1 v) =
126+ exprToCoreFn (Just ss) (com ++ com1) ty v
127+ exprToCoreFn _ _ _ e =
128+ error $ "Unexpected value in exprToCoreFn mn: " ++ show e
129+
130+ -- |
131+ -- Desugars case alternatives from AST to CoreFn representation.
132+ --
133+ altToCoreFn :: Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
134+ altToCoreFn ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn ss []) bs) (go vs)
135+ where
136+ go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
137+ go (Left ges) = Left $ map (exprToCoreFn ss [] Nothing *** exprToCoreFn ss [] Nothing) ges
138+ go (Right e) = Right (exprToCoreFn ss [] Nothing e)
139+
140+ -- |
141+ -- Desugars case binders from AST to CoreFn representation.
142+ --
143+ binderToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Binder -> Binder Ann
144+ binderToCoreFn ss com (A.NullBinder) =
145+ NullBinder (ss, com, Nothing, Nothing)
146+ binderToCoreFn ss com (A.BooleanBinder b) =
147+ LiteralBinder (ss, com, Nothing, Nothing) (BooleanLiteral b)
148+ binderToCoreFn ss com (A.StringBinder s) =
149+ LiteralBinder (ss, com, Nothing, Nothing) (StringLiteral s)
150+ binderToCoreFn ss com (A.NumberBinder n) =
151+ LiteralBinder (ss, com, Nothing, Nothing) (NumericLiteral n)
152+ binderToCoreFn ss com (A.VarBinder name) =
153+ VarBinder (ss, com, Nothing, Nothing) name
154+ binderToCoreFn ss com (A.ConstructorBinder dctor@(Qualified mn' _) bs) =
155+ let (_, tctor, _, _) = lookupConstructor env dctor
156+ in ConstructorBinder (ss, com, Nothing, Just $ getConstructorMeta dctor) (Qualified mn' tctor) dctor (map (binderToCoreFn ss []) bs)
157+ binderToCoreFn ss com (A.ObjectBinder bs) =
158+ LiteralBinder (ss, com, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn ss [])) bs)
159+ binderToCoreFn ss com (A.ArrayBinder bs) =
160+ LiteralBinder (ss, com, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn ss []) bs)
161+ binderToCoreFn ss com (A.ConsBinder b1 b2) =
162+ let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
163+ in ConstructorBinder (ss, com, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn ss []) [b1, b2]
164+ binderToCoreFn ss com (A.NamedBinder name b) =
165+ NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
166+ binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
167+ binderToCoreFn (Just ss) (com ++ com1) b
168+
169+ -- |
170+ -- Gets metadata for data constructors.
171+ --
172+ getConstructorMeta :: Qualified ProperName -> Meta
173+ getConstructorMeta ctor =
174+ case lookupConstructor env ctor of
175+ (Newtype, _, _, _) -> IsNewtype
176+ dc@(Data, _, _, fields) ->
177+ let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
178+ in IsConstructor constructorType fields
179+ where
180+ numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> Int
181+ numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
182+ typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> (ModuleName, ProperName)
183+ typeConstructor (Qualified (Just mn') _, (_, tyCtor, _, _)) = (mn', tyCtor)
184+ typeConstructor _ = error "Invalid argument to typeConstructor"
51185
52186-- |
53187-- Find module names from qualified references to values. This is used to
@@ -93,29 +227,6 @@ exportToCoreFn (A.TypeInstanceRef name) = [name]
93227exportToCoreFn (A.PositionedDeclarationRef _ _ d) = exportToCoreFn d
94228exportToCoreFn _ = []
95229
96−-- |
97−-- Desugars member declarations from AST to CoreFn representation.
98−--
99−declToCoreFn :: Environment -> Maybe SourceSpan -> [Comment] -> A.Declaration -> [Bind Ann]
100−declToCoreFn _ ss com (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
101− [NonRec (properToIdent ctor) $
102− Abs (ss, com, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
103−declToCoreFn _ _ _ d@(A.DataDeclaration Newtype _ _ _) =
104− error $ "Found newtype with multiple constructors: " ++ show d
105−declToCoreFn _ ss com (A.DataDeclaration Data tyName _ ctors) =
106− flip map ctors $ \(ctor, tys) ->
107− NonRec (properToIdent ctor) $ Constructor (ss, com, Nothing, Nothing) tyName ctor (length tys)
108−declToCoreFn env ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn env ss []) ds
109−declToCoreFn env ss com (A.ValueDeclaration name _ _ (Right e)) =
110− [NonRec name (exprToCoreFn env ss com Nothing e)]
111−declToCoreFn env ss _ (A.BindingGroupDeclaration ds) =
112− [Rec $ map (\(name, _, e) -> (name, exprToCoreFn env ss [] Nothing e)) ds]
113−declToCoreFn _ ss com (A.TypeClassDeclaration name _ supers members) =
114− [NonRec (properToIdent name) $ mkTypeClassConstructor ss com supers members]
115−declToCoreFn env _ com (A.PositionedDeclaration ss com1 d) =
116− declToCoreFn env (Just ss) (com ++ com1) d
117−declToCoreFn _ _ _ _ = []
118−
119230-- |
120231-- Makes a typeclass dictionary constructor function. The returned expression
121232-- is a function that accepts the superclass instances and member
@@ -131,117 +242,8 @@ mkTypeClassConstructor ss com supers members =
131242 (Ident a)
132243 (foldr (Abs nullAnn . Ident) dict as)
133244
134−-- |
135−-- Desugars expressions from AST to CoreFn representation.
136−--
137−exprToCoreFn :: Environment -> Maybe SourceSpan -> [Comment] -> Maybe Type -> A.Expr -> Expr Ann
138−exprToCoreFn _ ss com ty (A.NumericLiteral v) =
139− Literal (ss, com, ty, Nothing) (NumericLiteral v)
140−exprToCoreFn _ ss com ty (A.StringLiteral v) =
141− Literal (ss, com, ty, Nothing) (StringLiteral v)
142−exprToCoreFn _ ss com ty (A.BooleanLiteral v) =
143− Literal (ss, com, ty, Nothing) (BooleanLiteral v)
144−exprToCoreFn env ss com ty (A.ArrayLiteral vs) =
145− Literal (ss, com, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn env ss [] Nothing) vs)
146−exprToCoreFn env ss com ty (A.ObjectLiteral vs) =
147− Literal (ss, com, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn env ss [] Nothing)) vs)
148−exprToCoreFn env ss com ty (A.Accessor name v) =
149− Accessor (ss, com, ty, Nothing) name (exprToCoreFn env ss [] Nothing v)
150−exprToCoreFn env ss com ty (A.ObjectUpdate obj vs) =
151− ObjectUpdate (ss, com, ty, Nothing) (exprToCoreFn env ss [] Nothing obj) $ map (second (exprToCoreFn env ss [] Nothing)) vs
152−exprToCoreFn env ss com ty (A.Abs (Left name) v) =
153− Abs (ss, com, ty, Nothing) name (exprToCoreFn env ss [] Nothing v)
154−exprToCoreFn _ _ _ _ (A.Abs _ _) =
155− error "Abs with Binder argument was not desugared before exprToCoreFn"
156−exprToCoreFn env ss com ty (A.App v1 v2) =
157− App (ss, com, ty, Nothing) (exprToCoreFn env ss [] Nothing v1) (exprToCoreFn env ss [] Nothing v2)
158−exprToCoreFn _ ss com ty (A.Var ident) =
159− Var (ss, com, ty, Nothing) ident
160−exprToCoreFn env ss com ty (A.IfThenElse v1 v2 v3) =
161− Case (ss, com, ty, Nothing) [exprToCoreFn env ss [] Nothing v1]
162− [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
163− (Right $ exprToCoreFn env Nothing [] Nothing v2)
164− , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
165− (Right $ exprToCoreFn env Nothing [] Nothing v3) ]
166−exprToCoreFn env ss com ty (A.Constructor name) =
167− Var (ss, com, ty, Just $ getConstructorMeta env name) $ fmap properToIdent name
168−exprToCoreFn env ss com ty (A.Case vs alts) =
169− Case (ss, com, ty, Nothing) (map (exprToCoreFn env ss [] Nothing) vs) (map (altToCoreFn env ss) alts)
170−exprToCoreFn env ss com _ (A.TypedValue _ v ty) =
171− exprToCoreFn env ss com (Just ty) v
172−exprToCoreFn env ss com ty (A.Let ds v) =
173− Let (ss, com, ty, Nothing) (concatMap (declToCoreFn env ss []) ds) (exprToCoreFn env ss [] Nothing v)
174−exprToCoreFn env ss com _ (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
175− let args = map (exprToCoreFn env ss [] Nothing . snd) $ sortBy (compare `on` fst) vs
176− ctor = Var (ss, [], Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
177− in foldl (App (ss, com, Nothing, Nothing)) ctor args
178−exprToCoreFn env _ com ty (A.PositionedValue ss com1 v) =
179− exprToCoreFn env (Just ss) (com ++ com1) ty v
180−exprToCoreFn _ _ _ _ e =
181− error $ "Unexpected value in exprToCoreFn: " ++ show e
182−
183−-- |
184−-- Desugars case alternatives from AST to CoreFn representation.
185−--
186−altToCoreFn :: Environment -> Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
187−altToCoreFn env ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn env ss []) bs) (go vs)
188− where
189− go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
190− go (Left ges) = Left $ map (exprToCoreFn env ss [] Nothing *** exprToCoreFn env ss [] Nothing) ges
191− go (Right e) = Right (exprToCoreFn env ss [] Nothing e)
192−
193−-- |
194−-- Desugars case binders from AST to CoreFn representation.
195−--
196−binderToCoreFn :: Environment -> Maybe SourceSpan -> [Comment] -> A.Binder -> Binder Ann
197−binderToCoreFn _ ss com (A.NullBinder) =
198− NullBinder (ss, com, Nothing, Nothing)
199−binderToCoreFn _ ss com (A.BooleanBinder b) =
200− LiteralBinder (ss, com, Nothing, Nothing) (BooleanLiteral b)
201−binderToCoreFn _ ss com (A.StringBinder s) =
202− LiteralBinder (ss, com, Nothing, Nothing) (StringLiteral s)
203−binderToCoreFn _ ss com (A.NumberBinder n) =
204− LiteralBinder (ss, com, Nothing, Nothing) (NumericLiteral n)
205−binderToCoreFn _ ss com (A.VarBinder name) =
206− VarBinder (ss, com, Nothing, Nothing) name
207−binderToCoreFn env ss com (A.ConstructorBinder dctor@(Qualified mn _) bs) =
208− let (_, tctor, _) = lookupConstructor env dctor
209− in ConstructorBinder (ss, com, Nothing, Just $ getConstructorMeta env dctor) (Qualified mn tctor) dctor (map (binderToCoreFn env ss []) bs)
210−binderToCoreFn env ss com (A.ObjectBinder bs) =
211− LiteralBinder (ss, com, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn env ss [])) bs)
212−binderToCoreFn env ss com (A.ArrayBinder bs) =
213− LiteralBinder (ss, com, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn env ss []) bs)
214−binderToCoreFn env ss com (A.ConsBinder b1 b2) =
215− let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
216− in ConstructorBinder (ss, com, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn env ss []) [b1, b2]
217−binderToCoreFn env ss com (A.NamedBinder name b) =
218− NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn env ss [] b)
219−binderToCoreFn env _ com (A.PositionedBinder ss com1 b) =
220− binderToCoreFn env (Just ss) (com ++ com1) b
221−
222245-- |
223246-- Converts a ProperName to an Ident.
224247--
225248properToIdent :: ProperName -> Ident
226249properToIdent = Ident . runProperName
227−
228−-- |
229−-- Gets metadata for data constructors.
230−--
231−getConstructorMeta :: Environment -> Qualified ProperName -> Meta
232−getConstructorMeta env ctor =
233− case lookupConstructor env ctor of
234− (Newtype, _, _) -> IsNewtype
235− dc@(Data, _, ty) ->
236− let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
237− in IsConstructor constructorType (getArity ty)
238− where
239− getArity :: Type -> Int
240− getArity (TypeApp (TypeApp f _) t) | f == tyFunction = getArity t + 1
241− getArity (ForAll _ ty _) = getArity ty
242− getArity _ = 0
243− numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> Int
244− numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
245− typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> (ModuleName, ProperName)
246− typeConstructor (Qualified (Just mn) _, (_, tyCtor, _)) = (mn, tyCtor)
247− typeConstructor _ = error "Invalid argument to typeConstructor"