aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/io.jvm.lux
blob: 9ca8aebf3a794c0e807e724f236e3da9bf4cb7e8 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(;module:
  lux
  (lux (control monad)
       [io #- run]
       (concurrency ["P" promise])
       (data ["e" error]
             [text "T/" Eq<Text>]
             text/format)
       [meta]
       [host])
  (luxc ["&" base]))

(host;import java.io.File
  (new [String String])
  (exists [] #io #try boolean))

(host;import java.io.Reader
  (close [] #io #try void))

(host;import java.io.FileReader
  (new [File]))

(host;import java.io.BufferedReader
  (new [Reader])
  (readLine [] #io #try #? String))

(def: host-extension Text ".jvm")

(def: (find-in-sources path source-dirs)
  (-> &;Path (List &;Path) (P;Promise (Maybe File)))
  (loop [source-dirs source-dirs]
    (case source-dirs
      #;Nil
      (:: P;Monad<Promise> wrap #;None)

      (#;Cons dir source-dirs')
      (do P;Monad<Promise>
        [#let [file (File.new [dir path])]
         ?? (P;future (File.exists [] file))]
        (case ??
          (#;Right true)
          (wrap (#;Some file))

          _
          (recur source-dirs'))))))

(def: (read-source-code lux-file)
  (-> File (P;Promise (e;Error Text)))
  (P;future
   (let [reader (|> lux-file FileReader.new BufferedReader.new)]
     (loop [total ""]
       (do Monad<IO>
         [?line (BufferedReader.readLine [] reader)]
         (case ?line
           (#e;Error error)
           (wrap (#e;Error error))

           (#e;Success #;None)
           (wrap (#e;Success total))

           (#e;Success (#;Some line))
           (if (T/= "" total)
             (recur line)
             (recur (format total "\n" line)))))))))

(def: #export (read-module source-dirs module-name)
  (-> (List &;Path) Text (P;Promise (e;Error [&;Path Text])))
  (let [host-path (format module-name host-extension ".lux")
        lux-path (format module-name ".lux")]
    (with-expansions
      [<tries> (do-template [<path>]
                 [(do P;Monad<Promise>
                    [?file (find-in-sources <path> source-dirs)])
                  (case ?file
                    (#;Some file)
                    (do @
                      [?code (read-source-code file)]
                      (case ?code
                        (#e;Error error)
                        (wrap (#e;Error error))

                        (#e;Success code)
                        (wrap (#e;Success [<path> code]))))

                    #;None)]

                 [host-path]
                 [lux-path])]
      (<| <tries>
          (wrap (#e;Error (format "Module cannot be found: " module-name)))))))

(def: #export (write-module module-name module-descriptor)
  (-> Text Text (P;Promise Unit))
  (undefined))