More correct and more working.

This commit is contained in:
Bruce Hill 2018-04-13 14:54:35 -07:00
parent b05a46c78c
commit 222d4d0727
4 changed files with 177 additions and 105 deletions

View File

@ -5,14 +5,13 @@
# Compile-time action to make compile-time actions:
immediately:
lua> ".."
nomsu:define_compile_action("compile %actions to %lua", \(!! code location !!), function(\%actions, \%lua)
local tree = nomsu.compilestack[#nomsu.compilestack];
nomsu:define_compile_action("compile %actions to %lua", \(!! code location !!), function(tree, \%actions, \%lua)
local lua = Lua(tree.source, "nomsu:define_compile_action(");
local stubs = {};
for i, action in ipairs(\%actions.value) do
stubs[i] = nomsu:tree_to_named_stub(action);
end
lua:append(repr(stubs), ", ", repr(tree.source:get_line()), ", function(");
lua:append(repr(stubs), ", ", repr(tree.source:get_line()), ", function(tree");
local args = {};
for i,tok in ipairs(\%actions.value[1].value) do
if tok.type == "Var" then args[#args+1] = nomsu:var_to_lua_identifier(tok.value); end
@ -21,10 +20,10 @@ immediately:
error("Invalid type for 'compile % to %', expected a dict with expr/statements, but got text.", 0);
end
for i, arg in ipairs(args) do
lua:append(", ");
lua:append(arg);
if i < #args then lua:append(", ") end
end
local body_lua = nomsu:tree_to_lua(\%lua):as_statements();
local body_lua = nomsu:tree_to_lua(\%lua):as_statements("return ");
body_lua:declare_locals(args);
lua:append(")\\n ", body_lua, "\\nend);")
return lua;
@ -34,7 +33,6 @@ immediately:
immediately:
compile [action %actions %body] to:
lua> ".."
local tree = nomsu.compilestack[#nomsu.compilestack];
local lua = Lua(tree.source, "nomsu:define_action(");
local stubs = {};
for i, action in ipairs(\%actions.value) do
@ -49,7 +47,7 @@ immediately:
lua:append(arg);
if i < #args then lua:append(", ") end
end
local body_lua = nomsu:tree_to_lua(\%body):as_statements();
local body_lua = nomsu:tree_to_lua(\%body):as_statements("return ");
body_lua:declare_locals(args);
lua:append(")\\n ", body_lua, "\\nend);")
return lua;
@ -58,20 +56,19 @@ immediately:
immediately:
compile [parse %shorthand as %longhand] to:
lua> ".."
local tree = nomsu.compilestack[#nomsu.compilestack];
local lua = Lua(tree.source, "nomsu:define_compile_action(");
local stubs = {};
for i, action in ipairs(\%shorthand.value) do
stubs[i] = nomsu:tree_to_named_stub(action);
end
lua:append(repr(stubs), ", ", repr(tree.source:get_line()), ", function(");
lua:append(repr(stubs), ", ", repr(tree.source:get_line()), ", function(tree");
local args = {};
for i,tok in ipairs(\%shorthand.value[1].value) do
if tok.type == "Var" then args[#args+1] = nomsu:var_to_lua_identifier(tok.value); end
end
for i, arg in ipairs(args) do
lua:append(", ");
lua:append(arg);
if i < #args then lua:append(", ") end
end
local template;
if \%longhand.type == "Block" then
@ -127,14 +124,14 @@ immediately:
=lua "nomsu:tree_to_stub(\%tree)"
immediately:
compile [%tree's source code, %tree' source code] to {expr:"\(%tree as lua expr).source:get_text()"}
compile [%tree's source code, %tree' source code] to: LuaValue "\(%tree as lua expr).source:get_text()"
compile [repr %obj] to {expr:"repr(\(%obj as lua expr))"}
compile [type of %obj] to {expr:"type(\(%obj as lua expr))"}
compile [repr %obj] to: LuaValue "repr(\(%obj as lua expr))"
compile [type of %obj] to: LuaValue "type(\(%obj as lua expr))"
immediately:
compile [nomsu] to {expr:"nomsu"}
compile [%var as lua identifier] to {expr:"nomsu:var_to_lua_identifier(\(%var as lua expr))"}
compile [nomsu] to: LuaValue "nomsu"
compile [%var as lua identifier] to: LuaValue "nomsu:var_to_lua_identifier(\(%var as lua expr))"
action [action %names metadata]:
=lua "nomsu.action_metadata[ACTIONS[\%names]]"
@ -151,9 +148,8 @@ action [help %action]:
# Compiler tools
immediately:
#local def_metadata = nomsu.tree_metadata[nomsu.compilestack[#nomsu.compilestack]];
compile [run %code] to {..}
expr: ".."
compile [run %code] to:
LuaValue ".."
nomsu:run(\(%code as lua expr), '\
=lua "nomsu:get_line_number(nomsu.compilestack[#nomsu.compilestack])"
..')
@ -164,44 +160,40 @@ immediately:
compile [show lua %block] to:
lua> ".."
local \%lua = nomsu:tree_to_lua(\%block);
return {statements = "print("..repr(\%lua.statements or \%lua.expr)..");"};
return Lua(\%block.source, "print(", repr(tostring(\%lua)), ");");
immediately:
compile [say %message] to:
lua> ".."
local tree = nomsu.compilestack[#nomsu.compilestack];
if \%message.type == "Text" then
return {statements="print("..\(%message as lua expr)..");"};
return Lua(tree.source, "print(", \(%message as lua expr), ");");
else
return {statements="print(stringify("..\(%message as lua expr).."));"};
return Lua(tree.source, "print(stringify(", \(%message as lua expr), "));");
end
# Return
immediately:
#.. Return statement is wrapped in a do..end block because Lua is unhappy if you
put code after a return statement, unless you wrap it in a block.
compile [return] to {statements:"do return; end"}
compile [return %return_value] to {statements:"do return \(%return_value as lua expr); end"}
compile [return] to: Lua "do return; end"
compile [return %return_value] to: Lua "do return \(%return_value as lua expr); end"
# Error functions
immediately:
compile [barf] to {statements:"error(nil, 0);"}
compile [barf %msg] to {statements:"error(\(%msg as lua expr), 0);"}
compile [barf] to: LuaValue "error(nil, 0);"
compile [barf %msg] to: LuaValue "error(\(%msg as lua expr), 0);"
compile [assume %condition] to:
lua> "local \%assumption = 'Assumption failed: '..\%condition.source:get_text();"
return {..}
statements:".."
return:
Lua ".."
if not \(%condition as lua expr) then
error(\(repr %assumption), 0);
end
compile [assume %condition or barf %msg] to {..}
statements:".."
if not \(%condition as lua expr) then
error(\(%msg as lua expr), 0);
end
# Literals
immediately:
compile [yes] to {expr:"true"}
compile [no] to {expr:"false"}
compile [nothing, nil, null] to {expr:"nil"}
compile [yes] to: LuaValue "true"
compile [no] to: LuaValue "false"
compile [nothing, nil, null] to: LuaValue "nil"

View File

@ -3,29 +3,26 @@ immutable = require 'immutable'
local Lua, LuaValue, Location
export LINE_STARTS
Location = immutable {"text_name","text","start","stop"}, {
Location = immutable {"filename","start","stop"}, {
name:"Location"
__new: (text_name, text, start, stop)=>
assert(type(text_name) == 'string')
assert(type(text) == 'string')
assert(type(start) == 'number')
assert(type(stop or start) == 'number')
return text_name, text, start, stop or start
__tostring: => "#{@text_name}[#{@start}:#{@stop}]"
__new: (filename, start, stop)=>
assert(type(filename) == 'string' and type(start) == 'number' and type(stop) == 'number')
return filename, start, stop or start
__tostring: => "Location(\"#{@filename}\", #{@start}, #{@stop})"
__lt: (other)=>
assert(@text == other.text, "Cannot compare sources from different texts")
assert(@filename == other.filename, "Cannot compare sources from different files")
return if @start == other.start
@stop < other.stop
else @start < other.start
__le: (other)=>
assert(@text == other.text, "Cannot compare sources from different texts")
assert(@filename == other.filename, "Cannot compare sources from different files")
return if @start == other.start
@stop <= other.stop
else @start <= other.start
get_text: => @text\sub(@start,@stop)
get_text: => FILE_CACHE[@filename]\sub(@start,@stop)
get_line_number: =>
-- TODO: do a binary search if this is actually slow, which I doubt
line_starts = LINE_STARTS[@text]
line_starts = LINE_STARTS[FILE_CACHE[@filename]]
start_line = 1
while (line_starts[start_line+1] or (#src+1)) <= @start
start_line += 1
@ -33,12 +30,12 @@ Location = immutable {"text_name","text","start","stop"}, {
while (line_starts[stop_line+1] or (#src+1)) <= @stop
stop_line += 1
return start_line, stop_line
get_line: => "#{@text_name}:#{@get_line_number!}"
get_line: => "#{@filename}:#{@get_line_number!}"
get_line_range: =>
start_line, stop_line = @get_line_number!
return if stop_line == start_line
"#{text_name}:#{start_line}"
else "#{text_name}:#{start_line}-#{stop_line}"
"#{@filename}:#{start_line}"
else "#{@filename}:#{start_line}-#{stop_line}"
}
class Lua
@ -46,6 +43,9 @@ class Lua
is_value: false
new: (@source, ...)=>
if type(@source) == 'string'
filename,start,stop = @source\match("^(.-)[(%d+):(%d+)]$")
@source = Location(filename, tonumber(start), tonumber(stop))
for i=1,select("#",...)
x = select(i,...)
assert(type(x) != 'table' or getmetatable(x))
@ -109,7 +109,7 @@ class Lua
-- Return a mapping from output (lua) character number to input (nomsu) character number
lua_str = tostring(self)
metadata = {
nomsu_filename:@source.text_name, nomsu_file:@source.text,
nomsu_filename:@source.filename
lua_filename:lua_chunkname, lua_file:lua_str
lua_to_nomsu: {}, nomsu_to_lua: {}
}
@ -122,7 +122,7 @@ class Lua
for b in *lua.bits
walk b
lua_stop = lua_offset
nomsu_src, lua_src = lua.source, Location(lua_chunkname, lua_str, lua_start, lua_stop)
nomsu_src, lua_src = lua.source, Location(lua_chunkname, lua_start, lua_stop)
metadata.lua_to_nomsu[lua_src] = nomsu_src
metadata.nomsu_to_lua[nomsu_src] = lua_src
walk self
@ -143,9 +143,9 @@ class LuaValue extends Lua
assert(not ret\match(".*table: 0x.*"))
return ret
as_statements: =>
bits = {unpack @bits}
bits[#bits+1] = ";"
as_statements: (prefix="", suffix=";")=>
bits = {prefix, unpack @bits}
bits[#bits+1] = suffix
return Lua(@source, unpack(bits))
parenthesize: =>

View File

@ -32,7 +32,7 @@ do
local _obj_0 = require("lua_obj")
Lua, LuaValue, Location = _obj_0.Lua, _obj_0.LuaValue, _obj_0.Location
end
local FILE_CACHE = setmetatable({ }, {
FILE_CACHE = setmetatable({ }, {
__index = function(self, filename)
local file = io.open(filename)
if not (file) then
@ -196,7 +196,7 @@ do
pos = pos + #lpeg.userdata.source_code:match("[ \t\n\r]*", pos)
end
local line_no = 1
local text_loc = Location(lpeg.userdata.filename, src, pos)
local text_loc = Location(lpeg.userdata.filename, pos)
line_no = text_loc:get_line_number()
local prev_line = src:sub(LINE_STARTS[src][line_no - 1] or 1, LINE_STARTS[src][line_no] - 1)
local err_line = src:sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no + 1] or 0) - 1)
@ -215,7 +215,7 @@ setmetatable(NOMSU_DEFS, {
if type(value) == 'table' then
error("Not a tuple: " .. tostring(repr(value)))
end
local loc = Location(lpeg.userdata.filename, lpeg.userdata.source_code, start, stop)
local loc = Location(lpeg.userdata.filename, start, stop)
local node = Types[key](value, loc)
return node
end
@ -282,9 +282,6 @@ do
end
arg_positions = _accum_0
end
if #arg_positions ~= #args then
error("Mismatch in args between lua function's " .. tostring(repr(fn_arg_positions)) .. " and stub's " .. tostring(repr(args)) .. " for " .. tostring(repr(stub)), 0)
end
arg_orders[stub] = arg_positions
end
end
@ -379,7 +376,8 @@ do
local tree = self:parse(nomsu_code, filename)
assert(tree, "Failed to parse: " .. tostring(nomsu_code))
assert(tree.type == "File", "Attempt to run non-file: " .. tostring(tree.type))
local lua = self:tree_to_lua(tree):as_statements():with_locals_declared()
local lua = self:tree_to_lua(tree):as_statements()
lua:declare_locals()
lua:prepend("-- File: " .. tostring(filename) .. "\n")
return self:run_lua(lua, filename .. ".lua")
end,
@ -449,8 +447,9 @@ do
_chunk_counter = _chunk_counter + 1
filename = "<lua chunk #" .. tostring(_chunk_counter) .. ">"
else
filename = lua.source.text_name .. ".lua"
filename = lua.source.filename .. ".lua"
end
FILE_CACHE[filename] = tostring(lua)
end
if type(lua) ~= 'string' then
local metadata
@ -475,7 +474,7 @@ do
return tree.value[1]
end
local lua = Lua(tree.source, "return ", self:tree_to_lua(tree), ";")
return self:run_lua(lua, tree.source.text_name)
return self:run_lua(lua, tree.source.filename)
end,
tree_to_nomsu = function(self, tree, indentation, max_line, expr_type)
if indentation == nil then
@ -896,9 +895,9 @@ do
file_lua:declare_locals()
return file_lua
elseif "Comment" == _exp_0 then
return Lua(tree.source, "--" .. tree.value:gsub("\n", "\n--"))
return Lua(tree.source, "--" .. tree.value:gsub("\n", "\n--") .. "\n")
elseif "Nomsu" == _exp_0 then
return Lua(tree.source, "nomsu:parse(", tree.source:get_text(), ", ", repr(tree.source.text_name), ")")
return Lua(tree.source, "nomsu:parse(", tree.source:get_text(), ", ", repr(tree.source.filename), ")")
elseif "Block" == _exp_0 then
local block_lua = Lua(tree.source)
for i, arg in ipairs(tree.value) do
@ -941,14 +940,14 @@ do
local _list_1 = metadata.arg_orders[stub]
for _index_0 = 1, #_list_1 do
local p = _list_1[_index_0]
_accum_0[_len_0] = args[p]
_accum_0[_len_0] = args[p - 1]
_len_0 = _len_0 + 1
end
new_args = _accum_0
end
args = new_args
end
local lua = action(unpack(args))
local lua = action(tree, unpack(args))
remove(self.compilestack)
return lua
elseif not metadata and self.__class.math_patt:match(stub) then
@ -1367,15 +1366,61 @@ do
return "nomsu.moon:" .. tostring(debug_getinfo(2).currentline)
end
local nomsu = self
self:define_compile_action("immediately %block", get_line_no(), function(_block)
self:define_compile_action("immediately %block", get_line_no(), function(self, _block)
local lua = nomsu:tree_to_lua(_block):as_statements()
lua:declare_locals()
nomsu:run_lua(lua)
return Lua(_block.source, "if IMMEDIATE then\n", lua, "\nend")
return Lua(self.source, "if IMMEDIATE then\n", lua, "\nend")
end)
self:define_compile_action("lua> %code", get_line_no(), function(_code)
self:define_compile_action("Lua %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return LuaValue(_code.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
return LuaValue(self.source, "Lua(", repr(_code.source), ", ", nomsu:tree_to_lua(_code), ")")
end
local lua = LuaValue(self.source, "Lua(", repr(_code.source))
local _list_1 = _code.value
for _index_0 = 1, #_list_1 do
local bit = _list_1[_index_0]
lua:append(", ")
if type(bit) == "string" then
lua:append(repr(bit))
else
local bit_lua = nomsu:tree_to_lua(bit)
if not (bit_lua.is_value) then
local line, src = bit.source:get_line(), bit.source:get_text()
error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a string interpolation value, since it's not an expression.", 0)
end
lua:append(bit_lua)
end
end
lua:append(")")
return lua
end)
self:define_compile_action("LuaValue %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return LuaValue(self.source, "LuaValue(", repr(_code.source), ", ", nomsu:tree_to_lua(_code), ")")
end
local lua = LuaValue(self.source, "LuaValue(", repr(_code.source))
local _list_1 = _code.value
for _index_0 = 1, #_list_1 do
local bit = _list_1[_index_0]
lua:append(", ")
if type(bit) == "string" then
lua:append(repr(bit))
else
local bit_lua = nomsu:tree_to_lua(bit)
if not (bit_lua.is_value) then
local line, src = bit.source:get_line(), bit.source:get_text()
error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a string interpolation value, since it's not an expression.", 0)
end
lua:append(bit_lua)
end
end
lua:append(")")
return lua
end)
self:define_compile_action("lua> %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return LuaValue(self.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
end
local lua = Lua(_code.source)
local _list_1 = _code.value
@ -1394,11 +1439,11 @@ do
end
return lua
end)
self:define_compile_action("=lua %code", get_line_no(), function(_code)
self:define_compile_action("=lua %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return LuaValue(_code.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
return LuaValue(self.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
end
local lua = LuaValue(_code.source)
local lua = LuaValue(self.source)
local _list_1 = _code.value
for _index_0 = 1, #_list_1 do
local bit = _list_1[_index_0]
@ -1415,18 +1460,16 @@ do
end
return lua
end)
self:define_compile_action("!! code location !!", get_line_no(), function()
local tree = nomsu.compilestack[#nomsu.compilestack - 1]
return LuaValue(tree.source, repr(tostring(tree.source)))
self:define_compile_action("!! code location !!", get_line_no(), function(self)
return LuaValue(self.source, repr(self.source))
end)
self:define_action("run file %filename", get_line_no(), function(_filename)
return nomsu:run_file(_filename)
end)
return self:define_compile_action("use %filename", get_line_no(), function(_filename)
local tree = nomsu.compilestack[#nomsu.compilestack - 1]
return self:define_compile_action("use %filename", get_line_no(), function(self, _filename)
local filename = nomsu:tree_to_value(_filename)
nomsu:use_file(filename)
return LuaValue(tree.source, "nomsu:use_file(" .. tostring(repr(filename)) .. ")")
return LuaValue(self.source, "nomsu:use_file(" .. tostring(repr(filename)) .. ")")
end)
end
}

View File

@ -36,6 +36,7 @@ debug_getinfo = debug.getinfo
-- Add a ((%x foo %y) where {x:"asdf", y:"fdsa"}) compile-time action for substitution
-- Allow plain text backslash like: "\n" in longstrings without requiring "\\n"
export FILE_CACHE
FILE_CACHE = setmetatable {}, {
__index: (filename)=>
file = io.open(filename)
@ -149,7 +150,7 @@ NOMSU_DEFS = with {}
if lpeg.userdata.source_code\sub(pos,pos)\match("[\r\n]")
pos += #lpeg.userdata.source_code\match("[ \t\n\r]*", pos)
line_no = 1
text_loc = Location(lpeg.userdata.filename, src, pos)
text_loc = Location(lpeg.userdata.filename, pos)
line_no = text_loc\get_line_number!
prev_line = src\sub(LINE_STARTS[src][line_no-1] or 1, LINE_STARTS[src][line_no]-1)
err_line = src\sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no+1] or 0)-1)
@ -162,7 +163,7 @@ NOMSU_DEFS = with {}
setmetatable(NOMSU_DEFS, {__index:(key)=>
make_node = (start, value, stop)->
if type(value) == 'table' then error("Not a tuple: #{repr value}")-- = Tuple(value)
loc = Location(lpeg.userdata.filename, lpeg.userdata.source_code, start, stop)
loc = Location(lpeg.userdata.filename, start, stop)
node = Types[key](value, loc)
return node
self[key] = make_node
@ -247,8 +248,8 @@ class NomsuCompiler
unless fn_info.isvararg
arg_positions = [fn_arg_positions[a] for a in *args]
-- TODO: better error checking?
if #arg_positions != #args
error("Mismatch in args between lua function's #{repr fn_arg_positions} and stub's #{repr args} for #{repr stub}", 0)
--if #arg_positions != #args
-- error("Mismatch in args between lua function's #{repr fn_arg_positions} and stub's #{repr args} for #{repr stub}", 0)
arg_orders[stub] = arg_positions
@action_metadata[fn] = {
@ -304,7 +305,8 @@ class NomsuCompiler
tree = @parse(nomsu_code, filename)
assert tree, "Failed to parse: #{nomsu_code}"
assert tree.type == "File", "Attempt to run non-file: #{tree.type}"
lua = @tree_to_lua(tree)\as_statements!\with_locals_declared!
lua = @tree_to_lua(tree)\as_statements!
lua\declare_locals!
lua\prepend "-- File: #{filename}\n"
return @run_lua(lua, filename..".lua")
@ -353,7 +355,8 @@ class NomsuCompiler
_chunk_counter += 1
"<lua chunk ##{_chunk_counter}>"
else
lua.source.text_name..".lua"
lua.source.filename..".lua"
FILE_CACHE[filename] = tostring(lua)
if type(lua) != 'string'
lua, metadata = lua\make_offset_table(filename)
LUA_METADATA[lua] = metadata
@ -373,7 +376,7 @@ class NomsuCompiler
if tree.type == 'Text' and #tree.value == 1 and type(tree.value[1]) == 'string'
return tree.value[1]
lua = Lua(tree.source, "return ",@tree_to_lua(tree),";")
return @run_lua(lua, tree.source.text_name)
return @run_lua(lua, tree.source.filename)
tree_to_nomsu: (tree, indentation="", max_line=80, expr_type=nil)=>
-- Convert a tree into nomsu code that satisfies the max line requirement or nil
@ -659,11 +662,11 @@ class NomsuCompiler
return file_lua
when "Comment"
return Lua(tree.source, "--"..tree.value\gsub("\n","\n--"))
return Lua(tree.source, "--"..tree.value\gsub("\n","\n--").."\n")
when "Nomsu"
--return Lua(tree.source, repr(tree.value))
return Lua(tree.source, "nomsu:parse(",tree.source\get_text!,", ",repr(tree.source.text_name),")")
return Lua(tree.source, "nomsu:parse(",tree.source\get_text!,", ",repr(tree.source.filename),")")
when "Block"
block_lua = Lua(tree.source)
@ -688,9 +691,9 @@ class NomsuCompiler
args = [arg for arg in *tree.value when arg.type != "Word"]
-- Force all compile-time actions to take a tree location
if metadata and metadata.arg_orders
new_args = [args[p] for p in *metadata.arg_orders[stub]]
new_args = [args[p-1] for p in *metadata.arg_orders[stub]]
args = new_args
lua = action(unpack(args))
lua = action(tree, unpack(args))
remove @compilestack
return lua
elseif not metadata and @@math_patt\match(stub)
@ -1005,15 +1008,51 @@ class NomsuCompiler
-- Sets up some core functionality
get_line_no = -> "nomsu.moon:#{debug_getinfo(2).currentline}"
nomsu = self
@define_compile_action "immediately %block", get_line_no!, (_block)->
@define_compile_action "immediately %block", get_line_no!, (_block)=>
lua = nomsu\tree_to_lua(_block)\as_statements!
lua\declare_locals!
nomsu\run_lua(lua)
return Lua(_block.source, "if IMMEDIATE then\n", lua, "\nend")
return Lua(@source, "if IMMEDIATE then\n", lua, "\nend")
@define_compile_action "lua> %code", get_line_no!, (_code)->
@define_compile_action "Lua %code", get_line_no!, (_code)=>
if _code.type != "Text"
return LuaValue(_code.source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
return LuaValue(@source, "Lua(", repr(_code.source),", ",nomsu\tree_to_lua(_code),")")
lua = LuaValue(@source, "Lua(", repr(_code.source))
for bit in *_code.value
lua\append ", "
if type(bit) == "string"
lua\append repr(bit)
else
bit_lua = nomsu\tree_to_lua bit
unless bit_lua.is_value
line, src = bit.source\get_line!, bit.source\get_text!
error "#{line}: Cannot use #{colored.yellow src} as a string interpolation value, since it's not an expression.", 0
lua\append bit_lua
lua\append ")"
return lua
@define_compile_action "LuaValue %code", get_line_no!, (_code)=>
if _code.type != "Text"
return LuaValue(@source, "LuaValue(", repr(_code.source),", ",nomsu\tree_to_lua(_code),")")
lua = LuaValue(@source, "LuaValue(", repr(_code.source))
for bit in *_code.value
lua\append ", "
if type(bit) == "string"
lua\append repr(bit)
else
bit_lua = nomsu\tree_to_lua bit
unless bit_lua.is_value
line, src = bit.source\get_line!, bit.source\get_text!
error "#{line}: Cannot use #{colored.yellow src} as a string interpolation value, since it's not an expression.", 0
lua\append bit_lua
lua\append ")"
return lua
@define_compile_action "lua> %code", get_line_no!, (_code)=>
if _code.type != "Text"
return LuaValue(@source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
lua = Lua(_code.source)
for bit in *_code.value
@ -1027,11 +1066,11 @@ class NomsuCompiler
lua\append bit_lua
return lua
@define_compile_action "=lua %code", get_line_no!, (_code)->
@define_compile_action "=lua %code", get_line_no!, (_code)=>
if _code.type != "Text"
return LuaValue(_code.source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
return LuaValue(@source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
lua = LuaValue(_code.source)
lua = LuaValue(@source)
for bit in *_code.value
if type(bit) == "string"
lua\append bit
@ -1043,18 +1082,16 @@ class NomsuCompiler
lua\append bit_lua
return lua
@define_compile_action "!! code location !!", get_line_no!, ->
tree = nomsu.compilestack[#nomsu.compilestack-1]
return LuaValue(tree.source, repr(tostring(tree.source)))
@define_compile_action "!! code location !!", get_line_no!, =>
return LuaValue(@source, repr(@source))
@define_action "run file %filename", get_line_no!, (_filename)->
return nomsu\run_file(_filename)
@define_compile_action "use %filename", get_line_no!, (_filename)->
tree = nomsu.compilestack[#nomsu.compilestack-1]
@define_compile_action "use %filename", get_line_no!, (_filename)=>
filename = nomsu\tree_to_value(_filename)
nomsu\use_file(filename)
return LuaValue(tree.source, "nomsu:use_file(#{repr filename})")
return LuaValue(@source, "nomsu:use_file(#{repr filename})")
-- Only run this code if this file was run directly with command line arguments, and not require()'d:
if arg and debug_getinfo(2).func != require