aboutsummaryrefslogtreecommitdiff
path: root/core/metaprogramming.nom
diff options
context:
space:
mode:
Diffstat (limited to 'core/metaprogramming.nom')
-rw-r--r--core/metaprogramming.nom103
1 files changed, 100 insertions, 3 deletions
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index d8d3d77..b3c4356 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -30,6 +30,23 @@ lua> ".."
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+test: compile [five] to (Lua value "5")
+test:
+ assume ((five) == 5) or barf "Compile to expression failed."
+ compile [loc x] to (Lua "local _x = 99;")
+test:
+ lua> "do"
+ loc x
+ assume (%x is 99) or barf "Compile to statements with locals failed."
+ lua> "end"
+ assume (%x is (nil)) or barf "Failed to properly localize a variable."
+ compile [asdf] to:
+ %tmp = ""
+ return (Lua %tmp)
+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(\
@@ -63,6 +80,21 @@ compile [call %fn with %args] to (..)
lua:append(")")
return lua
+test:
+ local action [foo %x]:
+ return "outer"
+
+ with local [action (foo %)]:
+ local action [foo %x]:
+ %y = (%x + 1)
+ return %y
+
+ assume ((foo 10) == 11) or barf "Action didn't work."
+ assume (%y is (nil)) or barf "Action leaked a local into globals."
+ parse [baz %] as (foo %)
+
+ assume ((foo 1) == "outer")
+
compile [local action %actions %body] to (..)
lua> ".."
local fn_name = "A"..string.as_lua_id(\%actions[1].stub)
@@ -87,13 +119,43 @@ compile [local action %actions %body] to (..)
end
return lua
+test:
+ action [baz1]: return "baz1"
+ action [baz2] "baz2"
+
+test:
+ assume ((baz1) == "baz1")
+ assume ((baz2) == "baz2")
+
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 [action %action] to (Lua value "A\(%action.stub as lua id)")
+test:
+ assume ((action (say %)) == (=lua "A_say_1"))
+
+compile [action %action] to (Lua value (%action as lua id))
+
+test:
+ parse [swap %x and %y] as (..)
+ do:
+ %tmp = %x
+ %x = %y
+ %y = %tmp
+
+test:
+ set {%1:1, %2:2}
+ swap %1 and %2
+ assume ((%1 == 2) and (%2 == 1)) or barf ".."
+ 'parse % as %' failed on 'swap % and %'
+
+ set {%tmp:1, %tmp2:2}
+ swap %tmp and %tmp2
+ assume ((%tmp == 2) and (%tmp2 == 1)) or barf ".."
+ 'parse % as %' variable mangling failed.
+
compile [parse %actions as %body] to (..)
lua> ".."
local replacements = {}
@@ -142,6 +204,10 @@ compile [%tree as lua return] to (..)
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 ".."
+ action source code failed.
+
compile [%tree as nomsu] to (..)
Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))"
@@ -175,6 +241,15 @@ action [%tree with vars %replacements] (..)
end
end)
+compile [%tree has subtree %match_tree] to (..)
+ Lua value ".."
+ (function()
+ local match_tree = \(%match_tree as lua expr)
+ for subtree in coroutine.wrap(function() \(%tree as lua expr):map(coroutine.yield) end) do
+ if subtree == match_tree then return true end
+ end
+ end)()
+
compile [declare locals in %code] to (..)
Lua value "\(%code as lua expr):declare_locals()"
@@ -194,10 +269,23 @@ compile [to %lua write %code joined by %glue] to (..)
Lua ".."
\(%lua as lua expr):concat_append(\(%code as lua expr), \(%glue as lua expr));
+test:
+ assume ((quote "one\n\"two\"") == "\"one\\n\\\"two\\\"\"")
+
compile [quote %s] to (Lua value "repr(\(%s as lua expr))")
+
+test:
+ assume ((type of {}) == "table") or barf "type of failed."
+
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(NomsuCode(\"\(%text.source)\", \(%text as lua expr)))"
+ Lua value "nomsu:parse(\(%text as lua expr))"
compile [parse %text from %filename] to (..)
Lua value ".."
@@ -205,12 +293,21 @@ compile [parse %text from %filename] to (..)
%text as lua expr
..))
+test:
+ assume ((run "return (2 + 99)") == 101)
+ external %passed = (no)
+ run \: external %passed = (yes)
+ assume %passed
+
compile [run %nomsu_code] to (..)
Lua value ".."
nomsu: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)")
compile [compile %block, compiled %block, %block compiled] to (..)
Lua value "nomsu:compile(\(%block as lua))"
@@ -245,4 +342,4 @@ compile [with local compile actions %body] to (..)
action [Nomsu version]:
use "lib/version.nom"
return ".."
- \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) \ No newline at end of file
+ \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)