aboutsummaryrefslogtreecommitdiff
path: root/lib/metaprogramming.nom
diff options
context:
space:
mode:
Diffstat (limited to 'lib/metaprogramming.nom')
-rw-r--r--lib/metaprogramming.nom97
1 files changed, 61 insertions, 36 deletions
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom
index 9dcc9df..e60a235 100644
--- a/lib/metaprogramming.nom
+++ b/lib/metaprogramming.nom
@@ -5,32 +5,74 @@
# Nil
lua code ".."
|nomsu:defmacro("nil", function(nomsu, vars) return "nil", nil end)
-..with value 0
# Macros:
lua code ".."
- |nomsu:def("parse %shorthand as %longhand", function(nomsu, vars)
- | local alias = nomsu:get_alias(vars.shorthand)
+ |local function parse_as(nomsu, vars)
+ | if vars.shorthand.type ~= "Block" then
+ | nomsu:error("Expected shorthand to be Block, but got "..vars.shorthand.type)
+ | end
+ | if vars.longhand.type ~= "Block" then
+ | nomsu:error("Expected longhand to be Block, but got "..vars.longhand.type)
+ | end
| local template = vars.longhand
- | nomsu:defmacro(alias, function(nomsu, vars)
- | return nomsu:tree_to_lua(nomsu:replaced_vars(template, vars))
- | end)
+ | local function parsing_as(nomsu, vars)
+ | local expanded = nomsu:replaced_vars(template, vars)
+ | local expr,statement = nomsu:tree_to_lua(expanded)
+ | return expr, statement
+ | end
+ | for _,call in ipairs(vars.shorthand.value) do
+ | nomsu:defmacro(call, parsing_as)
+ | end
+ |end
+ |nomsu:def("parse nomsu %shorthand as nomsu %longhand", parse_as)
+parse nomsu \(parse %shorthand as %longhand) as nomsu \(parse nomsu \%shorthand as nomsu \%longhand)
+parse (foo %x) as (baz %x)
+
+lua code ".."
+ |nomsu:defmacro("lua expr %code", function(nomsu, vars)
+ | return nomsu:tree_to_value(vars.code, vars), nil
+ |end)
+
+
+# Rule that lets you make new rules
+lua code ".."
+ |nomsu:defmacro("rule %rule_def = %body", function(nomsu, vars)
+ | if vars.rule_def.type ~= "Block" then
+ | nomsu:error("Wrong type for rule definition, expected Block, but got "..vars.rule_def.type)
+ | end
+ | local thunk = nomsu:tree_to_lua({type="Thunk", value=vars.body, src=vars.body.src})
+ | local fn_name = "fn_"..nomsu:var_to_lua_identifier(nomsu:get_stub(vars.rule_def.value[1]))
+ | local lua = ([[
+ |do
+ | local %s = %s
+ | for _,alias in ipairs(%s) do
+ | nomsu:def(alias, %s)
+ | end
+ |end]]):format(fn_name, thunk, nomsu:repr(vars.rule_def.value), fn_name)
+ | return nil, lua
|end)
-..with value (nil)
+parse (rule %rule_name) as: lua expr "nomsu.defs[(nomsu:get_stub(\(%rule_name).value[1]))]"
+
+
+# Macro helper functions
+rule (%tree as value) =:
+ lua expr "nomsu:tree_to_value(vars.tree, vars)"
+
+rule (%tree as lua) =:
+ lua expr "nomsu:tree_to_lua(vars.tree)"
-parse \(lua code %code) as\: lua code %code with value (nil)
-parse \(lua block %block) as\:
+
+parse (lua block %block) as:
lua code ".."
|do
| \(%block)
|end
- ..with value (nil)
-parse \(lua value %value) as\: lua code (nil) with value %value
-parse \(nomsu) as\: lua value "nomsu"
-parse \(nomsu's %key) as\:
- lua value "nomsu[\(%key as lua)]"
-parse \(nomsu %method %args) as\:
+parse (nomsu) as: lua expr "nomsu"
+parse (nomsu's %key) as:
+ lua expr "nomsu[\(%key as lua)]"
+parse (nomsu %method %args) as:
lua block ".."
|local args = {"nomsu"}
|for _,arg in ipairs(vars.args.value) do
@@ -39,15 +81,7 @@ parse \(nomsu %method %args) as\:
|local method_name = nomsu:repr(nomsu:tree_to_value(vars.method, vars))
..with value ".."
|("nomsu[%s](%s)"):format(method_name, table.concat(args, ", "))
-parse \(repr %) as\: nomsu "repr" [%]
-
-# Rule that lets you make new rules
-lua block ".."
- |nomsu:def("rule helper %rule_def = %body", function(nomsu, vars)
- | nomsu:def(nomsu:get_alias(vars.rule_def), vars.body)
- |end)
-parse \(rule %rule_def = %body) as\: rule helper \(%rule_def) = \(%body)
-parse \(rule %rule_name) as\: lua value "nomsu.defs[nomsu:get_alias(\(%rule_name))]"
+parse (repr %) as: nomsu "repr" [%]
# Get the source code for a function
rule (help %rule) =:
@@ -56,17 +90,10 @@ rule (help %rule) =:
|if not fn_def then
| nomsu:writeln("Rule not found: "..nomsu:repr(vars.rule))
|else
- | nomsu:writeln("rule "..nomsu:repr(nomsu.utils.keys(fn_def.aliases))
+ | nomsu:writeln("rule "..nomsu:repr(nomsu.utils.keys(fn_def.invocation))
| .." ="..(fn_def.src or ":\\n <unknown source code>"))
|end
-# Macro helper functions
-rule (%tree as value) =:
- lua expr "nomsu:tree_to_value(vars.tree, vars)"
-
-rule (%tree as lua) =:
- lua expr "nomsu:tree_to_lua(vars.tree)"
-
# Compiler tools
rule (eval %code; run %code) =: nomsu "run" [%code]
rule (source code from tree %tree) =:
@@ -80,9 +107,7 @@ rule (source code from tree %tree) =:
| return vars.tree.src:match(":%s*(%S.*)").."\\n"
|end
-macro (source code %body) =:
- nomsu "repr" [nomsu "call" ["source code from tree %", %body]]
+parse (source code %body) as: source code from tree \%body
-macro (parse tree %code) =:
- nomsu "repr" [nomsu "stringify_tree" [lua expr "vars.code.value"]]
+parse (parse tree %code) as: repr (nomsu "tree_to_str" [\%code])