diff options
Diffstat (limited to 'lib/metaprogramming.nom')
| -rw-r--r-- | lib/metaprogramming.nom | 200 |
1 files changed, 0 insertions, 200 deletions
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom deleted file mode 100644 index 544ae59..0000000 --- a/lib/metaprogramming.nom +++ /dev/null @@ -1,200 +0,0 @@ -#.. - 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: -immediately: - lua> ".." - nomsu:define_compile_action("compile %actions to %lua", \(!! code location !!), function(\%actions, \%lua) - local signature = {}; - for i, action in ipairs(\%actions.value) do signature[i] = action:get_src(); end - local stubs = nomsu:get_stubs_from_signature(signature); - local stub_args = nomsu:get_args_from_signature(signature); - local arg_set = {}; - for i, arg in ipairs(stub_args[1]) do arg_set[arg] = true; end - if \%lua.type == "Text" then - error("Invalid type for 'compile % to %', expected a dict with expr/statements, but got text.", 0); - end - local body_lua = nomsu:tree_to_lua(\%lua); - local body_code = body_lua.statements or ("return "..body_lua.expr..";"); - local undeclared_locals = {}; - for i, body_local in ipairs(body_lua.locals or {}) do - if not arg_set[body_local] then - table.insert(undeclared_locals, body_local); - end - end - if #undeclared_locals > 0 then - body_code = "local "..table.concat(undeclared_locals, ", ")..";\\n"..body_code; - end - local lua_fn_args = table.concat(stub_args[1], ", "); - local def_tree = nomsu.compilestack[#nomsu.compilestack]; - local code_location = ("%s:%s,%s"):format(def_tree.filename, def_tree.start, def_tree.stop); - return {statements=([[ - nomsu:define_compile_action(]]..repr(signature)..[[, ]]..repr(code_location)..[[, function(]]..lua_fn_args..[[) - ]]..body_code.."\\n"..[[ - end); - ]])}; - end); - -# Compile-time action to make actions -immediately: - compile [action %actions %body] to: - lua> ".." - local signature = {}; - for i, action in ipairs(\%actions.value) do signature[i] = action:get_src(); end - local stubs = nomsu:get_stubs_from_signature(signature); - local stub_args = nomsu:get_args_from_signature(signature); - local arg_set = {}; - for i, arg in ipairs(stub_args[1]) do arg_set[arg] = true; end - local body_lua = nomsu:tree_to_lua(\%body); - local body_code = body_lua.statements or ("return "..body_lua.expr..";"); - local undeclared_locals = {}; - for i, body_local in ipairs(body_lua.locals or {}) do - if not arg_set[body_local] then - table.insert(undeclared_locals, body_local); - end - end - if #undeclared_locals > 0 then - body_code = "local "..table.concat(undeclared_locals, ", ")..";\\n"..body_code; - end - local lua_fn_args = table.concat(stub_args[1], ", "); - local def_tree = nomsu.compilestack[#nomsu.compilestack]; - local code_location = ("%s:%s,%s"):format(def_tree.filename, def_tree.start, def_tree.stop); - return {statements=[[ - nomsu:define_action(]]..repr(signature)..[[, ]]..repr(code_location)..[[, function(]]..lua_fn_args..[[) - ]]..body_code.."\\n"..[[ - end); - ]]}; - -# Macro to make nomsu macros: -immediately: - compile [parse %shorthand as %longhand] to: - lua> ".." - local signature = {}; - for i, action in ipairs(\%shorthand.value) do signature[i] = action:get_src(); end - local stubs = nomsu:get_stubs_from_signature(signature); - local stub_args = nomsu:get_args_from_signature(signature); - local lua_fn_args = table.concat(stub_args[1], ", "); - local template; - if \%longhand.type == "Block" then - local lines = {}; - for i, line in ipairs(\%longhand.value) do lines[i] = nomsu:dedent(line:get_src()); end - template = repr(table.concat(lines, "\\n")); - else - template = repr(nomsu:dedent(\%longhand:get_src())); - end - local replacements = {}; - for i, a in ipairs(stub_args[1]) do replacements[i] = a.."="..a; end - replacements = "{"..table.concat(replacements, ", ").."}"; - local def_tree = nomsu.compilestack[#nomsu.compilestack]; - local code_location = ("%s:%s,%s"):format(def_tree.filename, def_tree.start, def_tree.stop); - return {statements=[[ - nomsu:define_compile_action(]]..repr(signature)..[[, ]]..repr(code_location)..[[, function(]]..lua_fn_args..[[) - local template = nomsu:parse(]]..template..[[, ]]..repr(def_tree.filename)..[[); - local replacement = nomsu:tree_with_replaced_vars(template, ]]..replacements..[[); - return nomsu:tree_to_lua(replacement); - end); - ]]}; - -action [remove action %stub]: - lua> ".." - local fn = ACTION[\%stub]; - local metadata = ACTION_METADATA[fn]; - for i=#metadata.aliases,1,-1 do - metadata.arg_orders[metadata.aliases[i]] = nil; - table.remove(metadata.aliases, i); - end - ACTION[\%stub] = nil; - -immediately: - action [%tree as lua]: - =lua "nomsu:tree_to_lua(\%tree)" - - action [%tree as lua expr]: - lua> ".." - local lua = nomsu:tree_to_lua(\%tree); - if lua.locals or not lua.expr then - error("Invalid thing to convert to lua expr: "..\%tree:get_src()); - end - return lua.expr; - - action [%tree as lua statements]: - lua> ".." - local lua = nomsu:tree_to_lua(\%tree); - local code = lua.statements or (lua.expr..";"); - if lua.locals then - code = "local "..table.concat(lua.locals, ", ")..";\\n"..code; - end - return code; - - action [%tree as value]: - =lua "nomsu:tree_to_value(\%tree)" - -immediately: - compile [%tree's source code, %tree' source code] to {expr:"\(%tree as lua expr):get_src()"} - - compile [repr %obj] to {expr:"repr(\(%obj as lua expr))"} - compile [type of %obj] to {expr:"type(\(%obj as lua expr))"} - -immediately: - compile [nomsu] to {expr:"nomsu"} - compile [%var as lua identifier] to {expr:"nomsu:var_to_lua_identifier(\(%var as lua expr))"} - -action [action %names metadata]: - =lua "ACTION_METADATA[ACTION[\%names]]" - -# Get the source code for a function -action [help %action]: - lua> ".." - local metadata = \(action %action metadata); - if not metadata then - print("Action not found: "..repr(\%action)); - else - print(metadata.src or "<unknown source code>"); - end - -# Compiler tools -immediately: - compile [run %code] to {expr: "nomsu:run(\(%code as lua expr), '\(!! code location !!)')"} - parse [enable debugging] as: lua> "nomsu.debug = true;" - parse [disable debugging] as: lua> "nomsu.debug = false;" - -immediately: - compile [say %message] to: - lua> ".." - if \%message.type == "Text" then - return {statements="print("..\(%message as lua expr)..");"}; - else - return {statements="print(stringify("..\(%message as lua expr).."));"}; - end - -# Return -immediately: - #.. 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. - compile [return] to {statements:"do return; end"} - compile [return %return_value] to {statements:"do return \(%return_value as lua expr); end"} - -# Error functions -immediately: - compile [barf] to {statements:"error(nil, 0);"} - compile [barf %msg] to {statements:"error(\(%msg as lua expr), 0);"} - compile [assume %condition] to: - lua> "local \%assumption = 'Assumption failed: '..\%condition:get_src();" - return {..} - statements:".." - if not \(%condition as lua expr) then - error(\(repr %assumption), 0); - end - compile [assume %condition or barf %msg] to {..} - statements:".." - if not \(%condition as lua expr) then - error(\(%msg as lua expr), 0); - end - -# Literals -immediately: - compile [yes] to {expr:"true"} - compile [no] to {expr:"false"} - compile [nothing, nil, null] to {expr:"nil"} - |
