aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/program.lux
blob: 62c3ad03d22985425611a3575d3e5a02ef4f4c3f (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
(.module:
  [lux #*
   [control
    [monad (#+ do)]
    ["p" parser]]
   [concurrency
    ["." promise (#+ Promise)]
    [task (#+ Task)]]
   [data
    ["e" error]
    [text
     format]]
   ["." io (#- run)]
   [time
    ["." instant]]
   ["." cli (#+ CLI program:)]
   [world
    [file (#+ File)]]]
  [luxc
   ["." repl]
   [lang
    [".L" translation]]])

(type: Build
  {#build-sources (List File)
   #build-target File
   #build-program Text})

(type: REPL
  {#repl-sources (List File)
   #repl-target File})

(def: (param [short long])
  (-> [Text Text] (CLI Text))
  (cli.somewhere (p.after (p.either (cli.this short) (cli.this long))
                          cli.any)))

(def: build
  (CLI Build)
  ($_ p.seq
      (p.some (param ["-s" "--source"]))
      (param ["-t" "--target"])
      (param ["-p" "--program"])))

(def: repl
  (CLI REPL)
  ($_ p.seq
      (p.some (param ["-s" "--source"]))
      (param ["-t" "--target"])))

(type: Service
  (#Build Build)
  (#REPL REPL))

(def: service
  (CLI Service)
  (p.or (p.after (cli.this "build") build)
        (p.after (cli.this "repl") repl)))

(def: (or-crash! failure-describer action)
  (All [a] (-> Text (Task a) (Promise a)))
  (do promise.Monad<Promise>
    [?output action]
    (case ?output
      (#e.Error error)
      (exec (log! (format "\n"
                          failure-describer "\n"
                          error "\n"))
        ("lux io exit" 1))

      (#e.Success output)
      (wrap output))))

(program: [{service ..service}]
  (exec (case service
          (#Build [sources target program])
          (<| (or-crash! "Compilation failed:")
              (promise.future
               (do io.Monad<Process>
                 [#let [start (io.run instant.now)]
                  result (translationL.translate-program sources target program)
                  #let [end (io.run instant.now)
                        _ (log! (format "\n" "Elapsed time: " (%duration (instant.span start end))))]]
                 (wrap result))))
          
          (#REPL [sources target])
          (<| (or-crash! "REPL failed:")
              (repl.run sources target)))
    (io [])))