From dfd39f0b14794b360fd6c961c65ab45d229e00b1 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 22 Jul 2018 13:59:08 -0700 Subject: Shifting further towards having inline tests. Also added a helper function for directly extracting source lines from a Source or AST. --- core/metaprogramming.nom | 103 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 3 deletions(-) (limited to 'core/metaprogramming.nom') 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) -- cgit v1.2.3