diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2017-10-02 17:21:22 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2017-10-02 17:21:22 -0700 |
| commit | dcd3391b36c7accc194cfdc8654db085c9bc820e (patch) | |
| tree | d55e932ed8b4ba17dd5729803e27c1a543fb672a /lib/metaprogramming.nom | |
| parent | e2bbbfe1611f12b33692af175d661fa25b2cc616 (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.nom | 170 |
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" |
