Added support for compile actions returning trees, and compiling blocks

into values.
This commit is contained in:
Bruce Hill 2018-09-17 15:29:48 -07:00
parent e3bf10196a
commit c1cba45968
4 changed files with 82 additions and 31 deletions

View File

@ -197,16 +197,14 @@ compile [parse %actions as %body] to (..)
end end
local \%new_body = LuaCode(\%body.source, local \%new_body = LuaCode(\%body.source,
"local mangle = mangler()", "local mangle = mangler()",
"\\nlocal tree = ", make_tree(\%body), "\\nreturn ", make_tree(\%body))
"\\nlocal lua = nomsu:compile(tree)",
"\\nreturn lua")
local ret = \(compile as (compile %actions to %new_body)) local ret = \(compile as (compile %actions to %new_body))
return ret" return ret"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TODO: add check for .is_value # TODO: add check for .is_value
compile [%tree as lua expr] to (Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree)"))") compile [%tree as lua expr] to (Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree, nil, true)"), nil, true)")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -27,16 +27,9 @@ test:
# Variable assignment operator # Variable assignment operator
compile [%var = %value] to: compile [%var = %value] to:
lua> "local \%var_lua = \(%var as lua)" lua> "local \%var_lua = \(%var as lua expr)"
assume %var_lua.is_value or barf "Invalid target for assignment: \%var" assume %var_lua.is_value or barf "Invalid target for assignment: \%var"
lua> "\ lua> "local \%value_lua = \(%value as lua expr)"
..\%value = \%value:map(function(t)
if Action:is_instance(t) and t.stub == "?" then
return \%var
end
end)
local \%value_lua = \(%value as lua)"
assume %value_lua.is_value or barf "Invalid value for assignment: \%value" assume %value_lua.is_value or barf "Invalid value for assignment: \%value"
lua> "\ lua> "\
..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';') ..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')

View File

@ -667,7 +667,10 @@ do
end end
return run_lua_fn() return run_lua_fn()
end end
NomsuCompiler.compile = function(self, tree, compile_actions) NomsuCompiler.compile = function(self, tree, compile_actions, force_value)
if force_value == nil then
force_value = false
end
compile_actions = compile_actions or self.environment.COMPILE_ACTIONS compile_actions = compile_actions or self.environment.COMPILE_ACTIONS
if tree.version then if tree.version then
do do
@ -736,7 +739,7 @@ do
_continue_0 = true _continue_0 = true
break break
end end
local arg_lua = self:compile(tok, compile_actions) local arg_lua = self:compile(tok, compile_actions, true)
if not (arg_lua.is_value) then if not (arg_lua.is_value) then
if tok.type == "Block" then if tok.type == "Block" then
self:compile_error(tok, "Can't compile action (" .. tostring(stub) .. ") with a Block as an argument.", "Maybe there should be a compile-time action with that name that isn't being found?") self:compile_error(tok, "Can't compile action (" .. tostring(stub) .. ") with a Block as an argument.", "Maybe there should be a compile-time action with that name that isn't being found?")
@ -781,6 +784,7 @@ do
lua:append("}") lua:append("}")
return lua return lua
elseif "Block" == _exp_0 then elseif "Block" == _exp_0 then
if not force_value then
local lua = LuaCode(tree.source) local lua = LuaCode(tree.source)
lua:concat_append((function() lua:concat_append((function()
local _accum_0 = { } local _accum_0 = { }
@ -793,6 +797,43 @@ do
return _accum_0 return _accum_0
end)(), "\n") end)(), "\n")
return lua return lua
else
local lua = LuaCode.Value(tree.source)
local values
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #tree do
local line = tree[_index_0]
_accum_0[_len_0] = self:compile(line)
_len_0 = _len_0 + 1
end
values = _accum_0
end
local all_values = true
for _index_0 = 1, #values do
local v = values[_index_0]
all_values = all_values and v.is_value
end
if all_values then
if #values == 1 then
return values[1]
end
lua:append("(")
lua:concat_append(values, " and nil or ")
lua:append(")")
else
lua:append("((function()")
for i, v in ipairs(values) do
if v.is_value then
v = v:as_statements(i == #values and 'return ' or '')
end
lua:append("\n ", v)
end
lua:append("\nend)())")
end
return lua
end
elseif "Text" == _exp_0 then elseif "Text" == _exp_0 then
local lua = LuaCode.Value(tree.source) local lua = LuaCode.Value(tree.source)
local string_buffer = "" local string_buffer = ""

View File

@ -389,7 +389,7 @@ with NomsuCompiler
return run_lua_fn! return run_lua_fn!
.compile = (tree, compile_actions)=> .compile = (tree, compile_actions, force_value=false)=>
compile_actions or= @environment.COMPILE_ACTIONS compile_actions or= @environment.COMPILE_ACTIONS
if tree.version if tree.version
if get_version = @[("Nomsu version")\as_lua_id!] if get_version = @[("Nomsu version")\as_lua_id!]
@ -430,7 +430,7 @@ with NomsuCompiler
args = {} args = {}
for i, tok in ipairs tree for i, tok in ipairs tree
if type(tok) == "string" then continue if type(tok) == "string" then continue
arg_lua = @compile(tok, compile_actions) arg_lua = @compile(tok, compile_actions, true)
unless arg_lua.is_value unless arg_lua.is_value
if tok.type == "Block" if tok.type == "Block"
@compile_error tok, @compile_error tok,
@ -469,9 +469,28 @@ with NomsuCompiler
return lua return lua
when "Block" when "Block"
if not force_value
lua = LuaCode(tree.source) lua = LuaCode(tree.source)
lua\concat_append([@compile(line, compile_actions)\as_statements! for line in *tree], "\n") lua\concat_append([@compile(line, compile_actions)\as_statements! for line in *tree], "\n")
return lua return lua
else
lua = LuaCode.Value(tree.source)
values = [@compile(line) for line in *tree]
all_values = true
for v in *values do all_values and= v.is_value
if all_values
return values[1] if #values == 1
lua\append "("
lua\concat_append(values, " and nil or ")
lua\append ")"
else
lua\append("((function()")
for i, v in ipairs(values)
if v.is_value
v = v\as_statements(i == #values and 'return ' or '')
lua\append "\n ", v
lua\append("\nend)())")
return lua
when "Text" when "Text"
lua = LuaCode.Value(tree.source) lua = LuaCode.Value(tree.source)