aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/translation/js/imports.jvm.lux
blob: cbd4b27529c8f1fcb4648331e31211d5e221481e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
(.module:
  lux
  (lux (control [monad #+ do]
                ["p" parser]
                ["ex" exception #+ exception:])
       (data ["e" error #+ Error]
             [maybe]
             [text "text/" Eq<Text>]
             text/format)
       [macro]
       (macro [code]
              ["s" syntax])
       [io #+ Process])
  (luxc [lang]
        (lang [".L" module])))

(do-template [<name>]
  [(exception: #export (<name> {message Text})
     message)]

  [Invalid-Imports]
  [Module-Cannot-Import-Itself]
  [Circular-Dependency]
  )

(type: Import
  {#module Text
   #alias Text})

(def: import (s.Syntax Import) (s.tuple (p.seq s.text s.text)))

(def: #export (translate-imports translate-module annotations)
  (-> (-> Text Lux (Process Lux))
      Code
      (Meta (Process Lux)))
  (do macro.Monad<Meta>
    [_ (moduleL.set-annotations annotations)
     current-module macro.current-module-name
     imports (let [imports (|> (macro.get-tuple-ann (ident-for #.imports) annotations)
                               (maybe.default (list)))]
               (case (s.run imports (p.some import))
                 (#e.Success imports)
                 (wrap imports)
                 
                 (#e.Error error)
                 (lang.throw Invalid-Imports (%code (code.tuple imports)))))
     _ (monad.map @ (function (_ [dependency alias])
                      (do @
                        [_ (lang.assert Module-Cannot-Import-Itself current-module
                                        (not (text/= current-module dependency)))
                         already-seen? (moduleL.exists? dependency)
                         circular-dependency? (if already-seen?
                                                (moduleL.active? dependency)
                                                (wrap false))
                         _ (lang.assert Circular-Dependency (format "From: " current-module "\n"
                                                                    "  To: " dependency)
                                        (not circular-dependency?))
                         _ (moduleL.import dependency)
                         _ (if (text/= "" alias)
                             (wrap [])
                             (moduleL.alias alias dependency))]
                        (wrap [])))
                  imports)
     compiler macro.get-compiler]
    (wrap (monad.fold io.Monad<Process>
                      (function (_ import)
                        (translate-module (get@ #module import)))
                      compiler
                      imports))))