git.m455.casa

fa

clone url: git://git.m455.casa/fa


esperbuild/espersrc/fennel-0.7.0/src/launcher.fnl

1 ;; This is the command-line entry point for Fennel.
2
3 (local fennel (require :fennel))
4 (local unpack (or _G.unpack table.unpack))
5
6 (local help "
7 Usage: fennel [FLAG] [FILE]
8
9 Run fennel, a lisp programming language for the Lua runtime.
10
11 --repl : Command to launch an interactive repl session
12 --compile FILES : Command to AOT compile files, writing Lua to stdout
13 --eval SOURCE (-e) : Command to evaluate source code and print the result
14
15 --no-searcher : Skip installing package.searchers entry
16 --indent VAL : Indent compiler output with VAL
17 --add-package-path PATH : Add PATH to package.path for finding Lua modules
18 --add-fennel-path PATH : Add PATH to fennel.path for finding Fennel modules
19 --globals G1[,G2...] : Allow these globals in addition to standard ones
20 --globals-only G1[,G2] : Same as above, but exclude standard ones
21 --require-as-include : Inline required modules in the output
22 --metadata : Enable function metadata, even in compiled output
23 --no-metadata : Disable function metadata, even in REPL
24 --correlate : Make Lua output line numbers match Fennel input
25 --load FILE (-l) : Load the specified FILE before executing the command
26 --lua LUA_EXE : Run in a child process with LUA_EXE (experimental)
27 --no-fennelrc : Skip loading ~/.fennelrc when launching repl
28 --plugin FILE : Activate the compiler plugin in FILE
29 --compile-binary FILE
30 OUT LUA_LIB LUA_DIR : Compile FILE to standalone binary OUT (experimental)
31 --compile-binary --help : Display further help for compiling binaries
32 --no-compiler-sandbox : Do not limit compiler environment to minimal sandbox
33
34 --help (-h) : Display this text
35 --version (-v) : Show version
36
37 Globals are not checked when doing AOT (ahead-of-time) compilation unless
38 the --globals-only flag is provided.
39
40 Metadata is typically considered a development feature and is not recommended
41 for production. It is used for docstrings and enabled by default in the REPL.
42
43 When not given a command, runs the file given as the first argument.
44 When given neither command nor file, launches a repl.
45
46 If ~/.fennelrc exists, loads it before launching a repl.")
47
48 (local options {:plugins []})
49
50 (fn dosafely [f ...]
51 (let [args [...]
52 (ok val) (xpcall #(f (unpack args)) fennel.traceback)]
53 (when (not ok)
54 (io.stderr:write (.. val "\n"))
55 (os.exit 1))
56 val))
57
58 (fn allow-globals [global-names]
59 (set options.allowedGlobals [])
60 (each [g (global-names:gmatch "([^,]+),?")]
61 (table.insert options.allowedGlobals g)))
62
63 (fn handle-load [i]
64 (let [file (table.remove arg (+ i 1))]
65 (dosafely fennel.dofile file options)
66 (table.remove arg i)))
67
68 (fn handle-lua [i]
69 (table.remove arg i) ; remove the --lua flag from args
70 (let [tgt-lua (table.remove arg i)
71 cmd [(string.format "%s %s" tgt-lua (. arg 0))]]
72 (for [i 1 (# arg)] ; quote args to prevent shell escapes when executing
73 (table.insert cmd (string.format "%q" (. arg i))))
74 (let [ok (os.execute (table.concat cmd " "))]
75 (os.exit (if ok 0 1) true))))
76
77 ;; check for --lua first to ensure its child process retains all flags
78 (for [i (# arg) 1 -1]
79 (match (. arg i) "--lua" (handle-lua i)))
80
81 (for [i (# arg) 1 -1]
82 (match (. arg i)
83 "--no-searcher" (do (set options.no_searcher true)
84 (table.remove arg i))
85 "--indent" (do (set options.indent (table.remove arg (+ i 1)))
86 (when (= options.indent "false")
87 (set options.indent false))
88 (table.remove arg i))
89 "--add-package-path" (let [entry (table.remove arg (+ i 1))]
90 (set package.path (.. entry ";" package.path))
91 (table.remove arg i))
92 "--add-fennel-path" (let [entry (table.remove arg (+ i 1))]
93 (set fennel.path (.. entry ";" fennel.path))
94 (table.remove arg i))
95 "--load" (handle-load i)
96 "-l" (handle-load i)
97 "--no-fennelrc" (do (set options.fennelrc false)
98 (table.remove arg i))
99 "--correlate" (do (set options.correlate true)
100 (table.remove arg i))
101 "--check-unused-locals" (do (set options.checkUnusedLocals true)
102 (table.remove arg i))
103 "--globals" (do (allow-globals (table.remove arg (+ i 1)))
104 (each [global-name (pairs _G)]
105 (table.insert options.allowedGlobals global-name))
106 (table.remove arg i))
107 "--globals-only" (do (allow-globals (table.remove arg (+ i 1)))
108 (table.remove arg i))
109 "--require-as-include" (do (set options.requireAsInclude true)
110 (table.remove arg i))
111 "--metadata" (do (set options.useMetadata true)
112 (table.remove arg i))
113 "--no-metadata" (do (set options.useMetadata false)
114 (table.remove arg i))
115 "--no-compiler-sandbox" (do (set options.compiler-env _G)
116 (table.remove arg i))
117 "--plugin" (let [plugin (fennel.dofile (table.remove arg (+ i 1))
118 {:env :_COMPILER})]
119 (table.insert options.plugins 1 plugin)
120 (table.remove arg i))))
121
122 (when (not options.no_searcher)
123 (let [opts []]
124 (each [k v (pairs options)]
125 (tset opts k v))
126 (table.insert (or package.loaders package.searchers)
127 (fennel.make-searcher opts))))
128
129 (fn try-readline [ok readline]
130 (when ok
131 (when readline.set_readline_name
132 (readline.set_readline_name "fennel"))
133 (readline.set_options {:keeplines 1000 :histfile ""})
134 (fn options.readChunk [parser-state]
135 (let [prompt (if (< 0 parser-state.stack-size) ".. " ">> ")
136 str (readline.readline prompt)]
137 (if str (.. str "\n"))))
138 (var completer nil)
139 (fn options.registerCompleter [repl-completer]
140 (set completer repl-completer))
141 (fn repl-completer [text from to]
142 (if completer
143 (do (readline.set_completion_append_character "")
144 (completer (text:sub from to)))
145 []))
146 (readline.set_complete_function repl-completer)
147 readline))
148
149 (fn load-initfile []
150 (let [home (or (os.getenv "HOME") "/")
151 xdg-config-home (or (os.getenv "XDG_CONFIG_HOME") (.. home "/.config"))
152 xdg-initfile (.. xdg-config-home "/fennel/fennelrc")
153 home-initfile (.. home "/.fennelrc")
154 init (io.open xdg-initfile :rb)
155 init-filename (if init xdg-initfile home-initfile)
156 init (or init (io.open home-initfile :rb))]
157 (when init
158 (init:close)
159 (dosafely fennel.dofile init-filename options options fennel))))
160
161 (fn repl []
162 (let [readline (try-readline (pcall require :readline))]
163 (set options.pp (require :fennelview))
164 (when (not= false options.fennelrc)
165 (load-initfile))
166 (print (.. "Welcome to Fennel " fennel.version " on " _VERSION "!"))
167 (print "Use ,help to see available commands.")
168 (when (not readline)
169 (print "Try installing readline via luarocks for a better repl experience."))
170 (fennel.repl options)
171 (when readline
172 (readline.save_history))))
173
174 (fn eval [form]
175 (print (dosafely fennel.eval (if (= form "-")
176 (io.stdin:read :*a)
177 form) options)))
178
179 (match arg
180 ([] ? (= 0 (# arg))) (repl)
181 ["--repl"] (repl)
182 ["--compile" & files] (each [_ filename (ipairs files)]
183 (set options.filename filename)
184 (let [f (if (= filename "-")
185 io.stdin
186 (assert (io.open filename :rb)))
187 (ok val) (xpcall #(fennel.compile-string
188 (f:read :*a) options)
189 fennel.traceback)]
190 (if ok
191 (print val)
192 (do (io.stderr:write (.. val "\n"))
193 (os.exit 1)))
194 (f:close)))
195 ["--compile-binary" filename out
196 static-lua lua-include-dir & args] (let [bin (require :fennel.binary)]
197 (set options.filename filename)
198 (set options.requireAsInclude true)
199 (bin.compile filename out
200 static-lua lua-include-dir
201 options args))
202 ["--compile-binary"] (print (. (require :fennel.binary) :help))
203
204 ["--eval" form] (eval form)
205 ["-e" form] (eval form)
206 ["--version"] (print (.. "Fennel " fennel.version " on " _VERSION))
207 ["--help"] (print help)
208 ["-h"] (print help)
209 ["-" & args] (dosafely fennel.eval (io.stdin:read :*a))
210 [filename & args] (do (tset arg -2 (. arg -1))
211 (tset arg -1 (. arg 0))
212 (tset arg 0 (table.remove arg 1))
213 (dosafely fennel.dofile filename options (unpack args))))