aboutsummaryrefslogtreecommitdiff
path: root/lib/metaprogramming.nom
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2017-09-28 17:49:15 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2017-09-28 17:49:15 -0700
commitac25e20b9f94505175841d9a8da7253f8996926d (patch)
tree965a766f89b826f80a61569e1c7084e5e669558a /lib/metaprogramming.nom
parent10d61df78bdbf002a3701e468b0a3c88be2cad03 (diff)
Kinda mostly working, except for closure vars like in lib/secrets.nom.
Diffstat (limited to 'lib/metaprogramming.nom')
-rw-r--r--lib/metaprogramming.nom153
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