Incremental progress towards working.

This commit is contained in:
Bruce Hill 2018-04-12 18:01:51 -07:00
parent 17a2bded6a
commit 1de29826a8
4 changed files with 73 additions and 38 deletions

View File

@ -26,7 +26,7 @@ immediately:
end end
local body_lua = nomsu:tree_to_lua(\%lua):as_statements(); local body_lua = nomsu:tree_to_lua(\%lua):as_statements();
body_lua:declare_locals(args); body_lua:declare_locals(args);
lua:append("\\n ", body_lua, "\\nend);") lua:append(")\\n ", body_lua, "\\nend);")
return lua; return lua;
end); end);

View File

@ -56,6 +56,7 @@ class Lua
declare_locals: (skip={})=> declare_locals: (skip={})=>
if next(skip) == 1 if next(skip) == 1
skip = {[s]:true for s in *skip} skip = {[s]:true for s in *skip}
if #@free_vars > 0
@prepend "local #{concat @free_vars, ", "};\n" @prepend "local #{concat @free_vars, ", "};\n"
for var in *@free_vars do skip[var] = true for var in *@free_vars do skip[var] = true
for bit in *@bits for bit in *@bits
@ -66,7 +67,9 @@ class Lua
buff = {} buff = {}
for b in *@bits for b in *@bits
buff[#buff+1] = tostring(b) buff[#buff+1] = tostring(b)
return concat(buff, "") ret = concat(buff, "")
assert(not ret\match(".*table: 0x.*"))
return ret
__len: => __len: =>
len = 0 len = 0
@ -96,7 +99,6 @@ class Lua
lua_filename:lua_chunkname, lua_file:lua_str lua_filename:lua_chunkname, lua_file:lua_str
lua_to_nomsu: {}, nomsu_to_lua: {} lua_to_nomsu: {}, nomsu_to_lua: {}
} }
metadata, lua_offset = {}, 1
lua_offset = 1 lua_offset = 1
walk = (lua)-> walk = (lua)->
if type(lua) == 'string' if type(lua) == 'string'
@ -106,7 +108,7 @@ class Lua
for b in *lua.bits for b in *lua.bits
walk b walk b
lua_stop = lua_offset lua_stop = lua_offset
nomsu_src, lua_src = lua.souce, Location(lua_chunkname, lua_str, lua_start, lua_stop) nomsu_src, lua_src = lua.source, Location(lua_chunkname, lua_str, lua_start, lua_stop)
metadata.lua_to_nomsu[lua_src] = nomsu_src metadata.lua_to_nomsu[lua_src] = nomsu_src
metadata.nomsu_to_lua[nomsu_src] = lua_src metadata.nomsu_to_lua[nomsu_src] = lua_src
walk self walk self
@ -119,6 +121,14 @@ class LuaValue extends Lua
new: (@source, ...)=> new: (@source, ...)=>
@bits = {...} @bits = {...}
__tostring: =>
buff = {}
for b in *@bits
buff[#buff+1] = tostring(b)
ret = concat(buff, "")
assert(not ret\match(".*table: 0x.*"))
return ret
as_statements: => as_statements: =>
bits = {unpack @bits} bits = {unpack @bits}
bits[#bits+1] = ";" bits[#bits+1] = ";"

View File

@ -916,8 +916,8 @@ do
elseif "FunctionCall" == _exp_0 then elseif "FunctionCall" == _exp_0 then
insert(self.compilestack, tree) insert(self.compilestack, tree)
local stub = self:tree_to_stub(tree) local stub = self:tree_to_stub(tree)
local fn = rawget(self.environment.ACTIONS, stub) local action = rawget(self.environment.ACTIONS, stub)
local metadata = self.action_metadata[fn] local metadata = self.action_metadata[action]
if metadata and metadata.compile_time then if metadata and metadata.compile_time then
local args local args
do do
@ -948,7 +948,7 @@ do
end end
args = new_args args = new_args
end end
local lua = fn(unpack(args)) local lua = action(unpack(args))
remove(self.compilestack) remove(self.compilestack)
return lua return lua
elseif not metadata and self.__class.math_patt:match(stub) then elseif not metadata and self.__class.math_patt:match(stub) then
@ -1419,9 +1419,7 @@ do
end) end)
self:define_compile_action("!! code location !!", get_line_no(), function() self:define_compile_action("!! code location !!", get_line_no(), function()
local tree = nomsu.compilestack[#nomsu.compilestack - 1] local tree = nomsu.compilestack[#nomsu.compilestack - 1]
return LuaValue(tree.source, { return LuaValue(tree.source, repr(tostring(tree.source)))
repr(tostring(tree.source))
})
end) end)
self:define_action("run file %filename", get_line_no(), function(_filename) self:define_action("run file %filename", get_line_no(), function(_filename)
return nomsu:run_file(_filename) return nomsu:run_file(_filename)
@ -1430,9 +1428,7 @@ do
local tree = nomsu.compilestack[#nomsu.compilestack - 1] local tree = nomsu.compilestack[#nomsu.compilestack - 1]
local filename = nomsu:tree_to_value(_filename) local filename = nomsu:tree_to_value(_filename)
nomsu:use_file(filename) nomsu:use_file(filename)
return LuaValue(tree.source, { return LuaValue(tree.source, "nomsu:use_file(" .. tostring(repr(filename)) .. ")")
"nomsu:use_file(" .. tostring(repr(filename)) .. ")"
})
end) end)
end end
} }
@ -1510,6 +1506,9 @@ do
self.environment[k] = v self.environment[k] = v
end end
self.environment.Tuple = Tuple self.environment.Tuple = Tuple
self.environment.Lua = Lua
self.environment.LuaValue = LuaValue
self.environment.Location = Location
self.environment.ACTIONS = setmetatable({ }, { self.environment.ACTIONS = setmetatable({ }, {
__index = function(self, key) __index = function(self, key)
return error("Attempt to run undefined action: " .. tostring(key), 0) return error("Attempt to run undefined action: " .. tostring(key), 0)
@ -1597,21 +1596,37 @@ if arg and debug_getinfo(2).func ~= require then
return line_table return line_table
end end
}) })
debug.getinfo = function(...) debug.getinfo = function(thread, f, what)
local info = debug_getinfo(...) if what == nil then
f, what, thread = thread, f, nil
end
if type(f) == 'number' then
f = f + 1
end
local info
if thread == nil then
info = debug_getinfo(f, what)
else
info = debug_getinfo(thread, f, what)
end
if not info or not info.func then if not info or not info.func then
return info return info
end end
if info.source and info.source:sub(1, 1) ~= "@" and LINE_STARTS[info.source] then
do do
local metadata = nomsu.action_metadata[info.func] local metadata = nomsu.action_metadata[info.func]
if metadata then if metadata then
info.name = metadata.aliases[1] info.name = metadata.aliases[1]
end end
end end
local is_nomsu, nomsu_line = pcall(lua_line_to_nomsu_line, info.short_src, info.linedefined)
if is_nomsu then
if info.source:sub(1, 1) == "@" then if info.source:sub(1, 1) == "@" then
error("Not-yet-loaded source: " .. tostring(info.source)) error("Not-yet-loaded source: " .. tostring(info.source))
end end
info.linedefined = nomsu_line
info.currentline = lua_line_to_nomsu_line(info.short_src, info.currentline)
info.short_src = metadata.source.text_name
info.source = metadata.source.text
else else
if info.short_src and info.short_src:match("^.*%.moon$") then if info.short_src and info.short_src:match("^.*%.moon$") then
local line_table = moonscript_line_tables[info.short_src] local line_table = moonscript_line_tables[info.short_src]

View File

@ -34,6 +34,7 @@ debug_getinfo = debug.getinfo
-- Do a pass on all actions to enforce parameters-are-nouns heuristic -- Do a pass on all actions to enforce parameters-are-nouns heuristic
-- Maybe do some sort of lazy definitions of actions that defer until they're used in code -- Maybe do some sort of lazy definitions of actions that defer until they're used in code
-- Add a ((%x foo %y) where {x:"asdf", y:"fdsa"}) compile-time action for substitution -- 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"
FILE_CACHE = setmetatable {}, { FILE_CACHE = setmetatable {}, {
__index: (filename)=> __index: (filename)=>
@ -215,6 +216,9 @@ class NomsuCompiler
} }
for k,v in pairs(Types) do @environment[k] = v for k,v in pairs(Types) do @environment[k] = v
@environment.Tuple = Tuple @environment.Tuple = Tuple
@environment.Lua = Lua
@environment.LuaValue = LuaValue
@environment.Location = Location
@environment.ACTIONS = setmetatable({}, {__index:(key)=> @environment.ACTIONS = setmetatable({}, {__index:(key)=>
error("Attempt to run undefined action: #{key}", 0) error("Attempt to run undefined action: #{key}", 0)
}) })
@ -677,16 +681,16 @@ class NomsuCompiler
insert @compilestack, tree insert @compilestack, tree
stub = @tree_to_stub tree stub = @tree_to_stub tree
fn = rawget(@environment.ACTIONS, stub) action = rawget(@environment.ACTIONS, stub)
metadata = @action_metadata[fn] metadata = @action_metadata[action]
if metadata and metadata.compile_time if metadata and metadata.compile_time
args = [arg for arg in *tree.value when arg.type != "Word"] args = [arg for arg in *tree.value when arg.type != "Word"]
-- Force all compile-time actions to take a tree location -- Force all compile-time actions to take a tree location
if metadata and metadata.arg_orders if metadata and metadata.arg_orders
new_args = [args[p] for p in *metadata.arg_orders[stub]] new_args = [args[p] for p in *metadata.arg_orders[stub]]
args = new_args args = new_args
lua = fn(unpack(args)) lua = action(unpack(args))
remove @compilestack remove @compilestack
return lua return lua
elseif not metadata and @@math_patt\match(stub) elseif not metadata and @@math_patt\match(stub)
@ -1005,13 +1009,13 @@ class NomsuCompiler
lua = nomsu\tree_to_lua(_block)\as_statements! lua = nomsu\tree_to_lua(_block)\as_statements!
lua\declare_locals! lua\declare_locals!
nomsu\run_lua(lua) nomsu\run_lua(lua)
return Lua _block.source, "if IMMEDIATE then\n", lua, "\nend" return Lua(_block.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" if _code.type != "Text"
return LuaValue(_code.source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")") return LuaValue(_code.source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
lua = Lua _code.source lua = Lua(_code.source)
for bit in *_code.value for bit in *_code.value
if type(bit) == "string" if type(bit) == "string"
lua\append bit lua\append bit
@ -1041,7 +1045,7 @@ class NomsuCompiler
@define_compile_action "!! code location !!", get_line_no!, -> @define_compile_action "!! code location !!", get_line_no!, ->
tree = nomsu.compilestack[#nomsu.compilestack-1] tree = nomsu.compilestack[#nomsu.compilestack-1]
return LuaValue(tree.source, {repr(tostring(tree.source))}) return LuaValue(tree.source, repr(tostring(tree.source)))
@define_action "run file %filename", get_line_no!, (_filename)-> @define_action "run file %filename", get_line_no!, (_filename)->
return nomsu\run_file(_filename) return nomsu\run_file(_filename)
@ -1050,7 +1054,7 @@ class NomsuCompiler
tree = nomsu.compilestack[#nomsu.compilestack-1] tree = nomsu.compilestack[#nomsu.compilestack-1]
filename = nomsu\tree_to_value(_filename) filename = nomsu\tree_to_value(_filename)
nomsu\use_file(filename) nomsu\use_file(filename)
return LuaValue(tree.source, {"nomsu:use_file(#{repr filename})"}) return LuaValue(tree.source, "nomsu:use_file(#{repr filename})")
-- Only run this code if this file was run directly with command line arguments, and not require()'d: -- 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 if arg and debug_getinfo(2).func != require
@ -1081,17 +1085,23 @@ if arg and debug_getinfo(2).func != require
return line_table return line_table
} }
debug.getinfo = (...)-> debug.getinfo = (thread,f,what)->
info = debug_getinfo(...) if what == nil
f,what,thread = thread,f,nil
if type(f) == 'number' then f += 1 -- Account for this wrapper function
info = if thread == nil
debug_getinfo(f,what)
else debug_getinfo(thread,f,what)
if not info or not info.func then return info if not info or not info.func then return info
if info.source and info.source\sub(1,1) != "@" and LINE_STARTS[info.source]
if metadata = nomsu.action_metadata[info.func] if metadata = nomsu.action_metadata[info.func]
info.name = metadata.aliases[1] info.name = metadata.aliases[1]
is_nomsu, nomsu_line = pcall(lua_line_to_nomsu_line, info.short_src, info.linedefined)
if is_nomsu
if info.source\sub(1,1) == "@" then error("Not-yet-loaded source: #{info.source}") if info.source\sub(1,1) == "@" then error("Not-yet-loaded source: #{info.source}")
--info.linedefined = lua_line_to_nomsu_line(info.short_src, info.linedefined) info.linedefined = nomsu_line
--info.currentline = lua_line_to_nomsu_line(info.short_src, info.currentline) info.currentline = lua_line_to_nomsu_line(info.short_src, info.currentline)
--info.short_src = metadata.source.text_name info.short_src = metadata.source.text_name
--info.source = metadata.source.text info.source = metadata.source.text
else else
if info.short_src and info.short_src\match("^.*%.moon$") if info.short_src and info.short_src\match("^.*%.moon$")
line_table = moonscript_line_tables[info.short_src] line_table = moonscript_line_tables[info.short_src]