11module Language.PureScript.Backend.IR
22 ( module Language.PureScript.Backend.IR
33 , module Language.PureScript.Backend.IR.Types
4+ , module Language.PureScript.Backend.IR.Names
45 ) where
56
67import Control.Monad.Error.Class (MonadError (throwError ))
@@ -14,11 +15,11 @@ import Data.Text qualified as Text
1415import Data.Traversable (for )
1516import Language.PureScript.Backend.IR.Inliner (Annotation )
1617import Language.PureScript.Backend.IR.Inliner qualified as Inliner
18+ import Language.PureScript.Backend.IR.Names
1719import Language.PureScript.Backend.IR.Types
1820import Language.PureScript.Comments (Comment (.. ))
1921import Language.PureScript.CoreFn qualified as Cfn
2022import Language.PureScript.CoreFn.Laziness (applyLazinessTransform )
21- import Language.PureScript.Names (ModuleName (.. ), runModuleName )
2223import Language.PureScript.Names qualified as Names
2324import Language.PureScript.Names qualified as PS
2425import Language.PureScript.PSString
@@ -35,7 +36,7 @@ import Prelude hiding (identity, show)
3536
3637data Context = Context
3738 { annotations
38- ∷ [ Annotation]
39+ ∷ Map Name Annotation
3940 , contextModule
4041 ∷ Cfn.Module Cfn.Ann
4142 , contextDataTypes
@@ -87,7 +88,7 @@ mkModule cfnModule contextDataTypes = do
8788 , needsRuntimeLazy = Any False
8889 }
8990 do
90- moduleBindings ← mkDecls
91+ moduleBindings ← mkBindings
9192 moduleImports ← mkImports
9293 moduleExports ← mkExports
9394 moduleReExports ← mkReExports
@@ -103,20 +104,20 @@ mkModule cfnModule contextDataTypes = do
103104 , moduleForeigns
104105 }
105106
106- parseAnnotations ∷ Cfn. Module Cfn. Ann → Either CoreFnError [ Annotation ]
107+ parseAnnotations ∷ Cfn. Module Cfn. Ann → Either CoreFnError ( Map Name Annotation )
107108parseAnnotations currentModule =
108109 Cfn. moduleComments currentModule
109110 & foldMapM \ case
110- LineComment line → pure <$> parseAnnotationLine line
111- BlockComment block → traverse parseAnnotationLine (lines block)
112- & fmap catMaybes
111+ LineComment line → pure <$> parsePragmaLine line
112+ BlockComment block → traverse parsePragmaLine (lines block)
113+ & fmap ( Map. fromList . catMaybes)
113114 where
114- parseAnnotationLine ∷ Text → Either CoreFnError (Maybe Annotation )
115- parseAnnotationLine ( Text. strip → ln) = do
116- let parser = optional (Inliner. annotationParser <* Megaparsec. eof)
117- first
118- ( CoreFnError ( Cfn. moduleName currentModule) . AnnotationParsingError )
119- ( Megaparsec. parse parser ( Cfn. modulePath currentModule) ln )
115+ parsePragmaLine ∷ Text → Either CoreFnError (Maybe Inliner. Pragma )
116+ parsePragmaLine ln = do
117+ let parser = optional (Inliner. pragmaParser <* Megaparsec. eof)
118+ Megaparsec. parse parser ( Cfn. modulePath currentModule) ( Text. strip ln)
119+ & first
120+ ( CoreFnError ( Cfn. moduleName currentModule) . AnnotationParsingError )
120121
121122mkImports ∷ RepM [ModuleName ]
122123mkImports = do
@@ -169,80 +170,89 @@ mkQualified f (PS.Qualified by a) =
169170identToName ∷ PS. Ident → Name
170171identToName = Name . PS. runIdent
171172
172- mkDecls ∷ RepM [Grouping ( Ann , Name , Exp ) ]
173- mkDecls = do
174- psDecls ← gets $ contextModule >>> Cfn. moduleBindings
175- traverse mkGrouping psDecls
173+ mkBindings ∷ RepM [Binding ]
174+ mkBindings = do
175+ psBindings ← gets $ contextModule >>> Cfn. moduleBindings
176+ traverse mkBinding psBindings
176177
177- mkGrouping ∷ Cfn. Bind Cfn. Ann → RepM (Grouping (Ann , Name , Exp ))
178- mkGrouping = \ case
179- Cfn. NonRec _ann ident cfnExpr →
180- Standalone . (noAnn,identToName ident,) <$> makeExp cfnExpr
178+ mkBinding ∷ Cfn. Bind Cfn. Ann → RepM Binding
179+ mkBinding = \ case
180+ Cfn. NonRec _ann ident cfnExpr → do
181+ let name = identToName ident
182+ ann ← gets $ annotations >>> Map. lookup name
183+ expr ← makeExprAnnotated ann cfnExpr
184+
185+ pure $ Standalone (noAnn, name, expr)
181186 Cfn. Rec bindingGroup → do
182187 modname ← gets $ contextModule >>> Cfn. moduleName
183188 bindings ← writer $ applyLazinessTransform modname bindingGroup
184189 case NE. nonEmpty bindings of
185190 Nothing → throwContextualError EmptyBindingGroup
186191 Just bs →
187192 RecursiveGroup <$> for bs \ ((_ann, ident), expr) →
188- (noAnn,identToName ident,) <$> makeExp expr
193+ (noAnn,identToName ident,) <$> makeExpr expr
194+
195+ makeExpr ∷ CfnExp → RepM Exp
196+ makeExpr = makeExprAnnotated Nothing
189197
190- makeExp ∷ CfnExp → RepM Exp
191- makeExp cfnExpr =
198+ makeExprAnnotated ∷ Ann → CfnExp → RepM Exp
199+ makeExprAnnotated ann cfnExpr =
192200 case cfnExpr of
193201 Cfn. Literal _ann literal →
194- mkLiteral literal
195- Cfn. Constructor ann tyName ctorName ids →
196- mkConstructor ann tyName ctorName ids
202+ mkLiteral ann literal
203+ Cfn. Constructor cfnAnn tyName ctorName ids →
204+ mkConstructor cfnAnn ann tyName ctorName ids
197205 Cfn. Accessor _ann str expr →
198- mkAccessor str expr
206+ mkAccessor ann str expr
199207 Cfn. ObjectUpdate _ann expr patches →
200208 mkObjectUpdate expr patches
201209 Cfn. Abs _ann ident expr →
202- mkAbstraction ident expr
210+ mkAbstraction ann ident expr
203211 Cfn. App _ann abstr arg →
204212 mkApplication abstr arg
205213 Cfn. Var _ann qualifiedIdent →
206214 mkRef qualifiedIdent
207215 Cfn. Case _ann exprs alternatives →
208216 case NE. nonEmpty alternatives of
209- Just as → mkCase exprs as
217+ Just as → mkCase ann exprs as
210218 Nothing → throwContextualError $ EmptyCase cfnExpr
211- Cfn. Let _ann binds exprs → mkLet binds exprs
219+ Cfn. Let _ann binds exprs →
220+ mkLet ann binds exprs
212221
213- mkLiteral ∷ Cfn. Literal CfnExp → RepM Exp
214- mkLiteral = \ case
222+ mkLiteral ∷ Ann → Cfn. Literal CfnExp → RepM Exp
223+ mkLiteral ann = \ case
215224 Cfn. NumericLiteral (Left i) →
216- pure $ literalInt i
225+ pure $ LiteralInt ann i
217226 Cfn. NumericLiteral (Right d) →
218- pure $ literalFloat d
227+ pure $ LiteralFloat ann d
219228 Cfn. StringLiteral s →
220- pure $ literalString $ decodeStringEscaping s
229+ pure $ LiteralString ann $ decodeStringEscaping s
221230 Cfn. CharLiteral c →
222- pure $ literalChar c
231+ pure $ LiteralChar ann c
223232 Cfn. BooleanLiteral b →
224- pure $ literalBool b
233+ pure $ LiteralBool ann b
225234 Cfn. ArrayLiteral exprs →
226- literalArray <$> traverse makeExp exprs
235+ LiteralArray ann <$> traverse makeExpr exprs
227236 Cfn. ObjectLiteral kvs →
228- literalObject <$> traverse (bitraverse mkPropName makeExp ) kvs
237+ LiteralObject ann <$> traverse (bitraverse mkPropName makeExpr ) kvs
229238
230239mkConstructor
231240 ∷ Cfn. Ann
241+ → Ann
232242 → PS. ProperName 'PS.TypeName
233243 → PS. ProperName 'PS.ConstructorName
234244 → [PS. Ident ]
235245 → RepM Exp
236- mkConstructor ann properTyName properCtorName fields = do
246+ mkConstructor cfnAnn ann properTyName properCtorName fields = do
237247 let tyName = mkTyName properTyName
238248 contextModuleName ← gets (Cfn. moduleName . contextModule)
239249 algTy ← algebraicTy contextModuleName tyName
240250 pure
241- if isNewtype ann
251+ if isNewtype cfnAnn
242252 then identity
243253 else
244254 Ctor
245- noAnn
255+ ann
246256 algTy
247257 contextModuleName
248258 tyName
@@ -263,21 +273,21 @@ mkPropName str = case decodeString str of
263273 Left err → throwContextualError $ UnicodeDecodeError err
264274 Right decodedString → pure $ PropName decodedString
265275
266- mkAccessor ∷ PSString → CfnExp → RepM Exp
267- mkAccessor prop cfnExpr = do
276+ mkAccessor ∷ Ann → PSString → CfnExp → RepM Exp
277+ mkAccessor ann prop cfnExpr = do
268278 propName ← mkPropName prop
269- makeExp cfnExpr <&> \ expr → ObjectProp noAnn expr propName
279+ makeExprAnnotated ann cfnExpr <&> \ expr → ObjectProp noAnn expr propName
270280
271281mkObjectUpdate ∷ CfnExp → [(PSString , CfnExp )] → RepM Exp
272282mkObjectUpdate cfnExp props = do
273- expr ← makeExp cfnExp
274- patch ← traverse (bitraverse mkPropName makeExp ) props
283+ expr ← makeExpr cfnExp
284+ patch ← traverse (bitraverse mkPropName makeExpr ) props
275285 case NE. nonEmpty patch of
276286 Nothing → throwContextualError EmptyObjectUpdate
277287 Just ps → pure $ ObjectUpdate noAnn expr ps
278288
279- mkAbstraction ∷ PS. Ident → CfnExp → RepM Exp
280- mkAbstraction i e = abstraction param <$> makeExp e
289+ mkAbstraction ∷ Ann → PS. Ident → CfnExp → RepM Exp
290+ mkAbstraction ann i e = Abs ann param <$> makeExpr e
281291 where
282292 param ∷ Parameter Ann =
283293 case PS. runIdent i of
@@ -287,8 +297,8 @@ mkAbstraction i e = abstraction param <$> makeExp e
287297mkApplication ∷ CfnExp → CfnExp → RepM Exp
288298mkApplication e1 e2 =
289299 if isNewtype (Cfn. extractAnn e1)
290- then makeExp e2
291- else application <$> makeExp e1 <*> makeExp e2
300+ then makeExpr e2
301+ else application <$> makeExpr e1 <*> makeExpr e2
292302
293303mkQualifiedIdent ∷ PS. Qualified PS. Ident → RepM (Qualified Name )
294304mkQualifiedIdent (PS. Qualified by ident) =
@@ -303,27 +313,27 @@ mkQualifiedIdent (PS.Qualified by ident) =
303313mkRef ∷ PS. Qualified PS. Ident → RepM Exp
304314mkRef = (\ n → Ref noAnn n 0 ) <<$>> mkQualifiedIdent
305315
306- mkLet ∷ [Cfn. Bind Cfn. Ann ] → CfnExp → RepM Exp
307- mkLet binds expr = do
308- groupings ∷ NonEmpty ( Grouping ( Ann , Name , Exp )) ←
316+ mkLet ∷ Ann → [Cfn. Bind Cfn. Ann ] → CfnExp → RepM Exp
317+ mkLet ann binds expr = do
318+ groupings ∷ NonEmpty Binding ←
309319 NE.nonEmpty binds
310- & maybe (throwContextualError LetWithoutBinds ) (traverse mkGrouping )
311- lets groupings <$> makeExp expr
320+ & maybe (throwContextualError LetWithoutBinds ) (traverse mkBinding )
321+ Let ann groupings <$> makeExpr expr
312322
313323--------------------------------------------------------------------------------
314324-- Case statements are compiled to a decision trees (nested if/else's) ---------
315325-- The algorithm is based on this document: ------------------------------------
316326-- https://julesjacobs.com/notes/patternmatching/patternmatching.pdf -----------
317327
318- mkCase ∷ [CfnExp ] → NonEmpty (Cfn. CaseAlternative Cfn. Ann ) → RepM Exp
319- mkCase cfnExpressions alternatives = do
320- expressions ← traverse makeExp cfnExpressions
328+ mkCase ∷ Ann -> [CfnExp ] → NonEmpty (Cfn. CaseAlternative Cfn. Ann ) → RepM Exp
329+ mkCase ann cfnExpressions alternatives = do
330+ expressions ← traverse makeExpr cfnExpressions
321331 -- Before making clauses, we need to prepare bindings
322332 -- such that instead of repeating the same expression multiple times,
323333 -- we can bind it to a name once and then repeat references.
324334 (references, bindings) ← prepareBindings expressions
325335 clauses ← traverse (alternativeToClauses references) alternatives
326- let addHeader = maybe id lets (NE. nonEmpty bindings)
336+ let addHeader = maybe id ( Let ann) (NE. nonEmpty bindings)
327337 addHeader <$> mkCaseClauses (NE. toList clauses)
328338
329339-- Either an expression to inline, or a named expression reference.
@@ -649,8 +659,8 @@ alternativeToClauses
649659
650660 clauseResult ←
651661 bitraverse
652- (traverse (bitraverse makeExp makeExp ))
653- makeExp
662+ (traverse (bitraverse makeExpr makeExpr ))
663+ makeExpr
654664 caseAlternativeResult
655665
656666 pure
0 commit comments