aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-06-18 18:10:59 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-06-18 18:11:09 -0700
commitf83cc3ad8afaa122867270a9b1255295e902c422 (patch)
tree6d91f47c05f7173e3e447ae4f1412442edd6f6b2 /core
parenta22de3fdbbebb310a07252bd99b1ca8acb685ea6 (diff)
More streamlining and cleanup.
Diffstat (limited to 'core')
-rw-r--r--core/collections.nom3
-rw-r--r--core/control_flow.nom10
-rw-r--r--core/metaprogramming.nom182
-rw-r--r--core/operators.nom13
4 files changed, 100 insertions, 108 deletions
diff --git a/core/collections.nom b/core/collections.nom
index 69a51c7..6ba806a 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -55,6 +55,8 @@ compile [pop from %list, remove last from %list] to
compile [remove index %index from %list] to
Lua "table.remove(\(%list as lua expr), \(%index as lua expr))"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
# List Comprehension
parse [%expression for %item in %iterable] as
result of
@@ -73,6 +75,7 @@ parse [..]
add %expression to %comprehension
return %comprehension
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
parse [%expression for %var in %start to %stop] as
%expression for %var in %start to %stop via 1
diff --git a/core/control_flow.nom b/core/control_flow.nom
index fccdfca..5a96d3e 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -152,7 +152,7 @@ compile [..]
%body has subtree % where
(%.type = "Action") and
(%.stub is "do next %") and
- %.3 = %var
+ %.(3).1 = %var.1
..: to %lua write "\n ::continue_\(%var as lua identifier)::"
to %lua write "\nend --numeric for-loop"
@@ -160,7 +160,7 @@ compile [..]
%body has subtree % where
(%.type = "Action") and
(%.stub is "stop %") and
- %.2 = %var
+ %.(2).1 = %var.1
..
%lua <-
Lua ".."
@@ -246,7 +246,7 @@ compile [..]
%.2.(1) = %value.(1)
..: to %stop_labels write "\n::stop_\(%value as lua identifier)::"
- if: (length of %stop_labels) > 0
+ if: (length of "\%stop_labels") > 0
%lua <-
Lua ".."
do -- scope for stopping for % = % loop
@@ -300,7 +300,7 @@ compile [when %body] to
%is_first <- (no)
assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block"
- assume ((length of %code) > 0) or barf "Empty body for 'when' block"
+ assume ((length of "\%code") > 0) or barf "Empty body for 'when' block"
to %code write "\nend --when"
return %code
@@ -346,7 +346,7 @@ compile [when %branch_value = ? %body, when %branch_value is ? %body] to
%is_first <- (no)
assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block"
- assume ((length of %code) > 0) or barf "No body for 'when % = ?' block!"
+ assume ((length of "\%code") > 0) or barf "No body for 'when % = ?' block!"
to %code write "\nend"
%code <-
Lua ".."
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index d04ced3..a7da3d8 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -2,46 +2,92 @@
This File contains actions for making actions and compile-time actions and some helper
functions to make that easier.
-# Compile-time action to make compile-time actions:
lua> ".."
- nomsu.COMPILE_ACTIONS["give % nickname %"] = (function(nomsu, tree, \%action, \%nickname, is_compile_time)
- local function arg_to_string(a) return tostring(nomsu:compile(a)) end
- local action_args = table.map(\%action:get_args(), arg_to_string)
- local nickname_args = table.map(\%nickname:get_args(), arg_to_string)
- if utils.equivalent(action_args, nickname_args) then
- if is_compile_time then
- return LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%nickname.stub), "] = nomsu.COMPILE_ACTIONS[", repr(\%action.stub), "]")
+ nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
+ local lua = LuaCode(tree.source, "function(")
+ if AST.is_syntax_tree(\%args, "Action") then \%args = \%args:get_args() end
+ local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(nomsu:compile(a)) or a end)
+ lua:concat_append(lua_args, ", ")
+ local body_lua = AST.is_syntax_tree(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
+ body_lua:remove_free_vars(lua_args)
+ body_lua:declare_locals()
+ lua:append(")\n ", body_lua, "\nend")
+ return lua
+ end
+
+lua> ".."
+ nomsu.COMPILE_ACTIONS["compile as %"] = function(nomsu, tree, \%action)
+ local lua = LuaCode.Value(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%action.stub), "](")
+ local lua_args = table.map(\%action:get_args(), function(a) return nomsu:compile(a) end)
+ table.insert(lua_args, 1, "nomsu")
+ table.insert(lua_args, 2, "tree")
+ lua:concat_append(lua_args, ", ")
+ lua:append(")")
+ return lua
+ end
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+lua> ".."
+ nomsu.COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body)
+ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end))}
+ local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub),
+ "] = ", \(compile as: %args -> %body))
+ for i=2,#\%actions do
+ local alias = \%actions[i]
+ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end))}
+ lua:append("\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ")
+ if utils.equivalent(\%args, \%alias_args) then
+ lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
else
- return LuaCode(tree.source, "A", string.as_lua_id(\%nickname.stub), " = A", string.as_lua_id(\%action.stub))
+ lua:append("function(")
+ lua:concat_append(\%alias_args, ", ")
+ lua:append(")\n return nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
+ lua:concat_append(\%args, ", ")
+ lua:append(")\nend")
end
end
- local lua = LuaCode(tree.source)
- if is_compile_time then
- lua:append("nomsu.COMPILE_ACTIONS[", repr(\%nickname.stub), "] = ")
- table.insert(action_args, 1, "nomsu")
- table.insert(nickname_args, 1, "nomsu")
- table.insert(action_args, 2, "tree")
- table.insert(nickname_args, 2, "tree")
- else
- lua:append("A", string.as_lua_id(\%nickname.stub), " = ")
- end
- lua:append("(function(")
- lua:concat_append(nickname_args, ", ")
- if is_compile_time then
- lua:append(")\n return nomsu.COMPILE_ACTIONS[", repr(\%action.stub), "](")
- else
- lua:append(")\n return A", string.as_lua_id(\%action.stub), "(")
- end
- lua:concat_append(action_args, ", ")
- lua:append(")\nend)")
- if not is_compile_time then
- lua:add_free_vars({"A"..string.as_lua_id(\%nickname.stub)})
+ return lua
+ end
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+compile [local action %actions %body] to
+ lua> ".."
+ local fn_name = "A"..string.as_lua_id(\%actions[1].stub)
+ local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local lua = LuaCode(tree.source, fn_name, " = ", \(compile as: %args -> %body))
+ lua:add_free_vars({fn_name})
+ for i=2,#\%actions do
+ local alias = \%actions[i]
+ local alias_name = "A"..string.as_lua_id(alias.stub)
+ lua:add_free_vars({alias_name})
+ local \%alias_args = table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ lua:append("\n", alias_name, " = ")
+ if utils.equivalent(\%args, \%alias_args) then
+ lua:append(fn_name)
+ else
+ lua:append("function(")
+ lua:concat_append(\%alias_args, ", ")
+ lua:append(")\n return ", fn_name, "(")
+ lua:concat_append(\%args, ", ")
+ lua:append(")\nend")
+ end
end
return lua
- end)
- __MANGLE_INDEX = 0
- nomsu.COMPILE_ACTIONS["parse % as %"] = (function(nomsu, tree, \%actions, \%body)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+compile [action %actions %body] to
+ lua> ".."
+ local lua = \(compile as: local action %actions %body)
+ lua:remove_free_vars(table.map(\%actions, function(a) return "A"..string.as_lua_id(a.stub) end))
+ return lua
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+compile [parse %actions as %body] to
+ lua> ".."
local replacements = {}
for i,arg in ipairs(\%actions[1]:get_args()) do
replacements[arg[1]] = tostring(nomsu:compile(arg))
@@ -50,81 +96,25 @@ lua> ".."
if not AST.is_syntax_tree(t) then
return repr(t)
elseif t.type ~= 'Var' then
- local args = table.map(t, make_tree)
- table.insert(args, 1, repr(tostring(t.source)))
+ local args = {repr(tostring(t.source)), unpack(table.map(t, make_tree))}
return t.type.."("..table.concat(args, ", ")..")"
elseif replacements[t[1]] then
return replacements[t[1]]
else
- return t.type.."("..repr(tostring(t.source))..", "..repr(t[1].." \\0").."..('%X'):format(__MANGLE_INDEX))"
+ return t.type.."("..repr(tostring(t.source))..", "..repr(t[1].." \\0").."..string.format('%X', __MANGLE_INDEX))"
end
end
- local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "] = (function(nomsu, tree")
- lua:add_free_vars({"A"..string.as_lua_id(\%actions[1].stub)})
- for _,arg in ipairs(\%actions[1]:get_args()) do
- lua:append(", ", nomsu:compile(arg))
- end
- lua:append(")\n __MANGLE_INDEX = __MANGLE_INDEX + 1",
- "\n local tree = ", make_tree(\%body),
- "\n local lua = nomsu:compile(tree)",
- "\n lua:remove_free_vars({")
- local vars = table.map(\%actions[1]:get_args(), function(a)
- return "Var("..repr(tostring(a.source))..", "..repr(a[1])..")"
- end)
- lua:concat_append(vars, ", ")
- lua:append("})\n return lua\nend)")
-
- for i=2,#\%actions do
- lua:append("\n", nomsu.COMPILE_ACTIONS["give % nickname %"](nomsu, \%actions[i], \%actions[1], \%actions[i], true))
- end
- return lua
- end)
-
- nomsu.COMPILE_ACTIONS["local action % %"] = (function(nomsu, tree, \%actions, \%body, is_compile_time)
- local lua = LuaCode(tree.source)
- if is_compile_time then
- lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "] = ")
- else
- lua:append("A", string.as_lua_id(\%actions[1].stub), " = ")
- lua:add_free_vars({"A"..string.as_lua_id(\%actions[1].stub)})
- end
- lua:append("(function(")
- local args = \%actions[1]:get_args()
- local lua_args = table.map(args, function(a) return nomsu:compile(a) end)
- if is_compile_time then
- table.insert(lua_args, 1, "nomsu")
- table.insert(lua_args, 2, "tree")
- end
- lua:concat_append(lua_args, ", ")
- local body_lua = nomsu:compile(\%body):as_statements("return ")
- body_lua:remove_free_vars(args)
- body_lua:declare_locals()
- lua:append(")\n ", body_lua, "\nend)")
- for i=2,#\%actions do
- lua:append("\n", nomsu.COMPILE_ACTIONS["give % nickname %"](nomsu, \%actions[i], \%actions[1], \%actions[i], is_compile_time))
- end
- return lua
- end)
-
- -- Compile-time actions are always global, since they affect the state of the compiler
- nomsu.COMPILE_ACTIONS["compile % to %"] = (function(nomsu, tree, \%actions, \%body)
- local lua = nomsu.COMPILE_ACTIONS["local action % %"](nomsu, tree, \%actions, \%body, true)
- return lua
- end)
-
- nomsu.COMPILE_ACTIONS["action % %"] = (function(nomsu, tree, \%actions, \%body)
- local lua = nomsu.COMPILE_ACTIONS["local action % %"](nomsu, tree, \%actions, \%body)
- lua:remove_free_vars(table.map(\%actions, function(a) return "A"..a.stub:as_lua_id() end))
- return lua
- end)
+ local \%new_body = LuaCode(\%body.source,
+ "__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1",
+ "\nlocal tree = ", make_tree(\%body),
+ "\nreturn nomsu:compile(tree)")
+ return \(compile as: compile %actions to %new_body)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compile [remove action %action] to
Lua ".."
A\(=lua "string.as_lua_id(\(%action.stub))") = nil
- ARG_ORDERS[fn] = nil
- COMPILE_TIME[fn] = nil
action [%tree as nomsu]
=lua "nomsu:tree_to_nomsu(\%tree)"
diff --git a/core/operators.nom b/core/operators.nom
index b4567b1..0756751 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -50,7 +50,7 @@ compile [%var <- %value] to
lua> ".."
local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')
if \%var.type == 'Var' then
- lua:add_free_vars({\%var})
+ lua:add_free_vars({tostring(nomsu:compile(\%var))})
end
return lua
@@ -72,7 +72,7 @@ compile [<- %assignments, assign %assignments] to
local value_lua = \(%value as lua)
if not value_lua.is_value then error("Invalid value for assignment: "..\(%value as text)) end
if \%target.type == "Var" then
- lhs:add_free_vars({\%target})
+ lhs:add_free_vars({tostring(target_lua)})
end
if i > 1 then
lhs:append(", ")
@@ -94,7 +94,7 @@ compile [external %var <- %value] to
compile [with external %externs %body] to
%body_lua <- (%body as lua statements)
- lua> "\%body_lua:remove_free_vars(\%externs);"
+ lua> "\%body_lua:remove_free_vars(table.map(\%externs, function(v) return tostring(nomsu:compile(v)) end))"
return %body_lua
compile [with %assignments %body] to
@@ -112,16 +112,15 @@ compile [with %assignments %body] to
if not value_lua.is_value then
error("Invalid value for assignment: "..tostring(\%value))
end
- if \%target.type == "Var" then
- lhs:add_free_vars({\%target})
- end
if i > 1 then
lhs:append(", ")
rhs:append(", ")
end
lhs:append(target_lua)
rhs:append(value_lua)
- vars[i] = \%target
+ if \%target.type == "Var" then
+ vars[i] = tostring(target_lua)
+ end
end
\%lua:remove_free_vars(vars)
\%lua:prepend("local ", lhs, " = ", rhs, ";\n")