diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2017-09-28 17:49:15 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2017-09-28 17:49:15 -0700 |
| commit | ac25e20b9f94505175841d9a8da7253f8996926d (patch) | |
| tree | 965a766f89b826f80a61569e1c7084e5e669558a /lib/metaprogramming.nom | |
| parent | 10d61df78bdbf002a3701e468b0a3c88be2cad03 (diff) | |
Kinda mostly working, except for closure vars like in lib/secrets.nom.
Diffstat (limited to 'lib/metaprogramming.nom')
| -rw-r--r-- | lib/metaprogramming.nom | 153 |
1 files changed, 73 insertions, 80 deletions
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom index 301d74b..7c643a9 100644 --- a/lib/metaprogramming.nom +++ b/lib/metaprogramming.nom @@ -2,80 +2,86 @@ This File contains rules for making rules and macros and some helper functions to make that easier. -# Nil +# Rule to make rules: lua code ".." - |nomsu:defmacro("nil", function(nomsu, vars) return "nil", nil end) - -# Macros: -lua code ".." - |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) + |nomsu:def("escaped rule %rule_def = %body", function(nomsu, vars) + | local aliases = nomsu:typecheck(vars, "rule_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 canonical = aliases[1] + | nomsu:def(canonical, thunk, body.src) + | local function rewriter(nomsu, vars) + | return nomsu:tree_to_lua(nomsu:replaced_vars(canonical, vars)) | end - | local template = vars.longhand - | local function parsing_as(nomsu, vars) - | local expanded = nomsu:replaced_vars(template, vars) - | local expr,statement = nomsu:tree_to_lua(expanded) - | return expr, statement + | for i=2,#aliases do + | nomsu:defmacro(aliases[i], rewriter, body.src) | 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) - -lua code ".." - |nomsu:defmacro("lua expr %code", function(nomsu, vars) - | return nomsu:tree_to_value(vars.code, vars), nil |end) +# Rule to make nomsu macros: +escaped rule \(escaped parse %shorthand as %longhand) = \: + lua code ".." + |local aliases = nomsu:typecheck(vars, "shorthand", "Block").value + |local template = nomsu:typecheck(vars, "longhand", "Block") + |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 +parse (rule %rule_def = %body) as: escaped rule \%rule_def = \%body -# 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 = ([[ +# Rule to make lua macros: +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) =: + 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 - | 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) -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)" + | \(%body) + |end rule (%tree as lua) =: - lua expr "nomsu:tree_to_lua(vars.tree)" - - -parse (lua block %block) as: - lua code ".." - |do - | \(%block) - |end + lua expr "nomsu:tree_to_lua(\(%tree))" +rule (%tree as value) =: + lua expr "nomsu:tree_to_value(\(%tree), vars)" +compile (repr %obj) to: + "nomsu:repr(\(%obj as lua))" -parse (nomsu) as: lua expr "nomsu" -parse (nomsu's %key) as: - lua expr "nomsu['\(%key)']" -parse (nomsu %method %args) as: - lua expr "nomsu['\(%method)'](nomsu, unpack(\(%args)))" -parse (repr %) as: nomsu "repr" [%] -repr 5 +parse (lua block %block) as: lua code ".." + |do + | \(%block) + |end +rule (%tree as lua statement) =: + lua block ".." + |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 +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) =: @@ -89,7 +95,7 @@ rule (help %rule) =: |end # Compiler tools -rule (eval %code; run %code) =: nomsu "run" [%code] +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") @@ -100,23 +106,10 @@ rule (source code from tree %tree) =: |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: repr (nomsu "tree_to_str" [\%code]) - -parse (parse %code as lua code %lua) as: - parse nomsu \%code as nomsu: - nomsu "replaced_vars" [\(lua code %lua), lua expr "vars"] - -parse (parse %code as lua expr %lua) as: - parse nomsu \%code as nomsu: - nomsu "replaced_vars" [\(lua expr %lua), lua expr "vars"] - -parse (parse %code as lua block %lua) as: - parse nomsu \%code as nomsu: - nomsu "replaced_vars" [\(lua block %lua), lua expr "vars"] +parse (parse tree %code) as: nomsu "tree_to_str" [\%code] -parse (pass) as lua code: "" +parse (enable debugging) as: lua code "nomsu.debug = true" +parse (disable debugging) as: lua code "nomsu.debug = false" -pass |
