aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/io.jvm.lux
blob: 21c3da25640c82f6ac41f29c3ba6e281730ca84d (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
(;module:
  lux
  (lux (control monad
                ["ex" exception #+ exception:])
       [io #+ Process]
       (concurrency ["P" promise]
                    ["T" task])
       (data ["e" error]
             [text "text/" Eq<Text>]
             text/format)
       [macro]
       [host]
       (world [file #+ File]
              [blob #+ Blob])))

(host;import java.lang.String
  (new [(Array byte)]))

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

(exception: #export File-Not-Found)
(exception: #export Module-Not-Found)
(exception: #export Could-Not-Read-All-Data)

(host;import #long java.io.File
  (new [String])
  (exists [] #io #try boolean)
  (mkdir [] #io #try boolean)
  (delete [] #io #try boolean)
  (length [] #io #try long)
  (listFiles [] #io #try (Array java.io.File))
  (getAbsolutePath [] #io #try String)
  (isFile [] #io #try boolean)
  (isDirectory [] #io #try boolean))

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

(host;import java.io.InputStream
  (read [(Array byte)] #io #try int))

(host;import java.io.FileInputStream
  (new [java.io.File] #io #try))

(def: file-exists?
  (-> File (Process Bool))
  (|>. java.io.File.new (java.io.File.exists [])))

(def: (find-source path dirs)
  (-> Text (List File) (Process [Text File]))
  (case dirs
    #;Nil
    (io;fail (File-Not-Found path))

    (#;Cons dir dirs')
    (do io;Monad<Process>
      [#let [file (format dir "/" path)]
       ? (file-exists? file)]
      (if ?
        (wrap [path file])
        (find-source path dirs')))))

(def: (either left right)
  (All [a] (-> (Process a) (Process a) (Process a)))
  (do io;Monad<IO>
    [?output left]
    (case ?output
      (#e;Success output)
      (wrap (#e;Success output))

      (#e;Error error)
      right)))

(def: #export (read-file file)
  (-> File (Process Blob))
  (do io;Monad<Process>
    [#let [file' (java.io.File.new file)]
     size (java.io.File.length [] file')
     #let [data (blob;create (int-to-nat size))]
     stream (FileInputStream.new [file'])
     bytes-read (InputStream.read [data] stream)
     _ (AutoCloseable.close [] stream)]
    (if (i.= size bytes-read)
      (wrap data)
      (io;fail (Could-Not-Read-All-Data file)))))

(def: #export (read-module dirs name)
  (-> (List File) Text (Process [File Text]))
  (let [host-path (format name host-extension lux-extension)
        lux-path (format name lux-extension)]
    (do io;Monad<Process>
      [[path file] (: (Process [Text File])
                      ($_ either
                          (find-source host-path dirs)
                          (find-source lux-path dirs)
                          (io;fail (Module-Not-Found name))))
       blob (read-file file)]
      (wrap [path (String.new blob)]))))

(def: #export (write-module name descriptor)
  (-> Text Text (T;Task Unit))
  (T;fail "'write-module' is undefined."))

(def: (platform-target root-target)
  (-> File File)
  (format root-target "/" (for {"JVM" "jvm"
                                "JS" "js"})))

(def: #export (prepare-target target-dir)
  (-> File (T;Task Unit))
  (do T;Monad<Task>
    [_ (file;make-dir target-dir)
     _ (file;make-dir (platform-target target-dir))]
    (wrap [])))

(def: #export (prepare-module target-dir module-name)
  (-> File Text (T;Task Unit))
  (do T;Monad<Task>
    [_ (file;make-dir (format (platform-target target-dir) "/" module-name))]
    (wrap [])))

(def: #export (write-file target-dir file-name content)
  (-> File Text Blob (T;Task Unit))
  (|> file-name
      (format (platform-target target-dir) "/")
      (file;write content)))