git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Fixes for issue #62: double var decls and module renames (#66)
commitb2bf65425f2ac30f0b20b5647c9de47cb913620f authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 4 Oct 2020, 18:49 (6 years ago) parent7a3f114
4 files changed+33−53
src/CodeGen/IL.hs+1−44 src/CodeGen/IL/Common.hs+8−4 src/CodeGen/IL/Optimizer.hs+14−1 src/CodeGen/IL/Printer.hs+10−4
src/CodeGen/IL.hs+1−44
@@ -52,10 +52,7 @@ moduleToIL
5252 -> m (Text, [Text], [AST], Text, Text)
5353moduleToIL (Module _ coms mn _ imps _ foreigns decls) project =
5454 do
55− let usedNames = concatMap getNames decls
56− let mnLookup = renameImports usedNames imps
57− let decls' = renameModules mnLookup decls
58− ilDecls <- mapM (bindToIL ModuleDecl) decls'
55+ ilDecls <- mapM (bindToIL ModuleDecl) decls
5956 optimized <- traverse (traverse (optimize modName')) ilDecls
6057 let optimized' = concat optimized
6158 values = annotValue <$> optimized'
@@ -80,27 +77,6 @@ moduleToIL (Module _ coms mn _ imps _ foreigns decls) project =
8077 getNames (NonRec _ ident _) = [ident]
8178 getNames (Rec vals) = map (snd . fst) vals
8279
83− -- | Creates alternative names for each module to ensure they don't collide
84− -- with declaration names.
85− renameImports :: [Ident] -> [(Ann, ModuleName)] -> M.Map ModuleName (Ann, ModuleName)
86− renameImports = go M.empty
87− where
88− go :: M.Map ModuleName (Ann, ModuleName) -> [Ident] -> [(Ann, ModuleName)] -> M.Map ModuleName (Ann, ModuleName)
89− go acc used ((ann, mn') : mns') =
90− let mni = Ident $ runModuleName mn'
91− in if mn' /= mn && mni `elem` used
92− then let newName = freshModuleName 1 mn' used
93− in go (M.insert mn' (ann, newName) acc) (Ident (runModuleName newName) : used) mns'
94− else go (M.insert mn' (ann, mn') acc) used mns'
95− go acc _ [] = acc
96−
97− freshModuleName :: Integer -> ModuleName -> [Ident] -> ModuleName
98− freshModuleName i mn'@(ModuleName pns) used =
99− let newName = ModuleName $ init pns ++ [ProperName $ runProperName (last pns) <> "_" <> T.pack (show i)]
100− in if Ident (runModuleName newName) `elem` used
101− then freshModuleName (i + 1) mn' used
102− else newName
103−
10480 -- | Generates IL code for a module import
10581 --
10682 importToIL :: AST -> [Text]
@@ -112,25 +88,6 @@ moduleToIL (Module _ coms mn _ imps _ foreigns decls) project =
11288 extract :: Text -> Text
11389 extract = T.replace "_" "." . T.dropWhileEnd (=='_')
11490
115− -- | Replaces the `ModuleName`s in the AST so that the generated code refers to
116− -- the collision-avoiding renamed module imports.
117− renameModules :: M.Map ModuleName (Ann, ModuleName) -> [Bind Ann] -> [Bind Ann]
118− renameModules mnLookup binds =
119− let (f, _, _) = everywhereOnValues id ilExpr goBinder
120− in map f binds
121− where
122− ilExpr :: Expr a -> Expr a
123− ilExpr (Var ann q) = Var ann (renameQual q)
124− ilExpr e = e
125− goBinder :: Binder a -> Binder a
126− goBinder (ConstructorBinder ann q1 q2 bs) = ConstructorBinder ann (renameQual q1) (renameQual q2) bs
127− goBinder b = b
128− renameQual :: Qualified a -> Qualified a
129− renameQual (Qualified (Just mn') a) =
130− let (_,mnSafe) = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup
131− in Qualified (Just mnSafe) a
132− renameQual q = q
133−
13491 -- |
13592 -- Generate code in the simplified intermediate representation for a declaration
13693 --
src/CodeGen/IL/Common.hs+8−4
@@ -18,7 +18,7 @@ import qualified Language.PureScript.Constants as C
1818moduleNameToIL :: ModuleName -> Text
1919moduleNameToIL (ModuleName pns) =
2020 let name = T.intercalate "_" (runProperName `map` pns)
21− in if nameIsILBuiltIn name then (name <> "_") else name
21+ in if nameIsILBuiltIn name then (name <> moduleRenamerMarker) else name
2222
2323moduleNameToIL' :: ModuleName -> Text
2424moduleNameToIL' (ModuleName pns) = T.intercalate "." (runProperName `map` pns)
@@ -56,9 +56,10 @@ properToIL name
5656-- | Attempts to find a human-readable name for a symbol, if none has been specified returns the
5757-- ordinal value.
5858identCharToText :: Char -> Text
59+identCharToText 'ṩ' = "ᵤṩ"
5960identCharToText c | isAlphaNum c = T.singleton c
6061identCharToText '_' = "_"
61−identCharToText '\'' = "ʹ"
62+identCharToText '\'' = "ᵖ"
6263identCharToText c = "ᵤ" <> T.pack (show (ord c))
6364
6465moduleProperToIL :: Text -> Text
@@ -160,7 +161,7 @@ ilLiterals =
160161 ]
161162
162163withPrefix :: Text -> Text
163−withPrefix s = "PS__" <> s
164+withPrefix s = "Ꞌ" <> s
164165
165166anyType :: Text
166167anyType = "Any"
@@ -198,4 +199,7 @@ copyDictFn = "CopyDict"
198199freshName' :: MonadSupply m => m Text
199200freshName' = do
200201 name <- freshName
201− return $ T.replace "$" "ᵗ" name
202+ return $ T.replace "$" "ṩ" name
203+
204+moduleRenamerMarker :: Text
205+moduleRenamerMarker = "ᴹ"
src/CodeGen/IL/Optimizer.hs+14−1
@@ -22,10 +22,11 @@ import qualified Language.PureScript.Constants as C
2222optimize :: MonadSupply m => AST -> AST -> m AST
2323optimize mn il = do
2424 il' <- untilFixedPoint (inlineFnComposition . inlineUnsafeCoerce . inlineUnsafePartial . tidyUp) il
25− untilFixedPoint (return . ignoreUnusedResults . inlineCommonValues . inlineCommonOperators . tidyUp) . tco mn . inlineST
25+ il'' <- untilFixedPoint (return . ignoreUnusedResults . inlineCommonValues . inlineCommonOperators . tidyUp) . tco mn . inlineST
2626 =<< untilFixedPoint (return . magicDoST)
2727 =<< untilFixedPoint (return . magicDoEff)
2828 =<< untilFixedPoint (return . magicDoEffect) il'
29+ untilFixedPoint (return . collapseVarDeclarations) il''
2930 where
3031 tidyUp :: AST -> AST
3132 tidyUp = applyAll
@@ -54,6 +55,18 @@ collapseIfChecks = everywhere collapse where
5455 | prop == "otherwise" && val == "Data_Boolean" = exprs
5556 collapse exprs = exprs
5657
58+collapseVarDeclarations :: AST -> AST
59+collapseVarDeclarations = everywhere collapse where
60+ collapse :: AST -> AST
61+ collapse (Block ss sts) = Block ss (go Nothing sts)
62+ collapse s = s
63+
64+ go :: Maybe Text -> [AST] -> [AST]
65+ go _ [] = []
66+ go Nothing (decl@(VariableIntroduction _ var (Just _)) : sts) = decl : go (Just var) (go Nothing sts)
67+ go (Just var') ((VariableIntroduction ss var (Just val)) : sts)
68+ | var == var' = (Assignment ss (Var Nothing var) val) : go (Just var') sts
69+ go var' (s:sts) = s : go var' sts
5770
5871ignoreUnusedResults :: AST -> AST
5972ignoreUnusedResults = everywhere $ removeFromBlock go
src/CodeGen/IL/Printer.hs+10−4
@@ -459,7 +459,13 @@ implHeaderSource mn imports otherPrefix =
459459 "type _ = Any\n\n"
460460 where
461461 formatImport :: Text -> Text
462− formatImport s = " \"" <> otherPrefix <> "/" <> modPrefix <> "/" <> s <> "\"\n"
462+ formatImport s =
463+ "\t\"" <> otherPrefix <> "/" <> modPrefix <> "/" <> moduleRenamer s <> "\"\n"
464+ moduleRenamer :: Text -> Text
465+ moduleRenamer s
466+ | (s', sfx) <- T.breakOn moduleRenamerMarker s,
467+ not $ T.null sfx = s'
468+ moduleRenamer s = s
463469
464470implFooterSource :: Text -> [Ident] -> Text
465471implFooterSource mn foreigns =
@@ -487,7 +493,7 @@ implFooterSource mn foreigns =
487493 mainSource :: Text
488494 mainSource = "\
489495 \func main() {\n\
490− \ Run(PS__main())\n\
496+ \ Run(Ꞌmain())\n\
491497 \}\n\n\
492498 \"
493499
@@ -516,7 +522,7 @@ ffiLoader :: Text
516522ffiLoader = modLabel <> "/ffi-loader"
517523
518524initName :: Text -> Text
519−initName s = "ₒ" <> s
525+initName s = "_" <> s <> "ᵒⁿᶜᵉ"
520526
521527valueName :: Text -> Text
522−valueName s = "ₐ" <> s
528+valueName s = "_" <> s <> "ᶠᵒʳᵉⁱᵍⁿ"