Merge branch 'master' into patch-1

This commit is contained in:
leaf 2022-11-04 12:51:40 -07:00 committed by GitHub
commit b972b0d538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 163 additions and 159 deletions

View File

@ -1,6 +1,6 @@
LUA ?= lua5.1 LUA ?= lua5.1
LUA_VERSION = $(shell $(LUA) -e 'print(_VERSION:match("%d%.%d"))') LUA_VERSION = $(shell $(LUA) -e 'print(_VERSION:match("%d%.%d"))')
LUAROCKS = luarocks-$(LUA_VERSION) LUAROCKS = luarocks --lua-version=$(LUA_VERSION)
LUA_PATH_MAKE = $(shell $(LUAROCKS) path --lr-path);./?.lua;./?/init.lua LUA_PATH_MAKE = $(shell $(LUAROCKS) path --lr-path);./?.lua;./?/init.lua
LUA_CPATH_MAKE = $(shell $(LUAROCKS) path --lr-cpath);./?.so LUA_CPATH_MAKE = $(shell $(LUAROCKS) path --lr-cpath);./?.so
@ -25,12 +25,6 @@ compile:
$(LUA) bin/moonc -p bin/moon.moon >> bin/moon $(LUA) bin/moonc -p bin/moon.moon >> bin/moon
echo "-- vim: set filetype=lua:" >> bin/moon echo "-- vim: set filetype=lua:" >> bin/moon
compile_system:
moonc moon/ moonscript/
echo "#!/usr/bin/env lua" > bin/moon
moonc -p bin/moon.moon >> bin/moon
echo "-- vim: set filetype=lua:" >> bin/moon
watch: watch:
moonc moon/ moonscript/ && moonc -w moon/ moonscript/ moonc moon/ moonscript/ && moonc -w moon/ moonscript/

303
bin/moonc Executable file → Normal file
View File

@ -6,43 +6,46 @@ local lfs = require "lfs"
local parser = argparse() local parser = argparse()
parser:flag("-l --lint", "Perform a lint on the file instead of compiling") parser:flag("-l --lint", "Perform a lint on the file instead of compiling")
parser:flag("-v --version", "Print version") parser:flag("-v --version", "Print version")
parser:flag("-w --watch", "Watch file/directory for updates") parser:flag("-w --watch", "Watch file/directory for updates")
parser:option("--transform", "Transform syntax tree with module") parser:option("--transform", "Transform syntax tree with module")
parser:mutex( parser:mutex(
parser:option("-t --output-to", "Specify where to place compiled files"), parser:option("-t --output-to", "Specify where to place compiled files"),
parser:option("-o", "Write output to file"), parser:option("-o", "Write output to file"),
parser:flag("-p", "Write output to standard output"), parser:flag("-p", "Write output to standard output"),
parser:flag("-T", "Write parse tree instead of code (to stdout)"), parser:flag("-T", "Write parse tree instead of code (to stdout)"),
parser:flag("-b", "Write parse and compile time instead of code(to stdout)"), parser:flag("-b", "Write parse and compile time instead of code(to stdout)"),
parser:flag("-X", "Write line rewrite map instead of code (to stdout)") parser:flag("-X", "Write line rewrite map instead of code (to stdout)")
) )
parser:flag("-", parser:flag("-",
"Read from standard in, print to standard out (Must be only argument)") "Read from standard in, print to standard out (Must be only argument)")
local read_stdin = arg[1] == "-" -- luacheck: ignore 113 local read_stdin = arg[1] == "-" -- luacheck: ignore 113
if not read_stdin then if not read_stdin then
parser:argument("file/directory"):args("+") parser:argument("file/directory"):args("+")
else else
if arg[2] ~= nil then if arg[2] ~= nil then
io.stderr:write("- must be the only argument\n") io.stderr:write("- must be the only argument\n")
os.exit(1) os.exit(1)
end end
end end
local opts = read_stdin and {} or parser:parse() local opts = read_stdin and {} or parser:parse()
if opts.version then if opts.version then
local v = require "moonscript.version" local v = require "moonscript.version"
v.print_version() v.print_version()
os.exit() os.exit()
end end
function log_msg(...) function log_msg(...)
if not opts.p then if not opts.p then
io.stderr:write(table.concat({...}, " ") .. "\n") io.stderr:write(table.concat({...}, " ") .. "\n")
end end
end end
local moonc = require("moonscript.cmd.moonc") local moonc = require("moonscript.cmd.moonc")
@ -52,186 +55,186 @@ local compile_and_write = moonc.compile_and_write
local path_to_target = moonc.path_to_target local path_to_target = moonc.path_to_target
local function scan_directory(root, collected) local function scan_directory(root, collected)
root = normalize_dir(root) root = normalize_dir(root)
collected = collected or {} collected = collected or {}
for fname in lfs.dir(root) do for fname in lfs.dir(root) do
if not fname:match("^%.") then if not fname:match("^%.") then
local full_path = root..fname local full_path = root..fname
if lfs.attributes(full_path, "mode") == "directory" then if lfs.attributes(full_path, "mode") == "directory" then
scan_directory(full_path, collected) scan_directory(full_path, collected)
elseif fname:match("%.moon$") then elseif fname:match("%.moon$") then
table.insert(collected, full_path) table.insert(collected, full_path)
end end
end end
end end
return collected return collected
end end
local function remove_dups(tbl, key_fn) local function remove_dups(tbl, key_fn)
local hash = {} local hash = {}
local final = {} local final = {}
for _, v in ipairs(tbl) do for _, v in ipairs(tbl) do
local dup_key = key_fn and key_fn(v) or v local dup_key = key_fn and key_fn(v) or v
if not hash[dup_key] then if not hash[dup_key] then
table.insert(final, v) table.insert(final, v)
hash[dup_key] = true hash[dup_key] = true
end end
end end
return final return final
end end
-- creates tuples of input and target -- creates tuples of input and target
local function get_files(fname, files) local function get_files(fname, files)
files = files or {} files = files or {}
if lfs.attributes(fname, "mode") == "directory" then if lfs.attributes(fname, "mode") == "directory" then
for _, sub_fname in ipairs(scan_directory(fname)) do for _, sub_fname in ipairs(scan_directory(fname)) do
table.insert(files, { table.insert(files, {
sub_fname, sub_fname,
path_to_target(sub_fname, opts.output_to, fname) path_to_target(sub_fname, opts.output_to, fname)
}) })
end end
else else
table.insert(files, { table.insert(files, {
fname, fname,
path_to_target(fname, opts.output_to) path_to_target(fname, opts.output_to)
}) })
end end
return files return files
end end
if read_stdin then if read_stdin then
local parse = require "moonscript.parse" local parse = require "moonscript.parse"
local compile = require "moonscript.compile" local compile = require "moonscript.compile"
local text = io.stdin:read("*a") local text = io.stdin:read("*a")
local tree, err = parse.string(text) local tree, err = parse.string(text)
if not tree then error(err) end if not tree then error(err) end
local code, err, pos = compile.tree(tree) local code, err, pos = compile.tree(tree)
if not code then if not code then
error(compile.format_error(err, pos, text)) error(compile.format_error(err, pos, text))
end end
print(code) print(code)
os.exit() os.exit()
end end
local inputs = opts["file/directory"] local inputs = opts["file/directory"]
local files = {} local files = {}
for _, input in ipairs(inputs) do for _, input in ipairs(inputs) do
get_files(input, files) get_files(input, files)
end end
files = remove_dups(files, function(f) files = remove_dups(files, function(f)
return f[2] return f[2]
end) end)
-- returns an iterator that returns files that have been updated -- returns an iterator that returns files that have been updated
local function create_watcher(files) local function create_watcher(files)
local watchers = require("moonscript.cmd.watchers") local watchers = require("moonscript.cmd.watchers")
if watchers.InotifyWacher:available() then if watchers.InotifyWacher:available() then
return watchers.InotifyWacher(files):each_update() return watchers.InotifyWacher(files):each_update()
end end
return watchers.SleepWatcher(files):each_update() return watchers.SleepWatcher(files):each_update()
end end
if opts.watch then if opts.watch then
-- build function to check for lint or compile in watch -- build function to check for lint or compile in watch
local handle_file local handle_file
if opts.lint then if opts.lint then
local lint = require "moonscript.cmd.lint" local lint = require "moonscript.cmd.lint"
handle_file = lint.lint_file handle_file = lint.lint_file
else else
handle_file = compile_and_write handle_file = compile_and_write
end end
local watcher = create_watcher(files) local watcher = create_watcher(files)
-- catches interrupt error for ctl-c -- catches interrupt error for ctl-c
local protected = function() local protected = function()
local status, file = true, watcher() local status, file = true, watcher()
if status then if status then
return file return file
elseif file ~= "interrupted!" then elseif file ~= "interrupted!" then
error(file) error(file)
end end
end end
for fname in protected do for fname in protected do
local target = path_to_target(fname, opts.t) local target = path_to_target(fname, opts.t)
if opts.o then if opts.o then
target = opts.o target = opts.o
end end
local success, err = handle_file(fname, target) local success, err = handle_file(fname, target)
if opts.lint then if opts.lint then
if success then if success then
io.stderr:write(success .. "\n\n") io.stderr:write(success .. "\n\n")
elseif err then elseif err then
io.stderr:write(fname .. "\n" .. err .. "\n\n") io.stderr:write(fname .. "\n" .. err .. "\n\n")
end end
elseif not success then elseif not success then
io.stderr:write(table.concat({ io.stderr:write(table.concat({
"", "",
"Error: " .. fname, "Error: " .. fname,
err, err,
"\n", "\n",
}, "\n")) }, "\n"))
elseif success == "build" then elseif success == "build" then
log_msg("Built", fname, "->", target) log_msg("Built", fname, "->", target)
end end
end end
io.stderr:write("\nQuitting...\n") io.stderr:write("\nQuitting...\n")
elseif opts.lint then elseif opts.lint then
local has_linted_with_error; local has_linted_with_error;
local lint = require "moonscript.cmd.lint" local lint = require "moonscript.cmd.lint"
for _, tuple in pairs(files) do for _, tuple in pairs(files) do
local fname = tuple[1] local fname = tuple[1]
local res, err = lint.lint_file(fname) local res, err = lint.lint_file(fname)
if res then if res then
has_linted_with_error = true has_linted_with_error = true
io.stderr:write(res .. "\n\n") io.stderr:write(res .. "\n\n")
elseif err then elseif err then
has_linted_with_error = true has_linted_with_error = true
io.stderr:write(fname .. "\n" .. err.. "\n\n") io.stderr:write(fname .. "\n" .. err.. "\n\n")
end end
end end
if has_linted_with_error then if has_linted_with_error then
os.exit(1) os.exit(1)
end end
else else
for _, tuple in ipairs(files) do for _, tuple in ipairs(files) do
local fname, target = util.unpack(tuple) local fname, target = util.unpack(tuple)
if opts.o then if opts.o then
target = opts.o target = opts.o
end end
local success, err = compile_and_write(fname, target, { local success, err = compile_and_write(fname, target, {
print = opts.p, print = opts.p,
fname = fname, fname = fname,
benchmark = opts.b, benchmark = opts.b,
show_posmap = opts.X, show_posmap = opts.X,
show_parse_tree = opts.T, show_parse_tree = opts.T,
transform_module = opts.transform transform_module = opts.transform
}) })
if not success then if not success then
io.stderr:write(fname .. "\t" .. err .. "\n") io.stderr:write(fname .. "\t" .. err .. "\n")
os.exit(1) os.exit(1)
end end
end end
end end

View File

@ -102,7 +102,11 @@ dump = function(what)
lines = _accum_0 lines = _accum_0
end end
seen[what] = false seen[what] = false
return "{\n" .. concat(lines) .. (" "):rep((depth - 1) * 4) .. "}\n" local class_name
if what.__class then
class_name = "<" .. tostring(what.__class.__name) .. ">"
end
return tostring(class_name or "") .. "{\n" .. concat(lines) .. (" "):rep((depth - 1) * 4) .. "}\n"
else else
return tostring(what) .. "\n" return tostring(what) .. "\n"
end end

View File

@ -70,7 +70,10 @@ dump = (what) ->
seen[what] = false seen[what] = false
"{\n" .. concat(lines) .. (" ")\rep((depth - 1)*4) .. "}\n" class_name = if what.__class
"<#{what.__class.__name}>"
"#{class_name or ""}{\n" .. concat(lines) .. (" ")\rep((depth - 1)*4) .. "}\n"
else else
tostring(what).."\n" tostring(what).."\n"