aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/metaprogramming.nom6
-rw-r--r--core/operators.nom11
-rw-r--r--nomsu_compiler.lua67
-rw-r--r--nomsu_compiler.moon29
4 files changed, 82 insertions, 31 deletions
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 5d31c2b..c50f783 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -197,16 +197,14 @@ compile [parse %actions as %body] to (..)
end
local \%new_body = LuaCode(\%body.source,
"local mangle = mangler()",
- "\\nlocal tree = ", make_tree(\%body),
- "\\nlocal lua = nomsu:compile(tree)",
- "\\nreturn lua")
+ "\\nreturn ", make_tree(\%body))
local ret = \(compile as (compile %actions to %new_body))
return ret"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 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)")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/core/operators.nom b/core/operators.nom
index 161bf83..3ae7c2f 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -27,16 +27,9 @@ test:
# Variable assignment operator
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"
- lua> "\
- ..\%value = \%value:map(function(t)
- if Action:is_instance(t) and t.stub == "?" then
- return \%var
- end
- end)
- local \%value_lua = \(%value as lua)"
-
+ lua> "local \%value_lua = \(%value as lua expr)"
assume %value_lua.is_value or barf "Invalid value for assignment: \%value"
lua> "\
..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index e2b0d89..2e286b7 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -667,7 +667,10 @@ do
end
return run_lua_fn()
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
if tree.version then
do
@@ -736,7 +739,7 @@ do
_continue_0 = true
break
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 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?")
@@ -781,18 +784,56 @@ do
lua:append("}")
return lua
elseif "Block" == _exp_0 then
- local lua = LuaCode(tree.source)
- lua:concat_append((function()
- 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, compile_actions):as_statements()
- _len_0 = _len_0 + 1
+ if not force_value then
+ local lua = LuaCode(tree.source)
+ lua:concat_append((function()
+ 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, compile_actions):as_statements()
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)(), "\n")
+ 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
- return _accum_0
- end)(), "\n")
- return lua
+ 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
local lua = LuaCode.Value(tree.source)
local string_buffer = ""
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index 2f79a34..19d4049 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -389,7 +389,7 @@ with NomsuCompiler
return run_lua_fn!
- .compile = (tree, compile_actions)=>
+ .compile = (tree, compile_actions, force_value=false)=>
compile_actions or= @environment.COMPILE_ACTIONS
if tree.version
if get_version = @[("Nomsu version")\as_lua_id!]
@@ -430,7 +430,7 @@ with NomsuCompiler
args = {}
for i, tok in ipairs tree
if type(tok) == "string" then continue
- arg_lua = @compile(tok, compile_actions)
+ arg_lua = @compile(tok, compile_actions, true)
unless arg_lua.is_value
if tok.type == "Block"
@compile_error tok,
@@ -469,9 +469,28 @@ with NomsuCompiler
return lua
when "Block"
- lua = LuaCode(tree.source)
- lua\concat_append([@compile(line, compile_actions)\as_statements! for line in *tree], "\n")
- return lua
+ if not force_value
+ lua = LuaCode(tree.source)
+ lua\concat_append([@compile(line, compile_actions)\as_statements! for line in *tree], "\n")
+ 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"
lua = LuaCode.Value(tree.source)