on master help sign in
Handle imports more nicely during canonicalization

Changes include: 1. The old approach had a mapping from Raw to Canonical names, so you could then look up the canonical names in the dictionary of interfaces. The new approach just has a mapping from Raw names to interfaces which contain the relevant package information. 2. There used to be an intermediate Import type. There was code for checking if all imports existed. This check happens in the crawl phase though, so you could never get the error to manifest in this spot. The new approach just gets the necessary information without an intermediate allocation. (The allocation is so small it shouldn't matter though. More about it being checked elsewhere.)

commit50f8def9b93d24240ae2efab91773dc535549b92 authorEvan Czaplicki <evancz@users.noreply.github.com> dateFri 22 Feb 2019, 11:47 (8 years ago) parentefe80bc
2 files changed+15−57
compiler/src/Canonicalize/Environment/Foreign.hs+10−47 compiler/src/Canonicalize/Module.hs+5−10
compiler/src/Canonicalize/Environment/Foreign.hs+10−47
@@ -10,6 +10,7 @@ module Canonicalize.Environment.Foreign
1010import Control.Monad (foldM)
1111import qualified Data.List as List
1212import qualified Data.Map.Strict as Map
13+import Data.Map.Strict ((!))
1314import qualified Data.Name as Name
1415
1516import qualified AST.Canonical as Can
@@ -30,26 +31,12 @@ type Result i w a =
3031 Result.Result i w Error.Error a
3132
3233
33−
34−-- CREATE ENVIRONMENT
35−
36−
37−type ImportDict =
38− Map.Map Name.Name ModuleName.Canonical
39−
40−
41−createInitialEnv :: ModuleName.Canonical -> ImportDict -> I.Interfaces -> [Src.Import] -> Result i w Env.Env
42−createInitialEnv home importDict interfaces sourceImports =
43− do imports <- traverse (verifyImport importDict interfaces) (filter isNotKernel sourceImports)
44− (State vs ts cs bs qvs qts qcs) <- foldM addImport emptyState imports
34+createInitialEnv :: ModuleName.Canonical -> Map.Map ModuleName.Raw I.Interface -> [Src.Import] -> Result i w Env.Env
35+createInitialEnv home ifaces imports =
36+ do (State vs ts cs bs qvs qts qcs) <- foldM (addImport ifaces) emptyState imports
4537 Result.ok (Env.Env home (Map.map Env.Foreign vs) ts cs bs qvs qts qcs)
4638
4739
48−isNotKernel :: Src.Import -> Bool
49−isNotKernel (Src.Import (A.At _ name) _ _) =
50− not (Name.isKernel name)
51−
52−
5340
5441-- STATE
5542
@@ -80,9 +67,13 @@ emptyTypes =
8067-- ADD IMPORTS
8168
8269
83−addImport :: State -> Import -> Result i w State
84−addImport (State vs ts cs bs qvs qts qcs) (Import home (I.Interface defs unions aliases binops) prefix exposing) =
70+addImport :: Map.Map ModuleName.Raw I.Interface -> State -> Src.Import -> Result i w State
71+addImport ifaces (State vs ts cs bs qvs qts qcs) (Src.Import (A.At _ name) maybeAlias exposing) =
8572 let
73+ (I.Interface pkg defs unions aliases binops) = ifaces ! name
74+ !prefix = maybe name id maybeAlias
75+ !home = ModuleName.Canonical pkg name
76+
8677 !rawTypeInfo =
8778 Map.union
8879 (Map.mapMaybeWithKey (unionToType home) unions)
@@ -276,31 +267,3 @@ toCtors types =
276267
277268 _ ->
278269 dict
279−
280−
281−
282−-- VERIFY IMPORT
283−
284−
285−data Import =
286− Import
287− { _name :: ModuleName.Canonical
288− , _interface :: I.Interface
289− , _prefix :: Name.Name
290− , _exposing :: Src.Exposing
291− }
292−
293−
294−verifyImport :: ImportDict -> I.Interfaces -> Src.Import -> Result i w Import
295−verifyImport importDict interfaces (Src.Import (A.At region name) alias exposing) =
296− case Map.lookup name importDict of
297− Just canonicalName ->
298− case Map.lookup canonicalName interfaces of
299− Just interface ->
300− Result.ok (Import canonicalName interface (maybe name id alias) exposing)
301−
302− Nothing ->
303− Result.throw $ Error.ImportNotFound region name (Map.keys interfaces)
304−
305− Nothing ->
306− Result.throw $ Error.ImportNotFound region name (Map.elems importDict)
compiler/src/Canonicalize/Module.hs+5−10
@@ -41,19 +41,14 @@ type Result i w a =
4141-- MODULES
4242
4343
44−canonicalize
45− :: Pkg.Name
46− -> Map.Map Name.Name ModuleName.Canonical
47− -> I.Interfaces
48− -> Src.Module
49− -> Result i [W.Warning] Can.Module
50−canonicalize pkg importDict interfaces module_@(Src.Module name exports imports values _ _ binops effects) =
51− do let home = ModuleName.Canonical pkg name
44+canonicalize :: Pkg.Name -> Map.Map ModuleName.Raw I.Interface -> Src.Module -> Result i [W.Warning] Can.Module
45+canonicalize pkg ifaces modul@(Src.Module _ exports imports values _ _ binops effects) =
46+ do let home = ModuleName.Canonical pkg (Src.getName modul)
5247 let cbinops = Map.fromList (map canonicalizeBinop binops)
5348
5449 (env, cunions, caliases) <-
55− Local.add module_ =<<
56− Foreign.createInitialEnv home importDict interfaces imports
50+ Local.add modul =<<
51+ Foreign.createInitialEnv home ifaces imports
5752
5853 cvalues <- canonicalizeValues env values
5954 ceffects <- Effects.canonicalize env values cunions effects