aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/io.jvm.lux
blob: ab62b8f438c731ee1d1fa49a3c7037f008fbccdb (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
(;module:
  lux
  (lux (control monad)
       [io #- run]
       (concurrency ["P" promise])
       (data ["E" error]
             [text "T/" Eq<Text>]
             text/format)
       [macro]
       host)
  (luxc ["&" base]))

(jvm-import java.io.File
  (new [String String])
  (exists [] #io #try boolean))

(jvm-import java.io.Reader
  (close [] #io #try void))

(jvm-import java.io.FileReader
  (new [File]))

(jvm-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")]
    (let% [<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))