aboutsummaryrefslogtreecommitdiff
path: root/lib/metaprogramming.nom
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2017-10-02 17:21:22 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2017-10-02 17:21:22 -0700
commitdcd3391b36c7accc194cfdc8654db085c9bc820e (patch)
treed55e932ed8b4ba17dd5729803e27c1a543fb672a /lib/metaprogramming.nom
parente2bbbfe1611f12b33692af175d661fa25b2cc616 (diff)
Updated to undo some of the block/thunk stuff. Thunks are thunks, and
expressions can be grouped with parens, and they have a clear distinction.
Diffstat (limited to 'lib/metaprogramming.nom')
-rw-r--r--lib/metaprogramming.nom170
1 files changed, 74 insertions, 96 deletions
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom
index 4aa10e3..12144b4 100644
--- a/lib/metaprogramming.nom
+++ b/lib/metaprogramming.nom
@@ -4,127 +4,105 @@
# Rule to make rules:
lua code ".."
- |nomsu:defmacro("rule %rule_def = %body", function(nomsu, vars)
- | local aliases = nomsu:typecheck(vars, "rule_def", "Block").value
- | local canonical = aliases[1]
- | local body = nomsu:typecheck(vars, "body", "Block")
- | local thunk = nomsu:tree_to_lua({type="Thunk", value={type="Statements", value=body.value, src=body.src}, src=body.src})
- | local lua = ([[
+ |nomsu:defmacro("rule %signature = %body", (function(nomsu, vars)
+ | local signature = nomsu:typecheck(vars, "signature", "List").value;
+ | local body = nomsu:typecheck(vars, "body", "Thunk");
+ | return ([[
|nomsu:def(%s, %s, %s)
- |]]):format(nomsu:repr(canonical.src), thunk, nomsu:repr(body.src))
- | if #aliases > 1 then
- | lua = lua .. "\n" .. ([[
- |do
- | local aliased = %s
- | local src = %s
- | local function dealiaser(nomsu, vars)
- | return nomsu:tree_to_lua(nomsu:replaced_vars(aliased, vars))
- | end
- |]]):format(nomsu:repr(canonical), nomsu:repr(canonical.src))
- | for i=2,#aliases do
- | lua = lua .. ([[
- | nomsu:defmacro(%s, dealiaser, %s)
- |]]):format(nomsu:repr(aliases[i].src), nomsu:repr(canonical.src))
- | end
- | lua = lua .. [[
- |end]]
- | end
- | return nil, lua
- |end, "<source can be found in lib/metaprogramming.nom>")
+ |]]):format(nomsu:repr(signature), nomsu:tree_to_lua(body), nomsu:repr(body.src)), nil;
+ |end), "<source can be found in lib/metaprogramming.nom>");
# Rule to make nomsu macros:
-rule (escaped parse %shorthand as %longhand) =:
+rule [escaped parse %shorthand as %longhand] =:
lua code ".."
- |local aliases = nomsu:typecheck(vars, "shorthand", "Block").value
- |local template = nomsu:typecheck(vars, "longhand", "Block")
+ |local aliases = nomsu:typecheck(vars, "shorthand", "List").value;
+ |if #vars.longhand.value ~= 1 then;
+ | nomsu:error("Expected only 1 line to parse to, but got "..tostring(#vars.longhand.value));
+ |end;
+ |local template = nomsu:typecheck(vars, "longhand", "Thunk").value[1];
|local function parsing_as(nomsu, vars)
- | local replacement = nomsu:replaced_vars(template, vars)
- | return nomsu:tree_to_lua(replacement)
- |end
- |for _,call in ipairs(aliases) do
- | nomsu:defmacro(call, parsing_as, template.src)
- |end
-escaped parse \(parse %shorthand as %longhand) as \: escaped parse \%shorthand as \%longhand
+ | local replacement = nomsu:replaced_vars(template, vars);
+ | return nomsu:tree_to_lua(replacement);
+ |end;
+ |nomsu:defmacro(aliases, parsing_as, template.src);
+escaped parse \[parse %shorthand as %longhand] as \: escaped parse \%shorthand as \%longhand
# Rule to make lua macros:
-rule (escaped compile %macro_def to %body) =:
+rule [escaped compile %macro_def to %body] =:
lua code ".."
- |local aliases = nomsu:typecheck(vars, "macro_def", "Block").value
- |local body = nomsu:typecheck(vars, "body", "Block")
- |local thunk = nomsu:tree_to_value({type="Thunk", value={type="Statements", value=body.value, src=body.src}, src=body.src})
- |for _,alias in ipairs(aliases) do
- | nomsu:defmacro(alias, thunk, body.src)
- |end
-rule (escaped compile %macro_def to code %body) =:
+ |local aliases = nomsu:typecheck(vars, "macro_def", "List").value;
+ |local body = nomsu:typecheck(vars, "body", "Thunk");
+ |local thunk = nomsu:tree_to_value(body);
+ |nomsu:defmacro(aliases, thunk, body.src);
+rule [escaped compile %macro_def to code %body] =:
lua code ".."
- |local aliases = nomsu:typecheck(vars, "macro_def", "Block").value
- |local body = nomsu:typecheck(vars, "body", "Block")
- |local thunk = nomsu:tree_to_value({type="Thunk", value={type="Statements", value=body.value, src=body.src}, src=body.src})
- |local thunk2 = function(nomsu, vars) return nil, thunk(nomsu, vars) end
- |for _,alias in ipairs(aliases) do
- | nomsu:defmacro(alias, thunk2)
- |end
-parse (compile %macro_def to %body) as: escaped compile \%macro_def to \%body
-parse (compile %macro_def to code %body) as: escaped compile \%macro_def to code \%body
-parse (compile %macro_def to block %body) as: escaped compile \%macro_def to code\: ".."
- |do
- | \(%body)
- |end
+ |local aliases = nomsu:typecheck(vars, "macro_def", "List").value;
+ |local body = nomsu:typecheck(vars, "body", "Thunk");
+ |local thunk = nomsu:tree_to_value(body);
+ |local thunk_wrapper = function(nomsu, vars) return nil, thunk(nomsu, vars); end;
+ |nomsu:defmacro(aliases, thunk_wrapper, body.src);
+parse [compile %macro_def to %body] as: escaped compile \%macro_def to \%body
+parse [compile %macro_def to code %body] as: escaped compile \%macro_def to code \%body
-rule (do %) =: %
+rule [do %] =: %
-rule (%tree as lua) =:
+rule [%tree as lua] =:
lua expr "nomsu:tree_to_lua(\(%tree))"
-rule (%tree as value) =:
+rule [%tree as value] =:
lua expr "nomsu:tree_to_value(\(%tree), vars)"
-compile (repr %obj) to:
+compile [repr %obj] to:
"nomsu:repr(\(%obj as lua))"
-parse (lua block %block) as: lua code ".."
- |do
+parse [lua block %block] as: lua code ".."
+ |do;
| \(%block)
- |end
-rule (%tree as lua statement) =:
+ |end;
+rule [%tree as lua statement] =:
lua block ".."
- |local _,statement = nomsu:tree_to_lua(\(%tree))
- |return statement
-rule (%tree as lua statements) =:
+ |local _,statement = nomsu:tree_to_lua(\(%tree));
+ |return statement;
+rule [%tree as lua statements] =:
lua block ".."
- |local statements_tree = {type='Statements', value=\(%tree).value, src=\(%tree).src}
- |local _,statements = nomsu:tree_to_lua(statements_tree)
- |return statements
+ |local lua_bits = {};
+ |local statements = nomsu:typecheck(vars, "tree", "Thunk").value;
+ |for _,bit in ipairs(statements) do;
+ | local expr, statement = nomsu:tree_to_lua(bit);
+ | if statement then; table.insert(lua_bits, statement); end;
+ | if expr then; table.insert(lua_bits, "ret = "..expr..";"); end;
+ |end;
+ |return table.concat(lua_bits, "\\n");
-compile (nomsu) to: "nomsu"
-compile (nomsu's %key) to: "nomsu[\(%key as lua)]"
-compile (nomsu %method %args) to: "nomsu[\(%method as lua)](nomsu, unpack(\(%args as lua)))"
+compile [nomsu] to: "nomsu"
+compile [nomsu's %key] to: "nomsu[\(%key as lua)]"
+compile [nomsu %method %args] to: "nomsu[\(%method as lua)](nomsu, unpack(\(%args as lua)))"
# Get the source code for a function
-rule (help %rule) =:
+rule [help %rule] =:
lua block ".."
- |local fn_def = nomsu:get_fn_def(vars.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.invocation))
- | .." ="..(fn_def.src or ":\\n <unknown source code>"))
- |end
+ |local fn_def = nomsu:get_fn_def(vars.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.stub))
+ | .." ="..(fn_def.src or ":\\n <unknown source code>"));
+ |end;
# Compiler tools
-parse (eval %code; run %code) as: nomsu "run" [%code]
-rule (source code from tree %tree) =:
+parse [eval %code, run %code] as: nomsu "run" [%code]
+rule [source code from tree %tree] =:
lua block ".."
- |local _,_,leading_space = vars.tree.src:find("\\n(%s*)%S")
- |if leading_space then
- | local chunk1, chunk2 = vars.tree.src:match(":%s*([^\\n]*)(\\n.*)")
- | chunk2 = chunk2:gsub("\\n"..leading_space, "\\n")
- | return chunk1..chunk2.."\\n"
- |else
- | return vars.tree.src:match(":%s*(%S.*)").."\\n"
- |end
-parse (source code %body) as: source code from tree \%body
+ |local _,_,leading_space = vars.tree.src:find("\\n(%s*)%S");
+ |if leading_space then;
+ | local chunk1, chunk2 = vars.tree.src:match(":%s*([^\\n]*)(\\n.*)");
+ | chunk2 = chunk2:gsub("\\n"..leading_space, "\\n");
+ | return chunk1..chunk2.."\\n";
+ |else;
+ | return vars.tree.src:match(":%s*(%S.*)").."\\n";
+ |end;
+parse [source code %body] as: source code from tree \%body
-parse (parse tree %code) as: nomsu "tree_to_str" [\%code]
+parse [parse tree %code] as: nomsu "tree_to_str" [\%code]
-parse (enable debugging) as: lua code "nomsu.debug = true"
-parse (disable debugging) as: lua code "nomsu.debug = false"
+parse [enable debugging] as: lua code "nomsu.debug = true"
+parse [disable debugging] as: lua code "nomsu.debug = false"