forked from sctb/lumen
-
Notifications
You must be signed in to change notification settings - Fork 2
/
system.l
149 lines (126 loc) · 3.98 KB
/
system.l
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(target js: (define fs (require 'fs)))
(target js: (define child_process (require 'child_process)))
(target lua:
(define call-with-file (f path mode)
(let ((h e) (list ((get io 'open) path mode)))
(unless h
(error e))
(with x (f h)
((get h 'close) h)))))
(define read-file (path)
(target
js: ((get fs 'readFileSync) path 'utf8)
lua: (call-with-file
(fn (f) ((get f 'read) f '*a))
path)))
(define write-file (path data)
(target
js: ((get fs 'writeFileSync) path data 'utf8)
lua: (call-with-file
(fn (f) ((get f 'write) f data))
path 'w)))
(define file-exists? (path)
(target
js: (and ((get fs 'existsSync) path 'utf8)
((get ((get fs 'statSync) path) 'isFile)))
lua: (let f ((get io 'open) path)
(and (is? f)
(with r (or (is? ((get f 'read) f 0))
(= 0 ((get f 'seek) f 'end)))
((get f 'close) f))))))
(define directory-exists? (path)
(target
js: (and ((get fs 'existsSync) path 'utf8)
((get ((get fs 'statSync) path) 'isDirectory)))
lua: (let f ((get io 'open) path)
(and (is? f)
(with r (and (not ((get f 'read) f 0))
(not (= 0 ((get f 'seek) f 'end))))
((get f 'close) f))))))
(define path-separator
(target
js: (get (require 'path) 'sep)
lua: (char (get (get _G 'package) 'config) 0)))
(define path-join (a ...)
(reduce (fn (x y) (cat x path-separator y)) (list ...) a))
(define get-environment-variable (name)
(target
js: (get (get process 'env) name)
lua: ((get os 'getenv) name)))
(define stdout ()
((or process io) .stdout))
(define stderr ()
((or process io) .stderr))
(define write (x out)
((or out (stdout)) (.write x)))
(define exit (code)
(target js: ((get process 'exit) code)
lua: ((get os 'exit) code)))
(define argv nil)
(define-global set-argv (l)
(set argv l))
(define-global get-argv ()
(when (nil? argv)
(set-argv (target js: (cut (get process 'argv) 2)
lua: (or (get _G 'arg) (get _G 'args) ()))))
argv)
(define opt? (x)
(and (string? x) (= (char x 0) "-") (not (= x "-"))))
(define-global parse-positional (args pos)
(cut args (either pos 0) (first opt? args pos)))
(define-global parse-option (args)
(when (opt? (hd args))
`(,(hd args) ,(parse-positional args 1))))
(define-global parse-arguments (aliases argv)
(let (l (or argv (get-argv))
a (or aliases (obj)))
(with r (parse-positional l)
(set l (cut l (# r)))
(while true
(let p (parse-option l)
(unless p (break))
(let-when (op args) p
(when (= op "--")
(set l (cut l 1))
(break))
(set l (cut l (+ 1 (# args))))
(let (k (if (= (clip op 0 2) "--") (clip op 2) (clip op 1))
k (or (get a k) k)
v (if (none? args) true args))
(set (get r k) v)
(add r (list k v))))))
(set (get r 'rest) l)
(set-argv (get r 'rest)))))
(define-global arguments (aliases argv)
(let argv (or argv (get-argv))
(let r (parse-arguments argv aliases)
(set-argv (get r 'rest))
(wipe (get r 'rest))
(unless (empty? r) r))))
(define reload (module)
(wipe (target
lua: (get (get package 'loaded) module)
js: (get (get require 'cache) ((get require 'resolve) module))))
(require module))
(define run (command)
(target
js: ((get ((get child_process 'execSync) command) 'toString))
lua: (let f ((get io 'popen) command)
(with x ((get f 'read) f '*all)
((get f 'close) f)))))
(export read-file
write-file
file-exists?
directory-exists?
path-separator
path-join
get-environment-variable
stdout
stderr
write
exit
get-argv
set-argv
arguments
reload
run)