aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/platform/compiler/meta/archive.lux
blob: f36a0b754b6af404c3dbcca59d6af6502954c27e (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
70
71
72
73
74
75
(.module:
  [lux (#- Module)
   [control
    ["ex" exception (#+ exception:)]
    ["." equivalence (#+ Equivalence)]
    ["." monad (#+ do)]]
   [data
    ["." error (#+ Error)]
    ["." name]
    ["." text
     format]
    [collection
     ["." dictionary (#+ Dictionary)]]]
   [type (#+ :share)
    abstract]
   [world
    [file (#+ File)]]]
  [///
   [default (#+ Version)]]
  [/
   ["." signature (#+ Signature)]
   ["." key (#+ Key)]
   ["." descriptor (#+ Module Descriptor)]
   ["." document (#+ Document)]])

## Archive
(exception: #export (unknown-document {name Module})
  (ex.report ["Module" name]))

(exception: #export (cannot-replace-document {name Module}
                                             {old (Document Any)}
                                             {new (Document Any)})
  (ex.report ["Module" name]
             ["Old key" (signature.description (document.signature old))]
             ["New key" (signature.description (document.signature new))]))

(with-expansions [<Document> (as-is (type (Ex [d] (Document d))))]
  (abstract: #export Archive
    {}
    
    (Dictionary Text <Document>)

    (def: #export empty
      Archive
      (:abstraction (dictionary.new text.Hash<Text>)))

    (def: #export (add name document archive)
      (-> Module <Document> Archive (Error Archive))
      (case (dictionary.get name (:representation archive))
        (#.Some existing)
        (if (is? document existing)
          (#error.Success archive)
          (ex.throw cannot-replace-document [name existing document]))
        
        #.None
        (#error.Success (:abstraction (dictionary.put name document
                                                      (:representation archive))))))

    (def: #export (find name archive)
      (-> Module Archive (Error <Document>))
      (case (dictionary.get name (:representation archive))
        (#.Some document)
        (#error.Success document)
        
        #.None
        (ex.throw unknown-document [name])))

    (def: #export (merge additions archive)
      (-> Archive Archive (Error Archive))
      (monad.fold error.Monad<Error>
                  (function (_ [name' document'] archive')
                    (..add name' document' archive'))
                  archive
                  (dictionary.entries (:representation additions))))
    ))