aboutsummaryrefslogtreecommitdiff
path: root/nomsu.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nomsu.lua')
-rw-r--r--nomsu.lua232
1 files changed, 134 insertions, 98 deletions
diff --git a/nomsu.lua b/nomsu.lua
index 08ab170..1b5a73e 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -59,15 +59,16 @@ else
end
local usage = [=[Nomsu Compiler
-Usage: (nomsu | lua nomsu.lua | moon nomsu.moon) [-V version] [-O optimization level] [-v] [-c] [-s] [-I file] [--help | -h] [--version] [--no-core] [file [nomsu args...]]
+Usage: (nomsu | lua nomsu.lua | moon nomsu.moon) [-V version] [--help | -h] [--version] [-O optimization level] [-v] [-c] [-s] [-d debugger] [--no-core] [(file | -t tool | -e "nomsu code..." | -m files... [--]) [nomsu args...]]
OPTIONS
+ -t <tool> Run a tool.
+ -e Execute the specified string.
+ -m Run multiple files (all extra arguments).
-O <level> Run the compiler with the given optimization level (>0: use precompiled .lua versions of Nomsu files, when available).
-v Verbose: print compiled lua code.
-c Compile the input files into a .lua files.
- -e Execute the specified string.
-s Check the input files for syntax errors.
- -I <file> Add an additional input file or directory.
-d <debugger> Attempt to use the specified debugger to wrap the main body of execution.
-h/--help Print this message.
--version Print the version number and exit.
@@ -99,36 +100,31 @@ local nomsu_environment = require('nomsu_environment')
if not arg or debug.getinfo(2).func == require then
return nomsu_environment
end
-local file_queue = List({ })
local sep = "\3"
-local parser = re.compile([[ args <- {| (flag %sep)* (({~ file ~} -> add_file) {:primary_file: %true :} %sep)?
- {:nomsu_args: {| (nomsu_flag %sep)* {:extra_args: {| ({[^%sep]+} %sep)* |} :} |} :} |} !.
+local parser = re.compile([[ args <- {| (flag %sep)*
+ (("-e" %sep {:execute: {[^%sep]+} :} %sep)
+ / {:files: {|
+ ("-t" %sep {~ {[^%sep]+} -> "nomsu://tools/%1.nom" ~} %sep
+ / "-m" %sep (!("--" %sep) {[^%sep]+} %sep)* ("--" %sep)?
+ / {[^%sep]+} %sep
+ / {~ '' %sep? -> 'nomsu://tools/repl.nom' ~}) |} :})
+ {:nomsu_args: {| (nomsu_flag %sep)* {:extra_args: {| ({[^%sep]+} %sep)* |} :} |} :}
+ |} !.
flag <-
{:optimization: "-O" (%sep? %number)? :}
- / ("-I" %sep? ({~ file ~} -> add_file))
- / ("-e" %sep? (({} {~ file ~}) -> add_exec_string) {:exec_strings: %true :})
/ ({:check_syntax: "-s" %true:})
/ ({:compile: "-c" %true:})
/ {:verbose: "-v" %true :}
/ {:help: ("-h" / "--help") %true :}
/ {:version: "--version" %true :}
/ {:no_core: "--no-core" %true :}
- / {:debugger: ("-d" %sep? {(!%sep .)*}) :}
+ / {:debugger: ("-d" %sep? {[^%sep]*}) :}
/ {:requested_version: "-V" (%sep? {([0-9.])+})? :}
nomsu_flag <- {| ({:key: ('-' [a-z]) :} {:value: %true :}) / ({:key: ('--' [^%sep=]+) :} {:value: ('=' {[^%sep]+}) / %true :}) |}
- file <- ("-" -> "stdin") / {(!%sep .)+}
]], {
["true"] = lpeg.Cc(true),
number = lpeg.R("09") ^ 1 / tonumber,
- sep = lpeg.P(sep),
- add_file = function(f)
- return file_queue:add(f)
- end,
- add_exec_string = function(pos, s)
- local name = "command line arg @" .. tostring(pos) .. ".nom"
- Files.spoof(name, s)
- return file_queue:add(name)
- end
+ sep = lpeg.P(sep)
})
local arg_string = table.concat(arg, sep) .. sep
local args = parser:match(arg_string)
@@ -145,98 +141,138 @@ end
nomsu_args.extra_args = List(args.nomsu_args.extra_args or { })
nomsu_environment.command_line_args = nomsu_args
nomsu_environment.OPTIMIZATION = tonumber(args.optimization or 1)
-if args.version then
- nomsu_environment.run_file_1_in('core', nomsu_environment, nomsu_environment.OPTIMIZATION)
- nomsu_environment.run_1_in([[say (Nomsu version)]], nomsu_environment)
- os.exit(EXIT_SUCCESS)
-end
local run
run = function()
- local input_files = { }
- for _index_0 = 1, #file_queue do
- local f = file_queue[_index_0]
- if not (Files.exists(f)) then
- error("Could not find: '" .. tostring(f) .. "'")
- end
- local _list_1 = Files.list(f)
- for _index_1 = 1, #_list_1 do
- local filename = _list_1[_index_1]
- input_files[filename] = true
- end
- end
if not (args.no_core) then
- nomsu_environment.run_file_1_in('core', nomsu_environment, nomsu_environment.OPTIMIZATION)
- end
- for _index_0 = 1, #file_queue do
- local _continue_0 = false
- repeat
- local filename = file_queue[_index_0]
- if not (filename == "stdin" or filename:match("%.nom$")) then
+ for nomsupath in package.nomsupath:gmatch("[^;]+") do
+ local _continue_0 = false
+ repeat
+ local files = Files.list(nomsupath .. "/core")
+ if not (files) then
+ _continue_0 = true
+ break
+ end
+ for _index_0 = 1, #files do
+ local _continue_1 = false
+ repeat
+ local f = files[_index_0]
+ if not (f:match("%.nom$")) then
+ _continue_1 = true
+ break
+ end
+ nomsu_environment.run_file_1_in(f, nomsu_environment, nomsu_environment.OPTIMIZATION)
+ _continue_1 = true
+ until true
+ if not _continue_1 then
+ break
+ end
+ end
_continue_0 = true
+ until true
+ if not _continue_0 then
break
end
- if args.check_syntax then
- local code = Files.read(filename)
- local source = Source(filename, 1, #code)
- nomsu_environment._1_parsed(NomsuCode:from(source, code))
- print("Parse succeeded: " .. tostring(filename))
- elseif args.compile then
- local output
- if filename == 'stdin' then
- output = io.output()
- else
- output = io.open(filename:gsub("%.nom$", ".lua"), "w")
- end
- local code = Files.read(filename)
- local source = Source(filename, 1, #code)
- code = NomsuCode:from(source, code)
- local tree = nomsu_environment._1_parsed(code)
- if not (tree.type == 'FileChunks') then
- tree = {
- tree
- }
- end
- for chunk_no, chunk in ipairs(tree) do
- local lua = nomsu_environment.compile(chunk)
- lua:declare_locals()
- lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n")
- if args.verbose then
- print(lua:text())
+ end
+ end
+ if args.version then
+ nomsu_environment.run_1_in("say (Nomsu version)", nomsu_environment)
+ os.exit(EXIT_SUCCESS)
+ end
+ local input_files = { }
+ if args.execute then
+ table.insert(input_files, Files.spoof("<input command>", args.execute))
+ end
+ if args.files then
+ local _list_1 = args.files
+ for _index_0 = 1, #_list_1 do
+ local f = _list_1[_index_0]
+ local files
+ do
+ local nomsu_name = f:match("^nomsu://(.*)")
+ if nomsu_name then
+ for nomsupath in package.nomsupath:gmatch("[^;]+") do
+ local _continue_0 = false
+ repeat
+ files = Files.list(nomsupath .. "/" .. nomsu_name)
+ if not (files) then
+ _continue_0 = true
+ break
+ end
+ _continue_0 = true
+ until true
+ if not _continue_0 then
+ break
+ end
end
- nomsu_environment.run_1_in(chunk, nomsu_environment)
- output:write(lua:text(), "\n")
- end
- print(("Compiled %-25s -> %s"):format(filename, filename:gsub("%.nom$", ".lua")))
- output:close()
- elseif args.verbose then
- local code = Files.read(filename)
- local source = Source(filename, 1, #code)
- code = NomsuCode:from(source, code)
- local tree = nomsu_environment._1_parsed(code)
- if not (tree.type == 'FileChunks') then
- tree = {
- tree
- }
+ else
+ files = Files.list(f)
end
- for chunk_no, chunk in ipairs(tree) do
- local lua = nomsu_environment.compile(chunk)
- lua:declare_locals()
- lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n")
+ end
+ if not (files and #files > 0) then
+ error("Could not find: '" .. tostring(f) .. "'")
+ end
+ for _index_1 = 1, #files do
+ local filename = files[_index_1]
+ table.insert(input_files, filename)
+ end
+ end
+ end
+ for _index_0 = 1, #input_files do
+ local filename = input_files[_index_0]
+ if args.check_syntax then
+ local code = Files.read(filename)
+ local source = Source(filename, 1, #code)
+ nomsu_environment._1_parsed(NomsuCode:from(source, code))
+ print("Parse succeeded: " .. tostring(filename))
+ elseif args.compile then
+ local output
+ if filename == 'stdin' then
+ output = io.output()
+ else
+ output = io.open(filename:gsub("%.nom$", ".lua"), "w")
+ end
+ local code = Files.read(filename)
+ local source = Source(filename, 1, #code)
+ code = NomsuCode:from(source, code)
+ local tree = nomsu_environment._1_parsed(code)
+ if not (tree.type == 'FileChunks') then
+ tree = {
+ tree
+ }
+ end
+ for chunk_no, chunk in ipairs(tree) do
+ local lua = nomsu_environment.compile(chunk)
+ lua:declare_locals()
+ lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n")
+ if args.verbose then
print(lua:text())
- nomsu_environment.run_1_in(lua, nomsu_environment)
end
- else
- nomsu_environment.run_file_1_in(filename, nomsu_environment, 0)
+ nomsu_environment.run_1_in(chunk, nomsu_environment)
+ output:write(lua:text(), "\n")
+ end
+ print(("Compiled %-25s -> %s"):format(filename, filename:gsub("%.nom$", ".lua")))
+ output:close()
+ elseif args.verbose then
+ local code = Files.read(filename)
+ local source = Source(filename, 1, #code)
+ code = NomsuCode:from(source, code)
+ local tree = nomsu_environment._1_parsed(code)
+ if not (tree.type == 'FileChunks') then
+ tree = {
+ tree
+ }
end
- _continue_0 = true
- until true
- if not _continue_0 then
- break
+ for chunk_no, chunk in ipairs(tree) do
+ local lua = nomsu_environment.compile(chunk)
+ lua:declare_locals()
+ lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n")
+ print(lua:text())
+ nomsu_environment.run_1_in(lua, nomsu_environment)
+ end
+ else
+ nomsu_environment.run_file_1_in(filename, nomsu_environment, 0)
end
end
- if not (args.primary_file or args.exec_strings) then
- return nomsu_environment.run_file_1_in("tools/repl.nom", nomsu_environment, nomsu_environment.OPTIMIZATION)
- end
end
local debugger
if args.debugger == "nil" then