@@ -4,9 +4,7 @@ module Generate.JavaScript
44 ( ReplBuilder(..)
55 , generateForRepl
66 , Mode(..)
7− , MainsBuilder(..)
8− , MainTrie(..)
9− , generateMains
7+ , generate
108 )
119 where
1210
@@ -55,18 +53,11 @@ generateForRepl (Opt.Graph _ graph _) home name =
5553-- GENERATE MAINS
5654
5755
58−data MainsBuilder =
59− MainsBuilder
60− { _main_code :: B.Builder
61− , _main_trie :: MainTrie
62− }
63−
64−
6556data Mode = Debug | Prod
6657
6758
68−generateMains :: Mode -> Name.Target -> Opt.Graph -> I.Interfaces -> [ModuleName.Canonical] -> Either [ModuleName.Canonical] MainsBuilder
69−generateMains mode target (Opt.Graph mains graph fields) interfaces roots =
59+generate :: Mode -> Name.Target -> Opt.Graph -> I.Interfaces -> [ModuleName.Canonical] -> Either [ModuleName.Canonical] B.Builder
60+generate mode target (Opt.Graph mains graph fields) interfaces roots =
7061 let
7162 rootSet = Set.fromList roots
7263 rootMap = Map.restrictKeys mains rootSet
@@ -76,7 +67,7 @@ generateMains mode target (Opt.Graph mains graph fields) interfaces roots =
7667 realMode = toRealMode mode target fields
7768 state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
7869 in
79− Right $ MainsBuilder (stateToBuilder state) (toMainTrie realMode interfaces rootMap)
70+ Right $ stateToBuilder state <> toMainExports realMode interfaces rootMap
8071
8172 else
8273 Left $ Set.toList $
@@ -367,49 +358,85 @@ generateManagerHelp home effectsType =
367358
368359
369360
370−-- MAIN TRIE
361+-- MAIN EXPORTS
371362
372363
373−data MainTrie =
374− MainTrie
375− { _main :: Maybe B.Builder
376− , _subs :: Map.Map N.Name MainTrie
377− }
364+toMainExports :: Name.Mode -> I.Interfaces -> Map.Map ModuleName.Canonical Opt.Main -> B.Builder
365+toMainExports mode interfaces mains =
366+ let
367+ export =
368+ Name.fromKernel N.platform "export"
378369
370+ exports =
371+ generateExports mode interfaces $
372+ Map.foldrWithKey addToTrie emptyTrie mains
373+ in
374+ Name.toBuilder export <> "(" <> exports <> ");"
379375
380−emptyTrie :: MainTrie
381−emptyTrie =
382− MainTrie Nothing Map.empty
383376
377+generateExports :: Name.Mode -> I.Interfaces -> Trie -> B.Builder
378+generateExports mode interfaces (Trie maybeMain subs) =
379+ let
380+ object =
381+ case Map.toList subs of
382+ [] ->
383+ "{}"
384+
385+ (name, subTrie) : otherSubTries ->
386+ "{'" <> N.toBuilder name <> "':"
387+ <> generateExports mode interfaces subTrie
388+ <> List.foldl' (addSubTrie mode interfaces) "}" otherSubTries
389+ in
390+ case maybeMain of
391+ Nothing ->
392+ object
384393
385−toMainTrie :: Name.Mode -> I.Interfaces -> Map.Map ModuleName.Canonical Opt.Main -> MainTrie
386−toMainTrie mode interfaces mains =
387− Map.foldrWithKey (addMainTrie mode interfaces) emptyTrie mains
394+ Just (home, main) ->
395+ let initialize = Expr.generateMain mode interfaces home main in
396+ JS.exprToBuilder initialize <> "(" <> object <> ")"
388397
389398
390−addMainTrie :: Name.Mode -> I.Interfaces -> ModuleName.Canonical -> Opt.Main -> MainTrie -> MainTrie
391−addMainTrie mode interfaces home@(ModuleName.Canonical _ moduleName) main trie =
392− let
393− segments = Text.splitOn "." moduleName
394− initMain = Expr.generateMain mode interfaces home segments main
395− newTrie = segmentsToTrie segments (JS.exprToBuilder initMain)
396− in
397− merge trie newTrie
399+addSubTrie :: Name.Mode -> I.Interfaces -> B.Builder -> (N.Name, Trie) -> B.Builder
400+addSubTrie mode interfaces end (name, trie) =
401+ ",'" <> N.toBuilder name <> "':"
402+ <> generateExports mode interfaces trie
403+ <> end
404+
405+
406+
407+-- BUILD TRIES
408+
409+
410+data Trie =
411+ Trie
412+ { _main :: Maybe (ModuleName.Canonical, Opt.Main)
413+ , _subs :: Map.Map N.Name Trie
414+ }
415+
416+
417+emptyTrie :: Trie
418+emptyTrie =
419+ Trie Nothing Map.empty
420+
421+
422+addToTrie :: ModuleName.Canonical -> Opt.Main -> Trie -> Trie
423+addToTrie home@(ModuleName.Canonical _ moduleName) main trie =
424+ merge trie $ segmentsToTrie home (Text.splitOn "." moduleName) main
398425
399426
400−segmentsToTrie :: [N.Name] -> B.Builder -> MainTrie
401−segmentsToTrie segments mainBuilder =
427+segmentsToTrie :: ModuleName.Canonical -> [N.Name] -> Opt.Main -> Trie
428+segmentsToTrie home segments main =
402429 case segments of
403430 [] ->
404− MainTrie (Just mainBuilder) Map.empty
431+ Trie (Just (home, main)) Map.empty
405432
406433 segment : otherSegments ->
407− MainTrie Nothing (Map.singleton segment (segmentsToTrie otherSegments mainBuilder))
434+ Trie Nothing (Map.singleton segment (segmentsToTrie home otherSegments main))
408435
409436
410−merge :: MainTrie -> MainTrie -> MainTrie
411−merge (MainTrie main1 subs1) (MainTrie main2 subs2) =
412− MainTrie
437+merge :: Trie -> Trie -> Trie
438+merge (Trie main1 subs1) (Trie main2 subs2) =
439+ Trie
413440 (checkedMerge main1 main2)
414441 (Map.unionWith merge subs1 subs2)
415442