Switched to use load() with environment table instead of passing in
nomsu to everything. This has some nice code cleanliness benefits.
This commit is contained in:
parent
e09f05a50c
commit
6b09187899
@ -16,7 +16,7 @@ if [ "$FLUSH" = true ] ; then
|
||||
done
|
||||
fi
|
||||
|
||||
for file in $(cat lib/core.nom | lua -e "for filename in io.read('*a'):gmatch('require \"([^\"]*)\"') do print(filename) end") ; do
|
||||
for file in $(cat lib/core.nom | lua -e "for filename in io.read('*a'):gmatch('use \"([^\"]*)\"') do print(filename) end") ; do
|
||||
compilefile="${file/\.nom/.lua}"
|
||||
if [ ! -e "$compilefile" ] || [ "$file" -nt "$compilefile" ] ; then
|
||||
echo "Compiling $file into $compilefile"
|
||||
|
@ -16,7 +16,7 @@ parse [..]
|
||||
compile [..]
|
||||
%index st to last in %list, %index nd to last in %list, %index rd to last in %list
|
||||
%index th to last in %list
|
||||
..to: "nomsu.utils.nth_to_last(\(%list as lua), \(%index as lua))"
|
||||
..to: "utils.nth_to_last(\(%list as lua), \(%index as lua))"
|
||||
|
||||
parse [first in %list, first %list] as: 1 st in %list
|
||||
parse [last in %list, last %list] as: 1 st to last in %list
|
||||
@ -45,7 +45,7 @@ compile [..]
|
||||
..to: "((\(%list as lua))[\(%index as lua)] ~= nil)"
|
||||
|
||||
compile [length of %list, size of %list, size %list, number of %list, len %list] to:
|
||||
"nomsu.utils.size(\(%list as lua))"
|
||||
"utils.size(\(%list as lua))"
|
||||
|
||||
# Chained lookup
|
||||
compile [%list ->* %indices] to:
|
||||
@ -99,13 +99,13 @@ immediately:
|
||||
assume ((%item's "type") is "Var") or barf ".."
|
||||
List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||
return ".."
|
||||
(function(nomsu);
|
||||
(function();
|
||||
local comprehension = {};
|
||||
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
||||
comprehension[i] = \(%expression as lua);
|
||||
end;
|
||||
return comprehension;
|
||||
end)(nomsu)
|
||||
end)()
|
||||
parse [%expression for all %iterable] as: %expression for % in %iterable
|
||||
|
||||
compile [%expression for %key = %value in %iterable] to:
|
||||
@ -114,13 +114,13 @@ immediately:
|
||||
assume ((%value's "type") is "Var") or barf ".."
|
||||
List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
|
||||
return ".."
|
||||
(function(nomsu);
|
||||
(function();
|
||||
local comprehension = {};
|
||||
for \(%key as lua), \(%value as lua) in pairs(\(%iterable as lua)) do;
|
||||
comprehension[i] = \(%expression as lua);
|
||||
end;
|
||||
return comprehension;
|
||||
end)(nomsu)
|
||||
end)()
|
||||
|
||||
# Dict comprehensions
|
||||
immediately:
|
||||
@ -128,13 +128,13 @@ immediately:
|
||||
assume ((%item's "type") is "Var") or barf ".."
|
||||
Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||
return ".."
|
||||
(function(nomsu);
|
||||
(function();
|
||||
local comprehension = {};
|
||||
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
||||
comprehension[\(%key as lua)] = \(%value as lua);
|
||||
end;
|
||||
return comprehension;
|
||||
end)(nomsu)
|
||||
end)()
|
||||
parse [%key = %value for all %iterable] as: %key = %value for % in %iterable
|
||||
|
||||
compile [%key = %value for %src_key = %src_value in %iterable] to:
|
||||
@ -143,18 +143,18 @@ immediately:
|
||||
assume ((%src_value's "type") is "Var") or barf ".."
|
||||
Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type")
|
||||
return ".."
|
||||
(function(nomsu);
|
||||
(function();
|
||||
local comprehension = {};
|
||||
for \(%src_key as lua), \(%src_value as lua) in pairs(\(%iterable as lua)) do;
|
||||
comprehension[\(%key as lua)] = \(%value as lua);
|
||||
end;
|
||||
return comprehension;
|
||||
end)(nomsu)
|
||||
end)()
|
||||
|
||||
# Sorting:
|
||||
compile [sort %items] to: "table.sort(\(%items as lua))"
|
||||
compile [sort %items by %key_expr] to: ".."
|
||||
nomsu.utils.sort(\(%items as lua), function(\(\% as lua))
|
||||
utils.sort(\(%items as lua), function(\(\% as lua))
|
||||
return \(%key_expr as lua);
|
||||
end)
|
||||
|
||||
|
@ -50,13 +50,13 @@ immediately:
|
||||
doesn't have a proper ternary operator!)
|
||||
To see why this is necessary consider: (random()<.5 and false or 99)
|
||||
return ".."
|
||||
(function(nomsu)
|
||||
(function()
|
||||
if \(%condition as lua) then
|
||||
return \(%when_true_expr as lua);
|
||||
else
|
||||
return \(%when_false_expr as lua);
|
||||
end
|
||||
end)(nomsu)
|
||||
end)()
|
||||
|
||||
# GOTOs
|
||||
immediately:
|
||||
@ -344,10 +344,10 @@ immediately:
|
||||
..to code: ".."
|
||||
do
|
||||
local fell_through = false;
|
||||
local ok, ret = pcall(function(nomsu)
|
||||
local ok, ret = pcall(function()
|
||||
\(%action as lua statements)
|
||||
fell_through = true;
|
||||
end, nomsu);
|
||||
end);
|
||||
if ok then
|
||||
\(%success as lua statements)
|
||||
end
|
||||
@ -375,15 +375,15 @@ immediately:
|
||||
compile [do %action then always %final_action] to code: ".."
|
||||
do
|
||||
local fell_through = false;
|
||||
local ok, ret1 = pcall(function(nomsu)
|
||||
local ok, ret1 = pcall(function()
|
||||
\(%action as lua statements)
|
||||
fell_through = true;
|
||||
end, nomsu);
|
||||
local ok2, ret2 = pcall(function(nomsu)
|
||||
end);
|
||||
local ok2, ret2 = pcall(function()
|
||||
\(%final_action as lua statements)
|
||||
end, nomsu);
|
||||
if not ok then nomsu:error(ret1); end
|
||||
if not ok2 then nomsu:error(ret2); end
|
||||
end);
|
||||
if not ok then error(ret1); end
|
||||
if not ok2 then error(ret2); end
|
||||
if not fell_through then
|
||||
return ret1;
|
||||
end
|
||||
@ -402,12 +402,12 @@ immediately:
|
||||
local \(join %temp_vars with ", ") = \(join %old_vals with ", ");
|
||||
\(join %old_vals with ", ") = \(join %new_vals with ", ");
|
||||
local fell_through = false;
|
||||
local ok, ret = pcall(function(nomsu)
|
||||
local ok, ret = pcall(function()
|
||||
do
|
||||
\(%action as lua statements)
|
||||
end
|
||||
fell_through = true;
|
||||
end, nomsu);
|
||||
end);
|
||||
\(join %old_vals with ", ") = \(join %temp_vars with ", ");
|
||||
if not ok then error(ret, 0); end
|
||||
if not fell_through then return ret end
|
||||
|
18
lib/math.nom
18
lib/math.nom
@ -38,30 +38,30 @@ action [%n to the nearest %rounder]:
|
||||
# Any/all/none
|
||||
compile [all of %items, all %items] to:
|
||||
"(\(join ((% as lua) for all (%items' "value")) with " and "))"
|
||||
..if ((%items' "type") is "List") else "nomsu.utils.all(\(%items as lua))"
|
||||
..if ((%items' "type") is "List") else "utils.all(\(%items as lua))"
|
||||
parse [not all of %items, not all %items] as: not (all of %items)
|
||||
compile [any of %items, any %items] to:
|
||||
"(\(join ((% as lua) for all (%items' "value")) with " or "))"
|
||||
..if ((%items' "type") is "List") else "nomsu.utils.any(\(%items as lua))"
|
||||
..if ((%items' "type") is "List") else "utils.any(\(%items as lua))"
|
||||
parse [none of %items, none %items] as: not (any of %items)
|
||||
compile [sum of %items, sum %items] to:
|
||||
"(\(join ((% as lua) for all (%items' "value")) with " + "))"
|
||||
..if ((%items' "type") is "List") else "nomsu.utils.sum(\(%items as lua))"
|
||||
..if ((%items' "type") is "List") else "utils.sum(\(%items as lua))"
|
||||
compile [product of %items, product %items] to:
|
||||
"(\(join ((% as lua) for all (%items' "value")) with " * "))"
|
||||
..if ((%items' "type") is "List") else "nomsu.utils.product(\(%items as lua))"
|
||||
..if ((%items' "type") is "List") else "utils.product(\(%items as lua))"
|
||||
action [avg of %items, average of %items]:
|
||||
=lua "(nomsu.utils.sum(\%items)/#\%items)"
|
||||
=lua "(utils.sum(\%items)/#\%items)"
|
||||
compile [min of %items, smallest of %items, lowest of %items] to:
|
||||
"nomsu.utils.min(\(%items as lua))"
|
||||
"utils.min(\(%items as lua))"
|
||||
compile [max of %items, biggest of %items, largest of %items, highest of %items] to:
|
||||
"nomsu.utils.max(\(%items as lua))"
|
||||
"utils.max(\(%items as lua))"
|
||||
compile [min of %items by %value_expr] to: ".."
|
||||
nomsu.utils.min(\(%items as lua), function(\(\% as lua))
|
||||
utils.min(\(%items as lua), function(\(\% as lua))
|
||||
return \(%value_expr as lua)
|
||||
end)
|
||||
compile [max of %items by %value_expr] to: ".."
|
||||
nomsu.utils.max(\(%items as lua), function(\(\% as lua))
|
||||
utils.max(\(%items as lua), function(\(\% as lua))
|
||||
return \(%value_expr as lua)
|
||||
end)
|
||||
|
||||
|
@ -11,19 +11,19 @@ immediately:
|
||||
names[i] = alias.src;
|
||||
end
|
||||
local _, arg_names, _ = nomsu:get_stub(spec.value[1]);
|
||||
local args = {"nomsu"};
|
||||
for i, a in ipairs(arg_names) do args[i+1] = "_"..nomsu:var_to_lua_identifier(a); end
|
||||
names, args = nomsu:repr(names), table.concat(args, ", ");
|
||||
local args = {};
|
||||
for i, a in ipairs(arg_names) do args[i] = "_"..nomsu:var_to_lua_identifier(a); end
|
||||
names, args = repr(names), table.concat(args, ", ");
|
||||
return names, args;
|
||||
end
|
||||
|
||||
# Compile-time action to make compile-time actions:
|
||||
immediately:
|
||||
lua> ".."
|
||||
nomsu:define_compile_action("compile %names to %body", \(__line_no__), function(nomsu, \%names, \%body)
|
||||
nomsu:assert(\%names.type == "List",
|
||||
nomsu:define_compile_action("compile %names to %body", \(__line_no__), function(\%names, \%body)
|
||||
assert(\%names.type == "List",
|
||||
"Invalid type for compile definition names. Expected List, but got: "..tostring(\%names.type));
|
||||
nomsu:assert(\%body.type == "Block",
|
||||
assert(\%body.type == "Block",
|
||||
"Invalid type for compile definition body. Expected Block, but got: "..tostring(\%body.type));
|
||||
local names, args = nomsu:parse_spec(\%names);
|
||||
local body_lua = nomsu:tree_to_lua(\%body);
|
||||
@ -35,16 +35,16 @@ immediately:
|
||||
end
|
||||
local function compile_action_wrapper(...) return {expr=compile_action(...)}; end
|
||||
nomsu:define_compile_action(%s, %s, compile_action_wrapper, %s);
|
||||
end]]):format(args, body_lua, names, nomsu:repr(\%names:get_line_no()),
|
||||
nomsu:repr(("compile %s\\n..to code %s"):format(\%names.src, \%body.src)));
|
||||
end]]):format(args, body_lua, names, repr(\%names:get_line_no()),
|
||||
repr(("compile %s\\n..to code %s"):format(\%names.src, \%body.src)));
|
||||
return {statements=lua};
|
||||
end, \(__src__ 1));
|
||||
|
||||
lua> ".."
|
||||
nomsu:define_compile_action("compile %names to code %body", \(__line_no__), function(nomsu, \%names, \%body)
|
||||
nomsu:assert(\%names.type == "List",
|
||||
nomsu:define_compile_action("compile %names to code %body", \(__line_no__), function(\%names, \%body)
|
||||
assert(\%names.type == "List",
|
||||
"Invalid type for compile definition names. Expected List, but got: "..tostring(\%names.type));
|
||||
nomsu:assert(\%body.type == "Block",
|
||||
assert(\%body.type == "Block",
|
||||
"Invalid type for compile definition body. Expected Block, but got: "..tostring(\%body.type));
|
||||
local names, args = nomsu:parse_spec(\%names);
|
||||
local body_lua = nomsu:tree_to_lua(\%body);
|
||||
@ -56,8 +56,8 @@ immediately:
|
||||
end
|
||||
local function compile_action_wrapper(...) return {statements=compile_action(...)}; end
|
||||
nomsu:define_compile_action(%s, %s, compile_action_wrapper, %s);
|
||||
end]]):format(args, body_lua, names, nomsu:repr(\%names:get_line_no()),
|
||||
nomsu:repr(("compile %s\\n..to code %s"):format(\%names.src, \%body.src)));
|
||||
end]]):format(args, body_lua, names, repr(\%names:get_line_no()),
|
||||
repr(("compile %s\\n..to code %s"):format(\%names.src, \%body.src)));
|
||||
return {statements=lua};
|
||||
end, \(__src__ 1));
|
||||
|
||||
@ -65,9 +65,9 @@ immediately:
|
||||
immediately:
|
||||
compile [action %names %body] to code:
|
||||
lua> ".."
|
||||
nomsu:assert(\%names.type == "List",
|
||||
assert(\%names.type == "List",
|
||||
"Invalid type for action definition names. Expected List, but got: "..tostring(\%names.type));
|
||||
nomsu:assert(\%body.type == "Block",
|
||||
assert(\%body.type == "Block",
|
||||
"Invalid type for action definition body. Expected Block, but got: "..tostring(\%body.type));
|
||||
local names, args = nomsu:parse_spec(\%names);
|
||||
local body_lua = nomsu:tree_to_lua(\%body);
|
||||
@ -76,34 +76,34 @@ immediately:
|
||||
local def_lua = ([[
|
||||
nomsu:define_action(%s, \(__line_no__), function(%s)
|
||||
%s
|
||||
end, %s);]]):format(names, args, body_lua, nomsu:repr(src));
|
||||
end, %s);]]):format(names, args, body_lua, repr(src));
|
||||
return def_lua;
|
||||
|
||||
# Macro to make nomsu macros:
|
||||
immediately:
|
||||
lua> ".."
|
||||
nomsu:define_compile_action("parse %shorthand as %longhand", \(__line_no__), (function(nomsu, \%shorthand, \%longhand)
|
||||
nomsu:assert(\%shorthand.type == "List",
|
||||
nomsu:define_compile_action("parse %shorthand as %longhand", \(__line_no__), (function(\%shorthand, \%longhand)
|
||||
assert(\%shorthand.type == "List",
|
||||
"Invalid type for parse definition shorthand. Expected List, but got: "..tostring(\%shorthand.type));
|
||||
nomsu:assert(\%longhand.type == "Block",
|
||||
assert(\%longhand.type == "Block",
|
||||
"Invalid type for parse definition body. Expected Block, but got: "..tostring(\%longhand.type));
|
||||
local names, args = nomsu:parse_spec(\%shorthand);
|
||||
local template = {};
|
||||
for i, line in ipairs(\%longhand.value) do
|
||||
template[i] = nomsu:dedent(line.src);
|
||||
end
|
||||
template = nomsu:repr(table.concat(template, "\\n"));
|
||||
template = repr(table.concat(template, "\\n"));
|
||||
local _, arg_names, _ = nomsu:get_stub(\%shorthand.value[1]);
|
||||
local replacements = {};
|
||||
for i, a in ipairs(arg_names) do replacements[i] = "["..nomsu:repr(a).."]=_"..nomsu:var_to_lua_identifier(a); end
|
||||
for i, a in ipairs(arg_names) do replacements[i] = "["..repr(a).."]=_"..nomsu:var_to_lua_identifier(a); end
|
||||
replacements = "{"..table.concat(replacements, ", ").."}";
|
||||
local lua_code = ([[
|
||||
nomsu:define_compile_action(%s, %s, (function(%s)
|
||||
local template = nomsu:parse(%s, %s);
|
||||
local replacement = nomsu:replaced_vars(template, %s);
|
||||
return nomsu:tree_to_lua(replacement);
|
||||
end), %s)]]):format(names, nomsu:repr(\%shorthand:get_line_no()), args, template,
|
||||
nomsu:repr(\%shorthand:get_line_no()), replacements, nomsu:repr(nomsu:source_code(0)));
|
||||
end), %s)]]):format(names, repr(\%shorthand:get_line_no()), args, template,
|
||||
repr(\%shorthand:get_line_no()), replacements, repr(nomsu:source_code(0)));
|
||||
return {statements=lua_code};
|
||||
end), \(__src__ 1));
|
||||
|
||||
@ -124,7 +124,7 @@ immediately:
|
||||
action [%tree as value]:
|
||||
=lua "nomsu:tree_to_value(\%tree)"
|
||||
compile [repr %obj] to:
|
||||
"nomsu:repr(\(%obj as lua))"
|
||||
"repr(\(%obj as lua))"
|
||||
compile [indented %obj] to:
|
||||
"nomsu:indent(\(%obj as lua))"
|
||||
compile [dedented %obj] to:
|
||||
@ -153,7 +153,7 @@ action [help %action]:
|
||||
lua> ".."
|
||||
local fn_def = nomsu.defs[nomsu:get_stub(\%action)]
|
||||
if not fn_def then
|
||||
nomsu:writeln("Action not found: "..nomsu:repr(\%action));
|
||||
nomsu:writeln("Action not found: "..repr(\%action));
|
||||
else
|
||||
nomsu:writeln(fn_def.src or "<unknown source code>");
|
||||
end
|
||||
@ -182,7 +182,7 @@ compile [say %str] to:
|
||||
if \%str.type == "Text" then
|
||||
return "nomsu:writeln("..\(%str as lua)..")";
|
||||
else
|
||||
return "nomsu:writeln(nomsu:stringify("..\(%str as lua).."))";
|
||||
return "nomsu:writeln(stringify("..\(%str as lua).."))";
|
||||
end
|
||||
|
||||
# Error functions
|
||||
|
@ -20,7 +20,7 @@ immediately:
|
||||
if safe[\%a.type] or safe[\%b.type] then
|
||||
return "("..a_lua.." == "..b_lua..")";
|
||||
else
|
||||
return "nomsu.utils.equivalent("..a_lua..", "..b_lua..")";
|
||||
return "utils.equivalent("..a_lua..", "..b_lua..")";
|
||||
end
|
||||
compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to:
|
||||
lua> ".."
|
||||
@ -29,7 +29,7 @@ immediately:
|
||||
if safe[\%a.type] or safe[\%b.type] then
|
||||
return "("..a_lua.." ~= "..b_lua..")";
|
||||
else
|
||||
return "(not nomsu.utils.equivalent("..a_lua..", "..b_lua.."))";
|
||||
return "(not utils.equivalent("..a_lua..", "..b_lua.."))";
|
||||
end
|
||||
# For strict identity checking, use (%x's id) is (%y's id)
|
||||
compile [%'s id, id of %] to: "nomsu.ids[\(% as lua)]"
|
||||
|
@ -8,7 +8,7 @@ use "lib/metaprogramming.nom"
|
||||
action [join %strs with %glue]:
|
||||
lua> ".."
|
||||
local str_bits = {}
|
||||
for i,bit in ipairs(\%strs) do str_bits[i] = nomsu:stringify(bit) end
|
||||
for i,bit in ipairs(\%strs) do str_bits[i] = stringify(bit) end
|
||||
return table.concat(str_bits, \%glue)
|
||||
parse [join %strs] as: join %strs with ""
|
||||
|
||||
@ -49,7 +49,7 @@ lua do> ".."
|
||||
local color = "'"..c.."'";
|
||||
local reset = "'"..colors["reset color"].."'";
|
||||
nomsu:define_compile_action(name, \(__line_no__), function() return {expr=color}; end, \(__src__ 1));
|
||||
nomsu:define_compile_action(name.." %", \(__line_no__), function(nomsu, _)
|
||||
nomsu:define_compile_action(name.." %", \(__line_no__), function(_)
|
||||
return {expr=color..".."..nomsu:tree_to_lua(_).expr..".."..reset};
|
||||
end, \(__src__ 1));
|
||||
end
|
||||
|
115
nomsu.lua
115
nomsu.lua
@ -442,7 +442,10 @@ do
|
||||
end,
|
||||
run_file = function(self, filename)
|
||||
if filename:match(".*%.lua") then
|
||||
return dofile(filename)(self)
|
||||
local file = io.open(filename)
|
||||
local contents = file:read("*a")
|
||||
file:close()
|
||||
return assert(load(contents, nil, nil, self.environment))()
|
||||
end
|
||||
if filename:match(".*%.nom") then
|
||||
if not self.skip_precompiled then
|
||||
@ -472,13 +475,11 @@ do
|
||||
return loaded[filename]
|
||||
end,
|
||||
run_lua = function(self, lua_code)
|
||||
local load_lua_fn, err = load(([[return function(nomsu)
|
||||
%s
|
||||
end]]):format(lua_code))
|
||||
local run_lua_fn, err = load(lua_code, nil, nil, self.environment)
|
||||
if self.debug then
|
||||
self:writeln(tostring(colored.bright("RUNNING LUA:")) .. "\n" .. tostring(colored.blue(colored.bright(lua_code))))
|
||||
end
|
||||
if not load_lua_fn then
|
||||
if not run_lua_fn then
|
||||
local n = 1
|
||||
local fn
|
||||
fn = function()
|
||||
@ -488,21 +489,18 @@ end]]):format(lua_code))
|
||||
local code = "1 |" .. lua_code:gsub("\n", fn)
|
||||
self:error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(colored.onblack(code)))) .. "\n\n" .. tostring(err))
|
||||
end
|
||||
local run_lua_fn = load_lua_fn()
|
||||
run_lua_fn(self)
|
||||
return ret
|
||||
return run_lua_fn()
|
||||
end,
|
||||
tree_to_value = function(self, tree, filename)
|
||||
local code = "return (function(nomsu)\nreturn " .. tostring(self:tree_to_lua(tree).expr) .. ";\nend);"
|
||||
code = "-- Tree to value: " .. tostring(filename) .. "\n" .. code
|
||||
local code = "return " .. tostring(self:tree_to_lua(tree).expr) .. ";"
|
||||
if self.debug then
|
||||
self:writeln(tostring(colored.bright("RUNNING LUA TO GET VALUE:")) .. "\n" .. tostring(colored.blue(colored.bright(code))))
|
||||
end
|
||||
local lua_thunk, err = load(code)
|
||||
local lua_thunk, err = load(code, nil, nil, self.environment)
|
||||
if not lua_thunk then
|
||||
self:error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(colored.onblack(code)))) .. "\n\n" .. tostring(colored.red(err)))
|
||||
end
|
||||
return (lua_thunk())(self)
|
||||
return lua_thunk()
|
||||
end,
|
||||
tree_to_nomsu = function(self, tree, force_inline)
|
||||
if force_inline == nil then
|
||||
@ -780,7 +778,7 @@ end]]):format(lua_code))
|
||||
return _accum_0
|
||||
end)()))))
|
||||
end
|
||||
local lua = self.defs[tree.stub].fn(self, unpack(args))
|
||||
local lua = self.defs[tree.stub].fn(unpack(args))
|
||||
remove(self.compilestack)
|
||||
return lua
|
||||
elseif not def and self.__class.math_patt:match(tree.stub) then
|
||||
@ -836,7 +834,6 @@ end]]):format(lua_code))
|
||||
end
|
||||
args = new_args
|
||||
end
|
||||
insert(args, 1, "nomsu")
|
||||
remove(self.compilestack)
|
||||
return {
|
||||
expr = self.__class:comma_separated_items("nomsu.defs[" .. tostring(repr(tree.stub)) .. "].fn(", args, ")")
|
||||
@ -1164,8 +1161,9 @@ end]]):format(lua_code))
|
||||
return self:dedent(self.compilestack[#self.compilestack - level].src)
|
||||
end,
|
||||
initialize_core = function(self)
|
||||
local nomsu = self
|
||||
local nomsu_string_as_lua
|
||||
nomsu_string_as_lua = function(self, code)
|
||||
nomsu_string_as_lua = function(code)
|
||||
local concat_parts = { }
|
||||
local _list_0 = code.value
|
||||
for _index_0 = 1, #_list_0 do
|
||||
@ -1173,65 +1171,65 @@ end]]):format(lua_code))
|
||||
if type(bit) == "string" then
|
||||
insert(concat_parts, bit)
|
||||
else
|
||||
local lua = self:tree_to_lua(bit)
|
||||
local lua = nomsu:tree_to_lua(bit)
|
||||
if lua.statements then
|
||||
self:error("Cannot use [[" .. tostring(bit.src) .. "]] as a string interpolation value, since it's not an expression.")
|
||||
error("Cannot use [[" .. tostring(bit.src) .. "]] as a string interpolation value, since it's not an expression.")
|
||||
end
|
||||
insert(concat_parts, lua.expr)
|
||||
end
|
||||
end
|
||||
return concat(concat_parts)
|
||||
end
|
||||
self:define_compile_action("do %block", "nomsu.moon", function(self, _block)
|
||||
self:define_compile_action("do %block", "nomsu.moon", function(_block)
|
||||
local make_line
|
||||
make_line = function(lua)
|
||||
return lua.expr and (lua.expr .. ";") or lua.statements
|
||||
end
|
||||
if _block.type == "Block" then
|
||||
return self:tree_to_lua(_block)
|
||||
return nomsu:tree_to_lua(_block)
|
||||
else
|
||||
return {
|
||||
expr = tostring(self:tree_to_lua(_block)) .. "(nomsu)"
|
||||
expr = tostring(nomsu:tree_to_lua(_block)) .. "(nomsu)"
|
||||
}
|
||||
end
|
||||
end)
|
||||
self:define_compile_action("immediately %block", "nomsu.moon", function(self, _block)
|
||||
local lua = self:tree_to_lua(_block)
|
||||
self:define_compile_action("immediately %block", "nomsu.moon", function(_block)
|
||||
local lua = nomsu:tree_to_lua(_block)
|
||||
local lua_code = lua.statements or (lua.expr .. ";")
|
||||
lua_code = "-- Immediately:\n" .. lua_code
|
||||
self:run_lua(lua_code)
|
||||
nomsu:run_lua(lua_code)
|
||||
return {
|
||||
statements = lua_code
|
||||
}
|
||||
end)
|
||||
self:define_compile_action("lua> %code", "nomsu.moon", function(self, _code)
|
||||
local lua = nomsu_string_as_lua(self, _code)
|
||||
self:define_compile_action("lua> %code", "nomsu.moon", function(_code)
|
||||
local lua = nomsu_string_as_lua(_code)
|
||||
return {
|
||||
statements = lua
|
||||
}
|
||||
end)
|
||||
self:define_compile_action("=lua %code", "nomsu.moon", function(self, _code)
|
||||
local lua = nomsu_string_as_lua(self, _code)
|
||||
self:define_compile_action("=lua %code", "nomsu.moon", function(_code)
|
||||
local lua = nomsu_string_as_lua(_code)
|
||||
return {
|
||||
expr = lua
|
||||
}
|
||||
end)
|
||||
self:define_compile_action("__line_no__", "nomsu.moon", function(self)
|
||||
self:define_compile_action("__line_no__", "nomsu.moon", function()
|
||||
return {
|
||||
expr = repr(self.compilestack[#self.compilestack]:get_line_no())
|
||||
expr = repr(nomsu.compilestack[#nomsu.compilestack]:get_line_no())
|
||||
}
|
||||
end)
|
||||
self:define_compile_action("__src__ %level", "nomsu.moon", function(self, _level)
|
||||
self:define_compile_action("__src__ %level", "nomsu.moon", function(_level)
|
||||
return {
|
||||
expr = repr(self:source_code(self:tree_to_value(_level)))
|
||||
expr = repr(nomsu:source_code(nomsu:tree_to_value(_level)))
|
||||
}
|
||||
end)
|
||||
self:define_action("run file %filename", "nomsu.moon", function(self, _filename)
|
||||
return self:run_file(_filename)
|
||||
self:define_action("run file %filename", "nomsu.moon", function(_filename)
|
||||
return nomus:run_file(_filename)
|
||||
end)
|
||||
return self:define_compile_action("use %filename", "nomsu.moon", function(self, _filename)
|
||||
local filename = self:tree_to_value(_filename)
|
||||
self:require_file(filename)
|
||||
return self:define_compile_action("use %filename", "nomsu.moon", function(_filename)
|
||||
local filename = nomsu:tree_to_value(_filename)
|
||||
nomsu:require_file(filename)
|
||||
return {
|
||||
statements = "nomsu:require_file(" .. tostring(repr(filename)) .. ");"
|
||||
}
|
||||
@ -1272,13 +1270,56 @@ end]]):format(lua_code))
|
||||
end
|
||||
self.compilestack = { }
|
||||
self.debug = false
|
||||
self.utils = utils
|
||||
self.repr = function(self, ...)
|
||||
return repr(...)
|
||||
end
|
||||
self.stringify = function(self, ...)
|
||||
return stringify(...)
|
||||
end
|
||||
self.environment = {
|
||||
nomsu = self,
|
||||
repr = repr,
|
||||
stringify = stringify,
|
||||
utils = utils,
|
||||
lpeg = lpeg,
|
||||
re = re,
|
||||
next = next,
|
||||
unpack = unpack,
|
||||
setmetatable = setmetatable,
|
||||
coroutine = coroutine,
|
||||
rawequal = rawequal,
|
||||
getmetatable = getmetatable,
|
||||
pcall = pcall,
|
||||
error = error,
|
||||
package = package,
|
||||
os = os,
|
||||
require = require,
|
||||
tonumber = tonumber,
|
||||
tostring = tostring,
|
||||
string = string,
|
||||
xpcall = xpcall,
|
||||
module = module,
|
||||
print = print,
|
||||
loadfile = loadfile,
|
||||
rawset = rawset,
|
||||
_VERSION = _VERSION,
|
||||
collectgarbage = collectgarbage,
|
||||
rawget = rawget,
|
||||
bit32 = bit32,
|
||||
rawlen = rawlen,
|
||||
table = table,
|
||||
assert = assert,
|
||||
dofile = dofile,
|
||||
loadstring = loadstring,
|
||||
type = type,
|
||||
select = select,
|
||||
debug = debug,
|
||||
math = math,
|
||||
io = io,
|
||||
pairs = pairs,
|
||||
load = load,
|
||||
ipairs = ipairs
|
||||
}
|
||||
if not parent then
|
||||
return self:initialize_core()
|
||||
end
|
||||
|
87
nomsu.moon
87
nomsu.moon
@ -164,9 +164,17 @@ class NomsuCompiler
|
||||
setmetatable(@defs["#loaded_files"], {__index:parent["#loaded_files"]})
|
||||
@compilestack = {}
|
||||
@debug = false
|
||||
@utils = utils
|
||||
@repr = (...)=> repr(...)
|
||||
@stringify = (...)=> stringify(...)
|
||||
|
||||
@environment = {
|
||||
-- Discretionary/convenience stuff
|
||||
nomsu:self, repr:repr, stringify:stringify, utils:utils, lpeg:lpeg, re:re,
|
||||
-- Lua stuff:
|
||||
:next, :unpack, :setmetatable, :coroutine, :rawequal, :getmetatable, :pcall,
|
||||
:error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, :module,
|
||||
:print, :loadfile, :rawset, :_VERSION, :collectgarbage, :rawget, :bit32, :rawlen,
|
||||
:table, :assert, :dofile, :loadstring, :type, :select, :debug, :math, :io, :pairs,
|
||||
:load, :ipairs,
|
||||
}
|
||||
if not parent
|
||||
@initialize_core!
|
||||
|
||||
@ -303,7 +311,10 @@ class NomsuCompiler
|
||||
|
||||
run_file: (filename)=>
|
||||
if filename\match(".*%.lua")
|
||||
return dofile(filename)(@)
|
||||
file = io.open(filename)
|
||||
contents = file\read("*a")
|
||||
file\close!
|
||||
return assert(load(contents, nil, nil, @environment))!
|
||||
if filename\match(".*%.nom")
|
||||
if not @skip_precompiled -- Look for precompiled version
|
||||
file = io.open(filename\gsub("%.nom", ".lua"), "r")
|
||||
@ -327,32 +338,26 @@ class NomsuCompiler
|
||||
return loaded[filename]
|
||||
|
||||
run_lua: (lua_code)=>
|
||||
load_lua_fn, err = load([[
|
||||
return function(nomsu)
|
||||
%s
|
||||
end]]\format(lua_code))
|
||||
run_lua_fn, err = load(lua_code, nil, nil, @environment)
|
||||
if @debug
|
||||
@writeln "#{colored.bright "RUNNING LUA:"}\n#{colored.blue colored.bright(lua_code)}"
|
||||
if not load_lua_fn
|
||||
if not run_lua_fn
|
||||
n = 1
|
||||
fn = ->
|
||||
n = n + 1
|
||||
("\n%-3d|")\format(n)
|
||||
code = "1 |"..lua_code\gsub("\n", fn)
|
||||
@error("Failed to compile generated code:\n#{colored.bright colored.blue colored.onblack code}\n\n#{err}")
|
||||
run_lua_fn = load_lua_fn!
|
||||
run_lua_fn(self)
|
||||
return ret
|
||||
return run_lua_fn!
|
||||
|
||||
tree_to_value: (tree, filename)=>
|
||||
code = "return (function(nomsu)\nreturn #{@tree_to_lua(tree).expr};\nend);"
|
||||
code = "-- Tree to value: #{filename}\n"..code
|
||||
code = "return #{@tree_to_lua(tree).expr};"
|
||||
if @debug
|
||||
@writeln "#{colored.bright "RUNNING LUA TO GET VALUE:"}\n#{colored.blue colored.bright(code)}"
|
||||
lua_thunk, err = load(code)
|
||||
lua_thunk, err = load(code, nil, nil, @environment)
|
||||
if not lua_thunk
|
||||
@error("Failed to compile generated code:\n#{colored.bright colored.blue colored.onblack code}\n\n#{colored.red err}")
|
||||
return (lua_thunk!)(self)
|
||||
return lua_thunk!
|
||||
|
||||
tree_to_nomsu: (tree, force_inline=false)=>
|
||||
-- Return <nomsu code>, <is safe for inline use>
|
||||
@ -527,7 +532,7 @@ end]]\format(lua_code))
|
||||
if @debug
|
||||
@write "#{colored.bright "RUNNING MACRO"} #{colored.underscore colored.magenta(tree.stub)} "
|
||||
@writeln "#{colored.bright "WITH ARGS:"} #{colored.dim repr [(repr a)\sub(1,50) for a in *args]}"
|
||||
lua = @defs[tree.stub].fn(self, unpack(args))
|
||||
lua = @defs[tree.stub].fn(unpack(args))
|
||||
remove @compilestack
|
||||
return lua
|
||||
elseif not def and @@math_patt\match(tree.stub)
|
||||
@ -557,7 +562,6 @@ end]]\format(lua_code))
|
||||
new_args = [args[p] for p in *def.arg_positions]
|
||||
args = new_args
|
||||
|
||||
insert args, 1, "nomsu"
|
||||
remove @compilestack
|
||||
return expr:@@comma_separated_items("nomsu.defs[#{repr tree.stub}].fn(", args, ")")
|
||||
|
||||
@ -578,7 +582,7 @@ end]]\format(lua_code))
|
||||
@writeln "#{colored.bright "EXPR:"} #{lua.expr}, #{colored.bright "STATEMENT:"} #{lua.statements}"
|
||||
if lua.statements
|
||||
@error "Cannot use [[#{bit.src}]] as a string interpolation value, since it's not an expression."
|
||||
insert concat_parts, "nomsu:stringify(#{lua.expr})"
|
||||
insert concat_parts, "stringify(#{lua.expr})"
|
||||
|
||||
if string_buffer ~= ""
|
||||
insert concat_parts, repr(string_buffer)
|
||||
@ -759,52 +763,53 @@ end]]\format(lua_code))
|
||||
|
||||
initialize_core: =>
|
||||
-- Sets up some core functionality
|
||||
nomsu_string_as_lua = (code)=>
|
||||
nomsu = self
|
||||
nomsu_string_as_lua = (code)->
|
||||
concat_parts = {}
|
||||
for bit in *code.value
|
||||
if type(bit) == "string"
|
||||
insert concat_parts, bit
|
||||
else
|
||||
lua = @tree_to_lua bit
|
||||
lua = nomsu\tree_to_lua bit
|
||||
if lua.statements
|
||||
@error "Cannot use [[#{bit.src}]] as a string interpolation value, since it's not an expression."
|
||||
error "Cannot use [[#{bit.src}]] as a string interpolation value, since it's not an expression."
|
||||
insert concat_parts, lua.expr
|
||||
return concat(concat_parts)
|
||||
|
||||
@define_compile_action "do %block", "nomsu.moon", (_block)=>
|
||||
@define_compile_action "do %block", "nomsu.moon", (_block)->
|
||||
make_line = (lua)-> lua.expr and (lua.expr..";") or lua.statements
|
||||
if _block.type == "Block"
|
||||
return @tree_to_lua(_block)
|
||||
return nomsu\tree_to_lua(_block)
|
||||
else
|
||||
return expr:"#{@tree_to_lua _block}(nomsu)"
|
||||
return expr:"#{nomsu\tree_to_lua _block}(nomsu)"
|
||||
|
||||
@define_compile_action "immediately %block", "nomsu.moon", (_block)=>
|
||||
lua = @tree_to_lua(_block)
|
||||
@define_compile_action "immediately %block", "nomsu.moon", (_block)->
|
||||
lua = nomsu\tree_to_lua(_block)
|
||||
lua_code = lua.statements or (lua.expr..";")
|
||||
lua_code = "-- Immediately:\n"..lua_code
|
||||
@run_lua(lua_code)
|
||||
nomsu\run_lua(lua_code)
|
||||
return statements:lua_code
|
||||
|
||||
@define_compile_action "lua> %code", "nomsu.moon", (_code)=>
|
||||
lua = nomsu_string_as_lua(@, _code)
|
||||
@define_compile_action "lua> %code", "nomsu.moon", (_code)->
|
||||
lua = nomsu_string_as_lua(_code)
|
||||
return statements:lua
|
||||
|
||||
@define_compile_action "=lua %code", "nomsu.moon", (_code)=>
|
||||
lua = nomsu_string_as_lua(@, _code)
|
||||
@define_compile_action "=lua %code", "nomsu.moon", (_code)->
|
||||
lua = nomsu_string_as_lua(_code)
|
||||
return expr:lua
|
||||
|
||||
@define_compile_action "__line_no__", "nomsu.moon", ()=>
|
||||
expr: repr(@compilestack[#@compilestack]\get_line_no!)
|
||||
@define_compile_action "__line_no__", "nomsu.moon", ->
|
||||
expr: repr(nomsu.compilestack[#nomsu.compilestack]\get_line_no!)
|
||||
|
||||
@define_compile_action "__src__ %level", "nomsu.moon", (_level)=>
|
||||
expr: repr(@source_code(@tree_to_value(_level)))
|
||||
@define_compile_action "__src__ %level", "nomsu.moon", (_level)->
|
||||
expr: repr(nomsu\source_code(nomsu\tree_to_value(_level)))
|
||||
|
||||
@define_action "run file %filename", "nomsu.moon", (_filename)=>
|
||||
@run_file(_filename)
|
||||
@define_action "run file %filename", "nomsu.moon", (_filename)->
|
||||
nomus\run_file(_filename)
|
||||
|
||||
@define_compile_action "use %filename", "nomsu.moon", (_filename)=>
|
||||
filename = @tree_to_value(_filename)
|
||||
@require_file(filename)
|
||||
@define_compile_action "use %filename", "nomsu.moon", (_filename)->
|
||||
filename = nomsu\tree_to_value(_filename)
|
||||
nomsu\require_file(filename)
|
||||
return statements:"nomsu:require_file(#{repr filename});"
|
||||
|
||||
if arg
|
||||
|
11
utils.lua
11
utils.lua
@ -42,9 +42,12 @@ local _quote_patt = re.compile("(({'\n' / '\"' / \"'\" / '\\'}->mark_char) / (']
|
||||
mark_eq=function(eq)
|
||||
_quote_state.min_eq = max(_quote_state.min_eq or 0, #eq+1)
|
||||
end})
|
||||
local function repr(x)
|
||||
local function repr(x, depth)
|
||||
-- Create a string representation of the object that is close to the lua code that will
|
||||
-- reproduce the object (similar to Python's "repr" function)
|
||||
depth = depth or 10
|
||||
if depth == 0 then return "..." end
|
||||
depth = depth - 1
|
||||
local x_type = type(x)
|
||||
if x_type == 'table' then
|
||||
if getmetatable(x) then
|
||||
@ -55,12 +58,12 @@ local function repr(x)
|
||||
local i = 1
|
||||
for k, v in pairs(x) do
|
||||
if k == i then
|
||||
ret[#ret+1] = repr(x[i])
|
||||
ret[#ret+1] = repr(x[i], depth)
|
||||
i = i + 1
|
||||
elseif type(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
|
||||
ret[#ret+1] = k.."= "..repr(v)
|
||||
ret[#ret+1] = k.."= "..repr(v,depth)
|
||||
else
|
||||
ret[#ret+1] = "["..repr(k).."]= "..repr(v)
|
||||
ret[#ret+1] = "["..repr(k,depth).."]= "..repr(v,depth)
|
||||
end
|
||||
end
|
||||
return "{"..table.concat(ret, ", ").."}"
|
||||
|
Loading…
Reference in New Issue
Block a user