aboutsummaryrefslogtreecommitdiff
path: root/core/metaprogramming.nom
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-08-27 13:38:58 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-08-27 13:39:22 -0700
commit930d522fbc3ab57faa926ed85f0d35d661722402 (patch)
tree8c91c71728b43b4e1817ed182c39bf991cb4b2a9 /core/metaprogramming.nom
parentc6a7b0be9ebdddb58a03749705987cb3058060d3 (diff)
Bunch of miscellaneous changes. Paved the way a little bit for having
different compiler domains.
Diffstat (limited to 'core/metaprogramming.nom')
-rw-r--r--core/metaprogramming.nom116
1 files changed, 79 insertions, 37 deletions
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 153a0bf..968ed39 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -5,12 +5,12 @@
lua> "NOMSU_CORE_VERSION = 5"
lua> ".."
- nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
+ COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
local lua = LuaCode.Value(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)
+ local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(_ENV: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
+ local body_lua = AST.is_syntax_tree(\%body) and _ENV:compile(\%body):as_statements("return ") or \%body
body_lua:remove_free_vars(lua_args)
body_lua:declare_locals()
lua:append(")\\n ", body_lua, "\\nend)")
@@ -18,9 +18,9 @@ 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)
+ COMPILE_ACTIONS["compile as %"] = function(nomsu, tree, \%action)
+ local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", repr(\%action.stub), "](")
+ local lua_args = table.map(\%action:get_args(), function(a) return _ENV:compile(a) end)
table.insert(lua_args, 1, "nomsu")
table.insert(lua_args, 2, "tree")
lua:concat_append(lua_args, ", ")
@@ -48,22 +48,22 @@ test:
asdf
assume (%tmp is (nil)) or barf "compile to is leaking variables"
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(\
+ COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body)
+ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(_ENV:compile(\
..a)) end))}
- local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub),
+ local lua = LuaCode(tree.source, "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(\
+ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(_ENV:compile(\
..a)) end))}
- lua:append("\\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ")
+ lua:append("\\nCOMPILE_ACTIONS[", repr(alias.stub), "] = ")
if utils.equivalent(\%args, \%alias_args) then
- lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
+ lua:append("COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
else
lua:append("function(")
lua:concat_append(\%alias_args, ", ")
- lua:append(")\\n return nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
+ lua:append(")\\n return COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
lua:concat_append(\%args, ", ")
lua:append(")\\nend")
end
@@ -75,8 +75,8 @@ lua> ".."
compile [call %fn with %args] to (..)
lua> ".."
- local lua = LuaCode.Value(tree.source, nomsu:compile(\%fn), "(")
- lua:concat_append(table.map(\%args, function(a) return nomsu:compile(a) end), ", ")
+ local lua = LuaCode.Value(tree.source, _ENV:compile(\%fn), "(")
+ lua:concat_append(table.map(\%args, function(a) return _ENV:compile(a) end), ", ")
lua:append(")")
return lua
@@ -95,14 +95,14 @@ test:
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 \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(_ENV: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)
+ local \%alias_args = table.map(alias:get_args(), function(a) return tostring(_ENV:compile(a)) end)
lua:append("\\n", alias_name, " = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append(fn_name)
@@ -151,7 +151,7 @@ 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))
+ replacements[arg[1]] = tostring(_ENV:compile(arg))
end
local function make_tree(t)
if not AST.is_syntax_tree(t) then
@@ -168,7 +168,7 @@ compile [parse %actions as %body] to (..)
local \%new_body = LuaCode(\%body.source,
"__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1",
"\\nlocal tree = ", make_tree(\%body),
- "\\nlocal lua = nomsu:compile(tree); return lua")
+ "\\nlocal lua = _ENV:compile(tree); return lua")
local ret = \(compile as (compile %actions to %new_body))
return ret
@@ -176,33 +176,33 @@ compile [parse %actions as %body] to (..)
action [%tree as lua expr]:
lua> ".."
- \%tree_lua = nomsu:compile(\%tree)
+ \%tree_lua = _ENV:compile(\%tree)
if not \%tree_lua.is_value then
- nomsu:compile_error(\%tree.source, "Could not convert %s to a Lua expression",
- nomsu:tree_to_nomsu(\%tree))
+ _ENV:compile_error(\%tree.source, "Could not convert %s to a Lua expression",
+ _ENV:tree_to_nomsu(\%tree))
end
return \%tree_lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [%tree as lua] to (Lua value "nomsu:compile(\(%tree as lua expr))")
+compile [%tree as lua] to (Lua value "_ENV:compile(\(%tree as lua expr))")
compile [%tree as lua statements] to (..)
- Lua value "nomsu:compile(\(%tree as lua expr)):as_statements()"
+ Lua value "_ENV:compile(\(%tree as lua expr)):as_statements()"
compile [%tree as lua return] to (..)
- Lua value "nomsu:compile(\(%tree as lua expr)):as_statements('return ')"
+ Lua value "_ENV:compile(\(%tree as lua expr)):as_statements('return ')"
compile [remove action %action] to (..)
Lua "A\(=lua "string.as_lua_id(\(%action.stub))") = nil"
test:
- assume ("\(\(foo %x) as nomsu)" == "foo %x") or barf ".."
+ assume ("\(\(foo \%x) as nomsu)" == "foo %x") or barf ".."
action source code failed.
compile [%tree as nomsu] to (..)
- Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))"
+ Lua value "_ENV:tree_to_nomsu(\(%tree as lua expr))"
compile [%tree as inline nomsu] to (..)
- Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr), true)"
+ Lua value "_ENV:tree_to_nomsu(\(%tree as lua expr), true)"
action [%var as lua identifier, %var as lua id] (..)
lua> ".."
@@ -231,6 +231,14 @@ action [%tree with vars %replacements] (..)
end
end)
+compile [tree %tree with vars %replacements] to (..)
+ Lua value ".."
+ \(=lua "repr(\%tree)"):map(function(t)
+ if t.type == "Var" then
+ return \(%replacements as lua expr)[t[1]]
+ end
+ end)
+
compile [%tree has subtree %match_tree] to (..)
Lua value ".."
(function()
@@ -240,6 +248,39 @@ compile [%tree has subtree %match_tree] to (..)
end
end)()
+action [match %tree with %patt]:
+ lua> ".."
+ if \%patt.type == "Var" then return dict{[\%patt[1]]=\%tree} end
+ if \%patt.type == "Action" and \%patt.stub ~= \%tree.stub then return nil end
+ if #\%patt ~= #\%tree then return nil end
+ local matches = dict{}
+ for \%i=1,#\%patt do
+ if AST.is_syntax_tree(\%tree[\%i]) then
+ local submatch = \(match %tree.%i with %patt.%i)
+ if not submatch then return nil end
+ for k,v in pairs(submatch) do
+ if matches[k] and matches[k] ~= v then return nil end
+ matches[k] = v
+ end
+ end
+ end
+ return matches
+
+action [%tree with %patt ~> %replacement]:
+ lua> ".."
+ return \%tree:map(function(\%t)
+ local \%vars = \(match %t with %patt)
+ if not \%vars then return nil end
+ for \%k,\%v in pairs(\%vars) do
+ \%vars[\%k] = \(%v with %patt ~> %replacement)
+ end
+ return \%replacement:map(function(\%t)
+ if \%t.type == "Var" then
+ return \%vars[\%t[1]]
+ end
+ end)
+ end)
+
compile [declare locals in %code] to (..)
Lua value "\(%code as lua expr):declare_locals()"
@@ -275,11 +316,12 @@ compile [type of %obj] to (Lua value "type(\(%obj as lua expr))")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
- assume ((parse "foo %") == \(foo %))
-compile [parse %text] to (Lua value "nomsu:parse(\(%text as lua expr))")
+ assume ((parse "foo %") == \(foo \%))
+ assume ((parse "\\1") == \\1)
+compile [parse %text] to (Lua value "_ENV:parse(\(%text as lua expr))")
compile [parse %text from %filename] to (..)
Lua value ".."
- nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
+ _ENV:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
%text as lua expr
..))
@@ -287,19 +329,19 @@ test:
assume ((run "return (2 + 99)") == 101)
external %passed = (no)
run \:
- external %passed = (yes)
+ \(external \%passed = \(yes))
assume %passed
compile [run %nomsu_code] to (..)
Lua value ".."
- nomsu:run(\(%nomsu_code as lua expr), \(..)
+ _ENV:run(\(%nomsu_code as lua expr), \(..)
=lua "repr(tostring(\(%nomsu_code.source)))"
..)
test:
- assume ((\(5 + 5) as value) == 10) or barf "%tree as value failed."
-action [run tree %tree, %tree as value] (lua> "return nomsu:run(\%tree)")
+ assume ((\(\5 + \5) as value) == 10) or barf "%tree as value failed."
+action [run tree %tree, %tree as value] (lua> "return _ENV:run(\%tree)")
compile [compile %block, compiled %block, %block compiled] to (..)
- Lua value "nomsu:compile(\(%block as lua))"
+ Lua value "_ENV:compile(\(%block as lua))"
# Return statement is wrapped in a do..end block because Lua is unhappy if you
put code after a return statement, unless you wrap it in a block.
@@ -322,7 +364,7 @@ compile [command line args] to (Lua value "arg")
compile [with local compile actions %body] to (..)
Lua ".."
do
- local nomsu = table.fork(nomsu, {COMPILE_ACTIONS=table.fork(nomsu.COMPILE_ACTIONS)})
+ local nomsu = table.fork(nomsu, {COMPILE_ACTIONS=table.fork(COMPILE_ACTIONS)})
\(%body as lua statements)
end