More cleanup, slowly working through operators/control_flow

This commit is contained in:
Bruce Hill 2018-04-18 17:41:40 -07:00
parent ec17442090
commit dcb380f1f6
8 changed files with 157 additions and 116 deletions

View File

@ -8,7 +8,7 @@ use "core/operators.nom"
# No-Op
immediately:
compile [do nothing] to {statements:""}
compile [do nothing] to: Lua ""
# Conditionals
immediately:
@ -59,15 +59,15 @@ immediately
# GOTOs
immediately:
compile [=== %label ===, --- %label ---, *** %label ***] to {..}
statements:"::label_\(%label as lua identifier)::;"
compile [go to %label] to {..}
statements:"goto label_\(%label as lua identifier);"
compile [=== %label ===, --- %label ---, *** %label ***] to
Lua "::label_\(%label as lua identifier)::;"
compile [go to %label] to
Lua "goto label_\(%label as lua identifier);"
# Basic loop control
immediately:
compile [do next] to {statements:"continue;"}
compile [stop] to {statements:"break;"}
compile [do next] to: Lua "continue;"
compile [stop] to: Lua "break;"
# Helper function
immediately:
@ -84,17 +84,17 @@ immediately:
# While loops
immediately:
compile [do next repeat] to {statements:"goto continue_repeat;"}
compile [stop repeating] to {statements:"goto stop_repeat;"}
compile [do next repeat] to: Lua "goto continue_repeat;"
compile [stop repeating] to: Lua "goto stop_repeat;"
compile [repeat while %condition %body] to
%lua <-: Lua "while \(%condition as lua expr) do"
if %body has subtree % where:
(%.type = "Action") and ((%'s stub) is "do next repeat")
..:
%lua +<- "\n::continue_repeat::;"
%lua +<- "\n"
%lua +<- (%body as lua statements)
%lua +<- "\nend --while-loop"
%lua <-write "\n::continue_repeat::;"
%lua <-write "\n"
%lua <-write (%body as lua statements)
%lua <-write "\nend --while-loop"
if %body has subtree % where:
(%.type = "Action") and ((%'s stub) is "stop repeating")
..:
@ -113,8 +113,8 @@ immediately:
%lua <-: Lua "for i=1,\(%n as lua expr) do"
if %body has subtree % where
(%.type = "Action") and ((%'s stub) is "do next repeat")
..: %lua +<- "\n::continue_repeat::;"
%lua +<- "\n\(%body as lua statements)\nend --numeric for-loop"
..: %lua <-write "\n::continue_repeat::;"
%lua <-write "\n\(%body as lua statements)\nend --numeric for-loop"
if %body has subtree % where:
(%.type = "Action") and ((%'s stub) is "stop repeating")
..:
@ -128,10 +128,10 @@ immediately:
# For loop control flow:
immediately:
compile [stop %var] to {..}
statements:"goto stop_\(%var as lua identifier);"
compile [do next %var] to {..}
statements:"goto continue_\(%var as lua identifier);"
compile [stop %var] to
Lua "goto stop_\(%var as lua identifier);"
compile [do next %var] to
Lua "goto continue_\(%var as lua identifier);"
# Numeric range for loops
immediately:
@ -148,15 +148,15 @@ immediately:
(%.type = "Action") and
((%'s stub) is "do next %") and
%.value.3.value is %var.value
..: %lua write code "\n::continue_\(%var as lua identifier)::;"
%lua write code "\n\(%body as lua statements)\nend --numeric for-loop"
..: %lua <-write "\n::continue_\(%var as lua identifier)::;"
%lua <-write "\n\(%body as lua statements)\nend --numeric for-loop"
if %body has subtree % where:
(%.type = "Action") and:
((%'s stub) is "stop %") and:
%.value.2.value is %var.value
..:
%lua write code ".."
%lua <-write ".."
do -- scope for stopping for-loop
\%lua
::stop_\(%var as lua identifier)::;
@ -182,8 +182,8 @@ immediately:
(%.type = "Action") and
((%'s stub) is "do next %") and
%.value.3.value is %var.value
..: %lua +<- (Lua "\n::continue_\(%var as lua identifier)::;")
%lua +<- (Lua "\n\(%body as lua statements)\nend --foreach-loop")
..: %lua <-write (Lua "\n::continue_\(%var as lua identifier)::;")
%lua <-write (Lua "\n\(%body as lua statements)\nend --foreach-loop")
if %body has subtree % where:
(%.type = "Action") and
((%'s stub) is "stop %") and
@ -210,27 +210,27 @@ immediately:
(%.type = "Action") and
((%'s stub) is "do next %") and
%.value.3.value is %key.value
..: %lua +<- (Lua "\n::continue_\(%key as lua identifier)::;")
..: %lua <-write (Lua "\n::continue_\(%key as lua identifier)::;")
if %body has subtree % where:
(%.type = "Action") and
((%'s stub) is "do next %") and
%.value.3.value is %value.value
..: %lua +<- (Lua "\n::continue_\(%value as lua identifier)::;")
%lua +<- (Lua "\n\(%body as lua statements)\nend --foreach-loop")
..: %lua <-write (Lua "\n::continue_\(%value as lua identifier)::;")
%lua <-write (Lua "\n\(%body as lua statements)\nend --foreach-loop")
%stop_labels <- ""
if %body has subtree % where:
(%.type = "Action") and
((%'s stub) is "stop %") and
%.value.2.value is %key.value
..: %stop_labels +<- "\n::stop_\(%key as lua identifier)::;"
..: %stop_labels <-write "\n::stop_\(%key as lua identifier)::;"
if %body has subtree % where:
(%.type = "Action") and
((%'s stub) is "stop %") and
%.value.2.value is %value.value
..: %stop_labels +<- "\n::stop_\(%value as lua identifier)::;"
..: %stop_labels <-write "\n::stop_\(%value as lua identifier)::;"
if: %stop_labels is not ""
%lua <-
@ -271,7 +271,7 @@ immediately:
if: =lua "\%condition.type == 'Word' and \%condition.value == 'else'"
assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block"
%code +<- ".."
%code <-write ".."
else
\%action_statements
@ -280,7 +280,7 @@ immediately:
assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block"
lua> "table.insert(\%fallthroughs, \(%condition as lua expr));"
%condition_code <- (%fallthroughs joined with " or ")
%code +<- ".."
%code <-write ".."
\("if" if %is_first else "elseif") \%condition_code then
\%action_statements
@ -290,7 +290,7 @@ immediately:
assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block"
if: %code is not ""
%code +<- "\nend"
%code <-write "\nend"
lua> "utils.deduplicate(\%locals);"
return {statements:%code, locals:%locals}
@ -322,7 +322,7 @@ immediately:
if: =lua "\%condition.type == 'Word' and \%condition.value == 'else'"
assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block"
%code +<- ".."
%code <-write ".."
else
\%action_statements
@ -337,7 +337,7 @@ immediately:
..else
(%i'th in %fallthroughs) <- "utils.equivalent(branch_value, \%)"
%clause <- (%fallthroughs joined with " or ")
%code +<- ".."
%code <-write ".."
\("if" if %is_first else "elseif") \%clause then
\%action_statements
@ -348,7 +348,7 @@ immediately:
assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block"
assume (%code is not "") or barf "No body for 'when % = ?' block!"
unless %seen_else
%code +<- "\nend"
%code <-write "\nend"
%code <- ".."
do --when % = ?
local branch_value = \(%branch_value as lua expr);\

View File

@ -26,7 +26,7 @@ immediately:
local body_lua = \%lua:as_lua(nomsu);
body_lua:convert_to_statements("return ");
body_lua:declare_locals(args);
lua:append(")\\n ", body_lua, "\\nend);")
lua:append(")\\n ", body_lua, "\\nend);");
return lua;
end);
@ -75,7 +75,7 @@ immediately:
local template;
if \%longhand.type == "Block" then
local lines = {};
for i, line in ipairs(\%longhand.value) do lines[i] = line.source:get_text(); end
for i, line in ipairs(\%longhand.value) do lines[i] = tostring(line.source:get_text()); end
template = repr(table.concat(lines, "\\n"));
else
template = repr(tostring(\%longhand.source:get_text()));
@ -117,7 +117,7 @@ immediately:
lua> ".."
local lua = \%tree:as_lua(nomsu);
lua:convert_to_statements();
lua:declare_locals();
--lua:declare_locals();
return lua;
action [%tree as value]:
@ -127,7 +127,7 @@ immediately:
=lua "nomsu:tree_to_stub(\%tree)"
immediately:
parse [%var write code %code] as: lua> "\%var:append(\%code);"
parse [%var <-write %code] as: lua> "\%var:append(\%code);"
immediately:
compile [%tree's source code, %tree' source code] to: Lua value "\(%tree as lua expr).source:get_text()"

View File

@ -52,11 +52,12 @@ immediately:
lua> "local \%value_lua = nomsu:tree_to_lua(\%value);"
assume %value_lua.is_value or barf "Invalid value for assignment: \(%value's source code)"
lua> ".."
local \%lua = Lua(tree.source, \%var_lua, ' = ', \%value_lua, ';');
local lua = Lua(tree.source, \%var_lua, ' = ', \%value_lua, ';');
if \%var.type == 'Var' then
\%lua:add_free_vars(nomsu:var_to_lua_identifier(\%var.value));
print("Added var from assignment: "..tostring(\%var:as_lua(nomsu)));
lua:add_free_vars(\%var);
end
return \%lua;
return lua;
immediately:
# Simultaneous mutli-assignments like: x,y,z = 1,x,3;
@ -72,7 +73,7 @@ immediately:
local value_lua = nomsu:tree_to_lua(value);
if not value_lua.is_value then error("Invalid value for assignment: "..value:get_src()); end
if target.type == "Var" then
lhs:add_free_vars(nomsu:var_to_lua_identifier(target.value));
lhs:add_free_vars(target);
end
if i > 1 then
lhs:append(", ");

View File

@ -126,7 +126,7 @@ do
sub = function(self, start, stop)
local str = tostring(self):sub(start, stop)
local cls = self.__class
return cls(self.source:sub(start - self.source.start + 1, stop - self.source.stop + 1), str)
return cls(self.source:sub(start - self.source.start + 1, stop - self.source.start + 1), str)
end,
append = function(self, ...)
local n = select("#", ...)
@ -195,6 +195,11 @@ do
end
for i = 1, select("#", ...) do
local var = select(i, ...)
if type(var) == 'userdata' and var.type == "Var" then
var = tostring(var:as_lua())
elseif type(var) ~= 'string' then
var = tostring(var)
end
if not (seen[var]) then
self.free_vars[#self.free_vars + 1] = var
seen[var] = true
@ -235,21 +240,40 @@ do
skip = _tbl_0
end
end
if #self.free_vars > 0 then
self:prepend("local " .. tostring(concat(self.free_vars, ", ")) .. ";\n")
end
local to_declare = { }
local walk
walk = function(self)
local _list_0 = self.free_vars
for _index_0 = 1, #_list_0 do
local var = _list_0[_index_0]
if not (skip[var]) then
skip[var] = true
to_declare[#to_declare + 1] = var
end
end
local _list_1 = self.bits
for _index_0 = 1, #_list_1 do
local bit = _list_1[_index_0]
if type(bit) == Lua then
bit:declare_locals(skip)
if bit.__class == Lua then
walk(bit)
end
end
if #self.free_vars > 0 then
self.free_vars = { }
end
end
walk(self)
if #to_declare > 0 then
self:prepend("local " .. tostring(concat(to_declare, ", ")) .. ";\n")
end
return [[ if #@free_vars > 0
@prepend "local #{concat @free_vars, ", "};\n"
for var in *@free_vars do skip[var] = true
@free_vars = {}
for bit in *@bits
if bit.__class == Lua
bit\declare_locals(skip)
]]
end,
__tostring = function(self)
local buff = { }
@ -303,25 +327,23 @@ do
lua_to_nomsu = { },
nomsu_to_lua = { }
}
local lua_offset = 1
local walk
walk = function(lua)
if type(lua) == 'string' then
lua_offset = lua_offset + #lua
else
local lua_start = lua_offset
walk = function(lua, output_range)
local pos = 1
local _list_0 = lua.bits
for _index_0 = 1, #_list_0 do
local b = _list_0[_index_0]
walk(b)
if type(b) == 'string' then
local output = output_range:sub(pos, pos + #b)
metadata.lua_to_nomsu[output] = lua.source
metadata.nomsu_to_lua[lua.source] = output
else
walk(b, output_range:sub(pos, pos + #b))
end
local lua_stop = lua_offset
local nomsu_src, lua_src = lua.source, Source(lua_chunkname, lua_start, lua_stop)
metadata.lua_to_nomsu[lua_src] = nomsu_src
metadata.nomsu_to_lua[nomsu_src] = lua_src
pos = pos + #b
end
end
walk(self)
walk(self, Source(lua_chunkname, 1, #lua_str))
return lua_str, metadata
end,
parenthesize = function(self)

View File

@ -94,7 +94,7 @@ class Code
sub: (start,stop)=>
str = tostring(self)\sub(start,stop)
cls = @__class
return cls(@source\sub(start-@source.start+1,stop-@source.stop+1), str)
return cls(@source\sub(start-@source.start+1,stop-@source.start+1), str)
append: (...)=>
n = select("#",...)
@ -125,6 +125,10 @@ class Lua extends Code
seen = {[v]:true for v in *@free_vars}
for i=1,select("#",...)
var = select(i, ...)
if type(var) == 'userdata' and var.type == "Var"
var = tostring(var\as_lua!)
elseif type(var) != 'string'
var = tostring(var)
unless seen[var]
@free_vars[#@free_vars+1] = var
seen[var] = true
@ -140,12 +144,29 @@ class Lua extends Code
declare_locals: (skip={})=>
if next(skip) == 1
skip = {[s]:true for s in *skip}
to_declare = {}
walk = =>
for var in *@free_vars
unless skip[var]
skip[var] = true
to_declare[#to_declare+1] = var
for bit in *@bits
if bit.__class == Lua
walk bit
if #@free_vars > 0
@free_vars = {}
walk self
if #to_declare > 0
@prepend "local #{concat to_declare, ", "};\n"
[[
if #@free_vars > 0
@prepend "local #{concat @free_vars, ", "};\n"
for var in *@free_vars do skip[var] = true
@free_vars = {}
for bit in *@bits
if type(bit) == Lua
if bit.__class == Lua
bit\declare_locals(skip)
]]
__tostring: =>
buff = {}
@ -191,19 +212,18 @@ class Lua extends Code
lua_filename:lua_chunkname, lua_file:lua_str
lua_to_nomsu: {}, nomsu_to_lua: {}
}
lua_offset = 1
walk = (lua)->
if type(lua) == 'string'
lua_offset += #lua
else
lua_start = lua_offset
walk = (lua, output_range)->
pos = 1
for b in *lua.bits
walk b
lua_stop = lua_offset
nomsu_src, lua_src = lua.source, Source(lua_chunkname, lua_start, lua_stop)
metadata.lua_to_nomsu[lua_src] = nomsu_src
metadata.nomsu_to_lua[nomsu_src] = lua_src
walk self
if type(b) == 'string'
output = output_range\sub(pos, pos+#b)
metadata.lua_to_nomsu[output] = lua.source
metadata.nomsu_to_lua[lua.source] = output
else
walk b, output_range\sub(pos, pos+#b)
pos += #b
walk self, Source(lua_chunkname, 1, #lua_str)
return lua_str, metadata
parenthesize: =>

View File

@ -372,7 +372,7 @@ do
end
if filename:match(".*%.lua") then
local file = assert(FILE_CACHE[filename], "Could not find file: " .. tostring(filename))
return self:run_lua(file, filename)
return self:run_lua(file)
end
if filename:match(".*%.nom") then
if not self.skip_precompiled then
@ -443,7 +443,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.filename)
return self:run_lua(lua)
end,
tree_to_nomsu = function(self, tree, indentation, max_line, expr_type)
if indentation == nil then
@ -940,7 +940,7 @@ do
tree_with_replaced_vars = function(self, tree, replacements)
return self:tree_map(tree, function(t)
if t.type == "Var" then
local id = self:var_to_lua_identifier(t.value)
local id = tostring(t:as_lua(self))
if replacements[id] ~= nil then
return replacements[id]
end
@ -1088,7 +1088,7 @@ do
end)
self:define_compile_action("lua> %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return Lua.Value(self.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
return Lua.Value(self.source, "nomsu:run_lua(Lua(", repr(_code.source), ", ", repr(tostring(nomsu:tree_to_lua(_code))), "))")
end
local lua = Lua(_code.source)
local _list_0 = _code.value
@ -1109,7 +1109,7 @@ do
end)
self:define_compile_action("=lua %code", get_line_no(), function(self, _code)
if _code.type ~= "Text" then
return Lua.Value(self.source, "nomsu:run_lua(", nomsu:tree_to_lua(_code), ")")
return Lua.Value(self.source, "nomsu:run_lua(Lua(", repr(_code.source), ", ", repr(tostring(nomsu:tree_to_lua(_code))), "))")
end
local lua = Lua.Value(self.source)
local _list_0 = _code.value
@ -1303,7 +1303,7 @@ if arg and debug_getinfo(2).func ~= require then
return line_table
end
})
debug.getinfoXXXXXX = function(thread, f, what)
debug.getinfo = function(thread, f, what)
if what == nil then
f, what, thread = thread, f, nil
end
@ -1324,21 +1324,16 @@ if arg and debug_getinfo(2).func ~= require then
local metadata = nomsu.action_metadata[info.func]
if metadata then
info.name = metadata.aliases[1]
local filename
if type(metadata.source) == 'string' then
filename = metadata.source:match("^[^[:]*")
else
filename = metadata.source.filename
end
local _ = [=[ filename = if type(metadata.source) == 'string'
metadata.source\match("^[^[:]*")
else metadata.source.filename
info.short_src = filename
info.source = FILE_CACHE[filename]
local linedefined
ok, linedefined = pcall(lua_line_to_nomsu_line, info.short_src, info.linedefined)
if ok then
info.linedefined = linedefined
end
local currentline
if ok then info.linedefined = linedefined
ok, currentline = pcall(lua_line_to_nomsu_line, info.short_src, info.currentline)
--if ok then info.currentline = currentline
]=]
end
end
end

View File

@ -333,7 +333,7 @@ class NomsuCompiler
if filename\match(".*%.lua")
file = assert(FILE_CACHE[filename], "Could not find file: #{filename}")
return @run_lua(file, filename)
return @run_lua(file)
if filename\match(".*%.nom")
if not @skip_precompiled -- Look for precompiled version
lua_filename = filename\gsub("%.nom$", ".lua")
@ -383,7 +383,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.filename)
return @run_lua(lua)
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
@ -734,7 +734,7 @@ class NomsuCompiler
tree_with_replaced_vars: (tree, replacements)=>
return @tree_map tree, (t)->
if t.type == "Var"
id = @var_to_lua_identifier t.value
id = tostring(t\as_lua(self))
if replacements[id] != nil
return replacements[id]
@ -836,7 +836,8 @@ class NomsuCompiler
@define_compile_action "lua> %code", get_line_no!, (_code)=>
if _code.type != "Text"
return Lua.Value(@source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
return Lua.Value @source, "nomsu:run_lua(Lua(",repr(_code.source),
", ",repr(tostring(nomsu\tree_to_lua(_code))),"))"
lua = Lua(_code.source)
for bit in *_code.value
@ -852,7 +853,8 @@ class NomsuCompiler
@define_compile_action "=lua %code", get_line_no!, (_code)=>
if _code.type != "Text"
return Lua.Value(@source, "nomsu:run_lua(",nomsu\tree_to_lua(_code),")")
return Lua.Value @source, "nomsu:run_lua(Lua(",repr(_code.source),
", ",repr(tostring(nomsu\tree_to_lua(_code))),"))"
lua = Lua.Value(@source)
for bit in *_code.value
@ -906,7 +908,7 @@ if arg and debug_getinfo(2).func != require
return line_table
}
debug.getinfoXXXXXX = (thread,f,what)->
debug.getinfo = (thread,f,what)->
if what == nil
f,what,thread = thread,f,nil
if type(f) == 'number' then f += 1 -- Account for this wrapper function
@ -917,6 +919,7 @@ if arg and debug_getinfo(2).func != require
if info.short_src or info.source or info.linedefine or info.currentline
if metadata = nomsu.action_metadata[info.func]
info.name = metadata.aliases[1]
[=[
filename = if type(metadata.source) == 'string'
metadata.source\match("^[^[:]*")
else metadata.source.filename
@ -926,6 +929,7 @@ if arg and debug_getinfo(2).func != require
if ok then info.linedefined = linedefined
ok, currentline = pcall(lua_line_to_nomsu_line, info.short_src, info.currentline)
--if ok then info.currentline = currentline
]=]
return info

View File

@ -35,7 +35,6 @@ Tree "File",
as_lua: (nomsu)=>
if #@value == 1
return @value[1]\as_lua(nomsu)
declared_locals = {}
lua = Lua(@source)
for i, line in ipairs @value
line_lua = line\as_lua(nomsu)