Got nomsu codegen working again.

This commit is contained in:
Bruce Hill 2018-04-25 16:04:46 -07:00
parent cb28f52b41
commit 50a092e4b5
8 changed files with 87 additions and 63 deletions

View File

@ -26,7 +26,7 @@ immediately:
compile [%a is %b, %a = %b, %a == %b] to:
lua> ".."
local safe = {Text=true, Number=true};
local a_lua, b_lua = nomsu:tree_to_lua(\%a), nomsu:tree_to_lua(\%b);
local a_lua, b_lua = \%a:as_lua(nomsu), \%b:as_lua(nomsu);
if safe[\%a.type] or safe[\%b.type] then
return Lua.Value(tree.source, "(", a_lua, " == ", b_lua, ")");
else
@ -35,7 +35,7 @@ immediately:
compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to:
lua> ".."
local safe = {Text=true, Number=true};
local a_lua, b_lua = nomsu:tree_to_lua(\%a), nomsu:tree_to_lua(\%b);
local a_lua, b_lua = \%a:as_lua(nomsu), \%b:as_lua(nomsu);
if safe[\%a.type] or safe[\%b.type] then
return Lua.Value(tree.source, "(", a_lua, " ~= ", b_lua, ")");
else
@ -47,9 +47,9 @@ immediately:
# Variable assignment operator
immediately:
compile [%var <- %value] to:
lua> "local \%var_lua = nomsu:tree_to_lua(\%var);"
lua> "local \%var_lua = \%var:as_lua(nomsu);"
assume %var_lua.is_value or barf "Invalid target for assignment: \(%var's source code)"
lua> "local \%value_lua = nomsu:tree_to_lua(\%value);"
lua> "local \%value_lua = \%value:as_lua(nomsu);"
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, ';');
@ -67,9 +67,9 @@ immediately:
local lhs, rhs = Lua(tree.source), Lua(\%assignments.source);
for i, item in ipairs(\%assignments.value) do
local target, value = item.key, item.value;
local target_lua = nomsu:tree_to_lua(target);
local target_lua = target:as_lua(nomsu);
if not target_lua.is_value then error("Invalid target for assignment: "..target:get_src()); end
local value_lua = nomsu:tree_to_lua(value);
local value_lua = value:as_lua(nomsu);
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(target);
@ -106,8 +106,8 @@ immediately:
if not target.type == "Var" then
error("Invalid target for 'with' assignment: "..tostring(target.source:get_text()));
end
local target_lua = nomsu:tree_to_lua(target);
local value_lua = nomsu:tree_to_lua(value);
local target_lua = target:as_lua(nomsu);
local value_lua = value:as_lua(nomsu);
if not value_lua.is_value then
error("Invalid value for assignment: "..tostring(value.source:get_text()));
end

View File

@ -49,7 +49,7 @@ lua> ".."
local reset = "'"..colors["reset color"].."'";
nomsu:define_compile_action(name, \(!! code location !!), function(tree) return Lua.Value(tree.source, color); end);
nomsu:define_compile_action(name.." %", \(!! code location !!), function(\%)
return Lua.Value(tree.source, color, "..", nomsu:tree_to_lua(\%), "..", reset);
return Lua.Value(tree.source, color, "..", \%:as_lua(nomsu), "..", reset);
end);
end
end

View File

@ -104,6 +104,7 @@ do
local bits = self.bits
for i = 1, n do
local b = select(i, ...)
assert(b ~= self, "No recursion please.")
bits[#bits + 1] = b
if type(b) == 'string' then
do
@ -129,6 +130,7 @@ do
end
self.current_indent = 0
for i, b in ipairs(bits) do
assert(b ~= self, "No recursion please.")
if type(b) == 'string' then
do
local spaces = b:match("\n([ ]*)[^\n]*$")

View File

@ -95,6 +95,7 @@ class Code
bits = @bits
for i=1,n
b = select(i, ...)
assert(b != self, "No recursion please.")
bits[#bits+1] = b
if type(b) == 'string'
if spaces = b\match("\n([ ]*)[^\n]*$")
@ -112,6 +113,7 @@ class Code
bits[i] = select(i, ...)
@current_indent = 0
for i,b in ipairs(bits)
assert(b != self, "No recursion please.")
if type(b) == 'string'
if spaces = b\match("\n([ ]*)[^\n]*$")
@current_indent = #spaces
@ -245,4 +247,8 @@ class Nomsu extends Code
__len: =>
#tostring(self)
parenthesize: =>
@prepend "("
@append ")"
return {:Code, :Nomsu, :Lua, :Source}

View File

@ -1133,6 +1133,6 @@ if arg and debug_getinfo(2).func ~= require then
end
return os.exit(false, true)
end
xpcall(run, err_hand)
require('ldt').guard(run)
end
return NomsuCompiler

View File

@ -317,7 +317,7 @@ class NomsuCompiler
tree = @parse(nomsu_code)
assert tree, "Failed to parse: #{nomsu_code}"
assert tree.type == "File", "Attempt to run non-file: #{tree.type}"
lua = @tree_to_lua(tree)
lua = tree\as_lua(@)
lua\convert_to_statements!
lua\declare_locals!
lua\prepend "-- File: #{nomsu_code.source or ""}\n"
@ -387,12 +387,9 @@ class NomsuCompiler
-- Special case for text literals
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),";")
lua = Lua(tree.source, "return ",tree\as_lua(@),";")
return @run_lua(lua)
tree_to_nomsu: (tree)=>
return tree\as_nomsu!
value_to_nomsu: (value)=>
switch type(value)
when "nil"
@ -418,9 +415,6 @@ class NomsuCompiler
else
error("Unsupported value_to_nomsu type: #{type(value)}", 0)
tree_to_lua: (tree)=>
return tree\as_lua(self)
walk_tree: (tree, depth=0)=>
coroutine.yield(tree, depth)
return unless Types.is_node(tree)
@ -567,7 +561,7 @@ class NomsuCompiler
get_line_no = -> "nomsu.moon:#{debug_getinfo(2).currentline}"
nomsu = self
@define_compile_action "immediately %block", get_line_no!, (_block)=>
lua = nomsu\tree_to_lua(_block)
lua = _block\as_lua(nomsu)
lua\convert_to_statements!
lua\declare_locals!
nomsu\run_lua(lua)
@ -582,7 +576,7 @@ class NomsuCompiler
if type(bit) == "string"
lua\append repr(bit)
else
bit_lua = nomsu\tree_to_lua bit
bit_lua = bit\as_lua(nomsu)
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."
@ -615,14 +609,14 @@ class NomsuCompiler
@define_compile_action "lua> %code", get_line_no!, (_code)=>
if _code.type != "Text"
return Lua.Value @source, "nomsu:run_lua(Lua(",repr(_code.source),
", ",repr(tostring(nomsu\tree_to_lua(_code))),"))"
", ",repr(tostring(_code\as_lua(nomsu))),"))"
lua = Lua(_code.source)
for bit in *_code.value
if type(bit) == "string"
lua\append bit
else
bit_lua = nomsu\tree_to_lua bit
bit_lua = bit\as_lua(nomsu)
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
@ -632,14 +626,14 @@ class NomsuCompiler
@define_compile_action "=lua %code", get_line_no!, (_code)=>
if _code.type != "Text"
return Lua.Value @source, "nomsu:run_lua(Lua(",repr(_code.source),
", ",repr(tostring(nomsu\tree_to_lua(_code))),"))"
", ",repr(tostring(_code\as_lua(nomsu))),"))"
lua = Lua.Value(@source)
for bit in *_code.value
if type(bit) == "string"
lua\append bit
else
bit_lua = nomsu\tree_to_lua bit
bit_lua = bit\as_lua(nomsu)
unless 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
@ -819,8 +813,8 @@ if arg and debug_getinfo(2).func != require
--ProFi = require 'ProFi'
--ProFi\start()
--require('ldt').guard run
xpcall(run, err_hand)
require('ldt').guard run
--xpcall(run, err_hand)
--ProFi\stop()
--ProFi\writeReport( 'MyProfilingReport.txt' )

View File

@ -35,7 +35,7 @@ Tree = function(name, methods)
end
methods.type = name
methods.name = name
methods.as_nomsuXXXX = function(self)
methods.original_nomsu = function(self)
local leading_space = 0
local src_file = FILE_CACHE[self.source.filename]
while src_file:sub(self.source.start - leading_space - 1, self.source.start - leading_space - 1) == " " do
@ -82,7 +82,8 @@ Tree("File", {
end
local nomsu = Nomsu(self.source)
for i, line in ipairs(self.value) do
nomsu:append(assert(line:as_nomsu(), "Could not convert line to nomsu: " .. tostring(line)))
line = assert(line:as_nomsu(), "Could not convert line to nomsu")
nomsu:append(line)
if i < #self.value then
nomsu:append("\n")
end
@ -126,16 +127,16 @@ Tree("Block", {
if inline == nil then
inline = false
end
if inline then
if #self.value == 1 then
return self.value[1]:as_nomsu(true)
else
return nil
return self.value[1]:as_nomsu(inline)
end
if inline then
return nil
end
local nomsu = Nomsu(self.source)
for i, line in ipairs(self.value) do
nomsu:append(assert(line:as_nomsu(), "Could not convert line to nomsu: " .. tostring(line)))
line = assert(line:as_nomsu(), "Could not convert line to nomsu")
nomsu:append(line)
if i < #self.value then
nomsu:append("\n")
end
@ -297,7 +298,7 @@ Tree("Action", {
if not (i == 1) then
nomsu:append(" ")
end
if bit.type == "Action" then
if bit.type == "Action" or bit.type == "Block" then
arg_nomsu:parenthesize()
end
nomsu:append(arg_nomsu)
@ -321,7 +322,7 @@ Tree("Action", {
else
local arg_nomsu = bit:as_nomsu(true)
if arg_nomsu and #arg_nomsu < 80 then
if bit.type == "Action" then
if bit.type == "Action" or bit.type == "Block" then
arg_nomsu:parenthesize()
end
spacer = " "
@ -330,8 +331,8 @@ Tree("Action", {
if not (nomsu) then
return nil
end
if bit.type == "Action" then
nomsu:append("\n ", nomsu)
if bit.type == "Action" or bit.type == "Block" then
nomsu:append("\n ")
end
spacer = "\n.."
end
@ -419,22 +420,25 @@ Tree("Text", {
end
end
nomsu:append('"')
if #nomsu > 80 then
return nil
end
return nomsu
else
local inline_version = self:as_nomsu(true)
if inline_version and #inline_version <= 80 then
return inline_version
end
local nomsu = Nomsu(self.source, '".."\n ')
for i, bit in ipairs(self.value) do
if type(bit) == 'string' then
nomsu:append((bit:gsub("\\", "\\\\"):gsub("\n", "\n ")))
else
local interp_nomsu = bit:as_nomsu(true)
if interp_nomsu then
if bit.type ~= "Word" and bit.type ~= "List" and bit.type ~= "Dict" and bit.type ~= "Text" then
interp_nomsu:parenthesize()
end
nomsu:append("\\", interp_nomsu)
else
local interp_nomsu = bit:as_nomsu()
interp_nomsu = bit:as_nomsu()
if not (interp_nomsu) then
return nil
end
@ -499,6 +503,10 @@ Tree("List", {
nomsu:append("]")
return nomsu
else
local inline_version = self:as_nomsu(true)
if inline_version and #inline_version <= 80 then
return inline_version
end
local nomsu = Nomsu(self.source, "[..]")
local line = Nomsu(self.source, "\n ")
local _list_0 = self.value
@ -519,7 +527,7 @@ Tree("List", {
end
if #line.bits > 1 then
nomsu:append(line)
line = Nomsu(bit.source, "\n ")
line = Nomsu(item.source, "\n ")
end
line:append(item_nomsu)
end
@ -584,7 +592,7 @@ Tree("Dict", {
if not (key_nomsu) then
return nil
end
if entry.key.type == "Action" then
if entry.key.type == "Action" or entry.key.type == "Block" then
key_nomsu:parenthesize()
end
local value_nomsu = entry.value:as_nomsu(true)
@ -599,6 +607,10 @@ Tree("Dict", {
nomsu:append("}")
return nomsu
else
local inline_version = self:as_nomsu(true)
if inline_version then
return inline_version
end
local nomsu = Nomsu(self.source, "{..}")
local line = Nomsu(self.source, "\n ")
local _list_0 = self.value
@ -608,7 +620,7 @@ Tree("Dict", {
if not (key_nomsu) then
return nil
end
if entry.key.type == "Action" then
if entry.key.type == "Action" or entry.key.type == "Block" then
key_nomsu:parenthesize()
end
local value_nomsu = entry.value:as_nomsu(true)

View File

@ -6,7 +6,7 @@ lpeg = require 'lpeg'
{:repr, :stringify, :min, :max, :equivalent, :set, :is_list, :sum} = utils
immutable = require 'immutable'
{:insert, :remove, :concat} = table
{:Lua, :Location} = require "lua_obj"
{:Lua, :Nomsu, :Location} = require "lua_obj"
Types = {}
@ -21,7 +21,7 @@ Tree = (name, methods)->
.with_value = (value)=> getmetatable(self)(value, @source)
.type = name
.name = name
.as_nomsu = =>
.original_nomsu = =>
leading_space = 0
src_file = FILE_CACHE[@source.filename]
while src_file\sub(@source.start-leading_space-1, @source.start-leading_space-1) == " "
@ -54,7 +54,8 @@ Tree "File",
return nil if inline
nomsu = Nomsu(@source)
for i, line in ipairs @value
nomsu\append assert(line\as_nomsu!, "Could not convert line to nomsu: #{line}")
line = assert(line\as_nomsu!, "Could not convert line to nomsu")
nomsu\append line
if i < #@value
nomsu\append "\n"
return nomsu
@ -84,13 +85,13 @@ Tree "Block",
return lua
as_nomsu: (inline=false)=>
if inline
if #@value == 1
return @value[1]\as_nomsu(true)
else return nil
return @value[1]\as_nomsu(inline)
return nil if inline
nomsu = Nomsu(@source)
for i, line in ipairs @value
nomsu\append assert(line\as_nomsu!, "Could not convert line to nomsu: #{line}")
line = assert(line\as_nomsu!, "Could not convert line to nomsu")
nomsu\append line
if i < #@value
nomsu\append "\n"
return nomsu
@ -170,7 +171,7 @@ Tree "Action",
return nil unless arg_nomsu
unless i == 1
nomsu\append " "
if bit.type == "Action"
if bit.type == "Action" or bit.type == "Block"
arg_nomsu\parenthesize!
nomsu\append arg_nomsu
return nomsu
@ -190,14 +191,14 @@ Tree "Action",
else
arg_nomsu = bit\as_nomsu(true)
if arg_nomsu and #arg_nomsu < 80
if bit.type == "Action"
if bit.type == "Action" or bit.type == "Block"
arg_nomsu\parenthesize!
spacer = " "
else
arg_nomsu = bit\as_nomsu!
return nil unless nomsu
if bit.type == "Action"
nomsu\append "\n ", nomsu
if bit.type == "Action" or bit.type == "Block"
nomsu\append "\n "
spacer = "\n.."
nomsu\append arg_nomsu
return nomsu
@ -249,13 +250,17 @@ Tree "Text",
nomsu\append "\\", interp_nomsu
else return nil
nomsu\append '"'
if #nomsu > 80 then return nil
return nomsu
else
inline_version = @as_nomsu(true)
if inline_version and #inline_version <= 80
return inline_version
nomsu = Nomsu(@source, '".."\n ')
for i, bit in ipairs @value
if type(bit) == 'string'
nomsu\append (bit\gsub("\\","\\\\")\gsub("\n","\n "))
else
interp_nomsu = bit\as_nomsu(true)
if interp_nomsu
if bit.type != "Word" and bit.type != "List" and bit.type != "Dict" and bit.type != "Text"
interp_nomsu\parenthesize!
@ -265,7 +270,7 @@ Tree "Text",
return nil unless interp_nomsu
nomsu\append "\\\n ", interp_nomsu
if i < #@value
nomsu\append "\n.."
nomsu\append "\n .."
return nomsu
Tree "List",
@ -306,6 +311,9 @@ Tree "List",
nomsu\append "]"
return nomsu
else
inline_version = @as_nomsu(true)
if inline_version and #inline_version <= 80
return inline_version
nomsu = Nomsu(@source, "[..]")
line = Nomsu(@source, "\n ")
for item in *@value
@ -320,7 +328,7 @@ Tree "List",
return nil unless item_nomsu
if #line.bits > 1
nomsu\append line
line = Nomsu(bit.source, "\n ")
line = Nomsu(item.source, "\n ")
line\append item_nomsu
if #line.bits > 1
nomsu\append line
@ -372,7 +380,7 @@ Tree "Dict",
for i, entry in ipairs @value
key_nomsu = entry.key\as_nomsu(true)
return nil unless key_nomsu
if entry.key.type == "Action"
if entry.key.type == "Action" or entry.key.type == "Block"
key_nomsu\parenthesize!
value_nomsu = entry.value\as_nomsu(true)
return nil unless value_nomsu
@ -382,12 +390,14 @@ Tree "Dict",
nomsu\append "}"
return nomsu
else
inline_version = @as_nomsu(true)
if inline_version then return inline_version
nomsu = Nomsu(@source, "{..}")
line = Nomsu(@source, "\n ")
for entry in *@value
key_nomsu = entry.key\as_nomsu(true)
return nil unless key_nomsu
if entry.key.type == "Action"
if entry.key.type == "Action" or entry.key.type == "Block"
key_nomsu\parenthesize!
value_nomsu = entry.value\as_nomsu(true)
if value_nomsu and #line + #", " + #key_nomsu + #":" + #value_nomsu <= 80