From bf37295faeb9535c56671f4b2050260e1b88cd32 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 15 Jan 2019 15:53:31 -0800 Subject: Updating to v6.15, which includes "external (...)" instead of separate 'externally' versions of stuff, and some auto-formatting. --- lib/core/metaprogramming.nom | 217 ++++++++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 98 deletions(-) (limited to 'lib/core/metaprogramming.nom') diff --git a/lib/core/metaprogramming.nom b/lib/core/metaprogramming.nom index 936f9bd..9b3d5c4 100644 --- a/lib/core/metaprogramming.nom +++ b/lib/core/metaprogramming.nom @@ -1,9 +1,9 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This File contains actions for making actions and compile-time actions and some helper functions to make that easier. -lua> "NOMSU_CORE_VERSION = 14" +lua> "NOMSU_CORE_VERSION = 15" lua> "NOMSU_LIB_VERSION = 8" lua> (" do @@ -25,8 +25,7 @@ lua> (" COMPILE_RULES["1 ->"] = function(\(nomsu environment), \$args, \$body) if \$args and not \$body then \$args, \$body = {}, \$args end local body_lua = SyntaxTree:is_instance(\$body) and \(nomsu environment):compile(\$body) or \$body - if SyntaxTree:is_instance(\$body) and \$body.type ~= "Block" then body_lua:prepend("\ - ..return ") end + if SyntaxTree:is_instance(\$body) and \$body.type ~= "Block" then body_lua:prepend("return ") end local lua = LuaCode("(function(") if SyntaxTree:is_instance(\$args) and (\$args.type == "Action" or \$args.type == "MethodCall") then \$args = \$args:get_args() @@ -41,8 +40,7 @@ lua> (" end elseif not arg_lua:is_lua_id() then compile_error_at(SyntaxTree:is_instance(arg) and arg or nil, - "This does not compile to a Lua identifier, so it can't be used as a function \ - ..argument.", + "This does not compile to a Lua identifier, so it can't be used as a function argument.", "This should probably be a Nomsu variable instead (like $x).") end lua:add(i > 1 and ", " or "", arg_lua) @@ -186,26 +184,40 @@ test: ") test: - externally (baz1) means: - return "baz1" - externally (baz2) means "baz2" + $loc = 99 + external ($glob = 99) test: - assume ((baz1) == "baz1") - assume ((baz2) == "baz2") + assume $loc == (nil) + assume $glob == 99 -(externally $action means $body) compiles to: +(external $body) compiles to: lua> (" - local lua = \(\($action means $body) as lua) - lua:remove_free_vars({\$action:get_stub():as_lua_id()}) + local lua = \($body as lua) + lua:remove_free_vars() return lua ") -(externally $actions all mean $body) compiles to: +test: + [$x, $y] = ["outer", "outer"] + external: + (set external x local y) means: + with external [$x]: + $x = "inner" + $y = "inner" + set external x local y + unless (($x == "inner") and ($y == "outer")): + fail "'with external' failed." + +(with external $externals $body) compiles to: lua> (" - local lua = \(\($actions all mean $body) as lua) - lua:remove_free_vars(table.map(\$actions, function(a) return a:get_stub():as_lua_id() end)) - return lua + local body_lua = \($body as lua) + local varnames = {} + for i,\$v in ipairs(\$externals) do + varnames[i] = \($v as lua):text() + end + body_lua:remove_free_vars(varnames) + return body_lua ") test: @@ -239,8 +251,8 @@ test: if replacements[t:as_var()] then return replacements[t:as_var()] else - return "SyntaxTree{mangle("..t:as_var():as_lua().."), type="..t.type:as_lua()..", \ - ..source="..tostring(t.source):as_lua().."}" + return "SyntaxTree{mangle("..t:as_var():as_lua().."), type="..t.type:as_lua(\ + ..)..", source="..tostring(t.source):as_lua().."}" end elseif SyntaxTree:is_instance(t) then local ret = {} @@ -274,34 +286,37 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [$action parses as $body] all parse as ([$action] all parse as $body) -externally (in (nomsu environment) $tree as lua expr) means: - lua> (" - local tree_lua = \(nomsu environment):compile(\$tree) - if \$tree.type == 'Block' then - tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()') - elseif \$tree.type == 'MethodCall' and #\$tree > 2 then - compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).."\ - .. method calls.", - "Replace this with a single method call.") - end - return tree_lua - ") +external: + (in (nomsu environment) $tree as lua expr) means: + lua> (" + local tree_lua = \(nomsu environment):compile(\$tree) + if \$tree.type == 'Block' then + tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()') + elseif \$tree.type == 'MethodCall' and #\$tree > 2 then + compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).."\ + .. method calls.", + "Replace this with a single method call.") + end + return tree_lua + ") # Need to make sure the proper environment is used for compilation (i.e. the caller's environment) -($tree as lua expr) compiles to (\(in \(nomsu environment) $tree as lua expr) as lua) +($tree as lua expr) compiles to + \(in \(nomsu environment) $tree as lua expr) as lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -externally [$var as lua identifier, $var as lua id] all mean: - lua> (" - local lua = \($var as lua) - if not lua:text():is_a_lua_id() then - compile_error(\$var, - "This is supposed to be something that compiles to a valid Lua identifier.", - "This should probably be a variable.") - end - return lua - ") +external: + [$var as lua identifier, $var as lua id] all mean: + lua> (" + local lua = \($var as lua) + if not lua:text():is_a_lua_id() then + compile_error(\$var, + "This is supposed to be something that compiles to a valid Lua identifier.", + "This should probably be a variable.") + end + return lua + ") test: (num args (*extra arguments*)) means (select "#" (*extra arguments*)) @@ -312,11 +327,10 @@ test: assume (third arg 5 6 7 8) == 7 (*extra arguments*) compiles to "..." - ($ is syntax tree) compiles to "SyntaxTree:is_instance(\($ as lua expr))" - -externally ($ is $kind syntax tree) means - =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" +external: + ($ is $kind syntax tree) means + =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" ($tree with $t -> $replacement) compiles to (" \($tree as lua expr):map(function(\($t as lua expr)) @@ -329,14 +343,15 @@ externally ($ is $kind syntax tree) means end) ") -externally ($tree with vars $replacements) means - =lua (" - \$tree:map(function(\$t) - if \$t.type == "Var" then - return \$replacements[\$t:as_var()] - end - end) - ") +external: + ($tree with vars $replacements) means + =lua (" + \$tree:map(function(\$t) + if \$t.type == "Var" then + return \$replacements[\$t:as_var()] + end + end) + ") (tree $tree with vars $replacements) compiles to (" \(=lua "(\$tree):as_lua()"):map(function(t) @@ -355,24 +370,25 @@ externally ($tree with vars $replacements) means end)() ") -externally (match $tree with $patt) means: - lua> (" - if \$patt.type == "Var" then return Dict{[\$patt:as_var()]=\$tree} end - if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end - if #\$patt ~= #\$tree then return nil end - local matches = Dict{} - for \($i)=1,#\$patt do - if SyntaxTree:is_instance(\$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 +external: + (match $tree with $patt) means: + lua> (" + if \$patt.type == "Var" then return Dict{[\$patt:as_var()]=\$tree} end + if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end + if #\$patt ~= #\$tree then return nil end + local matches = Dict{} + for \($i)=1,#\$patt do + if SyntaxTree:is_instance(\$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 - end - return matches - ") + return matches + ") test: assume @@ -390,20 +406,20 @@ test: assume ({} is a "Dict") assume ("" is text) assume ("" isn't a "Dict") -externally ($ is text) means (=lua "\(lua type of $) == 'string'") -externally [$ is not text, $ isn't text] all mean - =lua "\(lua type of $) ~= 'string'" -externally (type of $) means: - lua> (" - local lua_type = \(lua type of $) - if lua_type == 'string' then return 'Text' - elseif lua_type == 'table' or lua_type == 'userdata' then - local mt = getmetatable(\$) - if mt and mt.__type then return mt.__type end - end - return lua_type - ") +external: + ($ is text) means (=lua "\(lua type of $) == 'string'") + [$ is not text, $ isn't text] all mean (=lua "\(lua type of $) ~= 'string'") + (type of $) means: + lua> (" + local lua_type = \(lua type of $) + if lua_type == 'string' then return 'Text' + elseif lua_type == 'table' or lua_type == 'userdata' then + local mt = getmetatable(\$) + if mt and mt.__type then return mt.__type end + end + return lua_type + ") [$ is a $type, $ is an $type] all parse as ((type of $) == $type) [$ isn't a $type, $ isn't an $type, $ is not a $type, $ is not an $type] @@ -441,19 +457,24 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# - (with local compile actions $body) compiles to (" - do - local OLD_RULES = COMPILE_RULES - local OLD_ENV = \(nomsu environment) - local \(nomsu environment) = setmetatable({ - COMPILE_RULES=setmetatable({}, {__index=OLD_RULES}) - }, {__index=OLD_ENV}) - \($body as lua) - end +test: + using compile rules: + (yes) compiles to "3" + assume $(COMPILE RULES).yes + ..do: + assume (yes) == 3 + assume (yes) == (=lua "true") + +(using compile rules $rules do $body) compiles to: + lua> (" + local env = \(new environment) + env:run(\$rules) + local lua = env:compile(\$body) + return lua ") -externally (Nomsu version) means: - return (" - \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) - ") +external: + (Nomsu version) means: + return (" + \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) + ") -- cgit v1.2.3