git.m455.casa

fa

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


esperbuild/espersrc/fennel-0.7.0/old/launcher.lua

1 #!/usr/bin/env lua
2
3 -- This is the old version of the launcher wrapper script; we keep it around
4 -- for bootstraping purposes to avoid chicken/egg problems using launcher.fnl
5 -- to compile Fennel itself. In general there is no need to keep this file in
6 -- sync with launcher.fnl; changes for new features should just go there.
7
8 local fennel_dir = arg[0]:match("(.-)[^\\/]+$")
9 package.path = fennel_dir .. "?.lua;" .. package.path
10 local fennel = require('fennel')
11 local unpack = unpack or table.unpack
12
13 local help = [[
14 Usage: fennel [FLAG] [FILE]
15
16 Run fennel, a lisp programming language for the Lua runtime.
17
18 --repl : Command to launch an interactive repl session
19 --compile FILES : Command to compile files and write Lua to stdout
20 --eval SOURCE (-e) : Command to evaluate source code and print the result
21
22 --no-searcher : Skip installing package.searchers entry
23 --indent VAL : Indent compiler output with VAL
24 --add-package-path PATH : Add PATH to package.path for finding Lua modules
25 --add-fennel-path PATH : Add PATH to fennel.path for finding Fennel modules
26 --globals G1[,G2...] : Allow these globals in addition to standard ones
27 --globals-only G1[,G2] : Same as above, but exclude standard ones
28 --check-unused-locals : Raise error when compiling code with unused locals
29 --require-as-include : Inline required modules in the output
30 --metadata : Enable function metadata, even in compiled output
31 --no-metadata : Disable function metadata, even in REPL
32 --correlate : Make Lua output line numbers match Fennel input
33 --load FILE (-l) : Load the specified FILE before executing the command
34 --no-fennelrc : Skip loading ~/.fennelrc when launching repl
35
36 --help (-h) : Display this text
37 --version (-v) : Show version
38
39 Metadata is typically considered a development feature and is not recommended
40 for production. It is used for docstrings and enabled by default in the REPL.
41
42 When not given a command, runs the file given as the first argument.
43 When given neither command nor file, launches a repl.
44
45 If ~/.fennelrc exists, loads it before launching a repl.]]
46
47 local options = {}
48
49 local function dosafe(filename, opts, args)
50 local ok, val = xpcall(function()
51 return fennel.dofile(filename, opts, unpack(args))
52 end, fennel.traceback)
53 if not ok then
54 io.stderr:write(val .. "\n")
55 os.exit(1)
56 end
57 return val
58 end
59
60 local function allowGlobals(globalNames)
61 options.allowedGlobals = {}
62 for g in globalNames:gmatch("([^,]+),?") do
63 table.insert(options.allowedGlobals, g)
64 end
65 end
66
67 for i=#arg, 1, -1 do
68 if arg[i] == "--no-searcher" then
69 options.no_searcher = true
70 table.remove(arg, i)
71 elseif arg[i] == "--indent" then
72 options.indent = table.remove(arg, i+1)
73 if options.indent == "false" then options.indent = false end
74 table.remove(arg, i)
75 elseif arg[i] == "--add-package-path" then
76 local entry = table.remove(arg, i+1)
77 package.path = entry .. ";" .. package.path
78 table.remove(arg, i)
79 elseif arg[i] == "--add-fennel-path" then
80 local entry = table.remove(arg, i+1)
81 fennel.path = entry .. ";" .. fennel.path
82 table.remove(arg, i)
83 elseif arg[i] == "--load" or arg[i] == "-l" then
84 local file = table.remove(arg, i+1)
85 dosafe(file, options, {})
86 table.remove(arg, i)
87 elseif arg[i] == "--no-fennelrc" then
88 options.fennelrc = false
89 table.remove(arg, i)
90 elseif arg[i] == "--correlate" then
91 options.correlate = true
92 table.remove(arg, i)
93 elseif arg[i] == "--check-unused-locals" then
94 options.checkUnusedLocals = true
95 table.remove(arg, i)
96 elseif arg[i] == "--globals" then
97 allowGlobals(table.remove(arg, i+1))
98 for globalName in pairs(_G) do
99 table.insert(options.allowedGlobals, globalName)
100 end
101 table.remove(arg, i)
102 elseif arg[i] == "--globals-only" then
103 allowGlobals(table.remove(arg, i+1))
104 table.remove(arg, i)
105 elseif arg[i] == "--require-as-include" then
106 options.requireAsInclude = true
107 table.remove(arg, i)
108 elseif arg[i] == "--metadata" then
109 options.useMetadata = true
110 table.remove(arg, i)
111 elseif arg[i] == "--no-metadata" then
112 options.useMetadata = false
113 table.remove(arg, i)
114 end
115 end
116
117 if not options.no_searcher then
118 local opts = {}
119 for k,v in pairs(options) do opts[k] = v end
120 table.insert((package.loaders or package.searchers), fennel.make_searcher(opts))
121 end
122
123 -- Try to load readline library
124 local function tryReadline(opts)
125 local readline_ok, readline = pcall(require, "readline")
126 if readline_ok then
127 if readline.set_readline_name then -- added as of readline.lua 2.6-0
128 readline.set_readline_name('fennel')
129 end
130 readline.set_options({
131 keeplines = 1000, histfile = '', })
132 function opts.readChunk(parserState)
133 local prompt = parserState.stackSize > 0 and '.. ' or '>> '
134 local str = readline.readline(prompt)
135 if str then
136 return str .. "\n"
137 end
138 end
139
140 -- completer is registered by the repl, until then returns empty list
141 local completer
142 function opts.registerCompleter(replCompleter)
143 completer = replCompleter
144 end
145 local function replCompleter(text, from, to)
146 if completer then
147 -- stop completed syms from adding extra space on match
148 readline.set_completion_append_character('')
149 return completer(text:sub(from, to))
150 else
151 return {}
152 end
153 end
154 readline.set_complete_function(replCompleter)
155 return readline
156 end
157 end
158
159 -- TODO: generalize this instead of hardcoding it
160 local fok, friendly = pcall(fennel.dofile, fennel_dir .. "fennelfriend.fnl", options)
161 if fok then
162 options["assert-compile"] = friendly["assert-compile"]
163 options["parse-error"] = friendly["parse-error"]
164 end
165
166 if arg[1] == "--repl" or #arg == 0 then
167 local ppok, pp = pcall(fennel.dofile, fennel_dir .. "fennelview.fnl", options)
168 if ppok then
169 options.pp = pp
170 else
171 ppok, pp = pcall(require, "fennelview")
172 if ppok then
173 options.pp = pp
174 end
175 end
176
177 local readline = tryReadline(options)
178
179 if options.fennelrc ~= false then
180 local home = os.getenv("HOME")
181 local xdg_config_home = os.getenv("XDG_CONFIG_HOME") or home .. "/.config"
182 local xdg_initfile = xdg_config_home .. "/fennel/fennelrc"
183 local home_initfile = home .. "/.fennelrc"
184 local init, initFilename = io.open(xdg_initfile, "rb"), xdg_initfile
185 if not init then
186 init, initFilename = io.open(home_initfile, "rb"), home_initfile
187 end
188
189 if init then
190 init:close()
191 -- pass in options so fennerlrc can make changes to it
192 dosafe(initFilename, options, {options})
193 end
194 end
195
196 print("Welcome to Fennel " .. fennel.version .. "!")
197 if options.useMetadata ~= false then
198 print("Use (doc something) to view documentation.")
199 end
200 fennel.repl(options)
201 -- if readline loaded, persist history (noop if histfile == '')
202 if readline then readline.save_history() end
203 elseif arg[1] == "--compile" then
204 for i = 2, #arg do
205 local f = arg[i] == "-" and io.stdin or assert(io.open(arg[i], "rb"))
206 options.filename=arg[i]
207 local ok, val = xpcall(function()
208 return fennel.compileString(f:read("*all"), options)
209 end, fennel.traceback)
210 if ok then
211 print(val)
212 else
213 io.stderr:write(val .. "\n")
214 os.exit(1)
215 end
216 f:close()
217 end
218 elseif arg[1] == "--eval" or arg[1] == "-e" then
219 if arg[2] and arg[2] ~= "-" then
220 print(fennel.eval(arg[2], options))
221 else
222 local source = io.stdin:read("*a")
223 print(fennel.eval(source, options))
224 end
225 elseif arg[1] == "--version" or arg[1] == "-v" then
226 print("Fennel " .. fennel.version)
227 elseif #arg >= 1 and arg[1] ~= "--help" and arg[1] ~= "-h" then
228 local filename = table.remove(arg, 1) -- let the script have remaining args
229 if filename == "-" then
230 local source = io.stdin:read("*a")
231 fennel.eval(source, options)
232 else
233 dosafe(filename, options, arg)
234 end
235 else
236 print(help)
237 end