116 lines
4.7 KiB
Plaintext
116 lines
4.7 KiB
Plaintext
#..
|
|
This File contains rules for making rules and macros and some helper functions to make
|
|
that easier.
|
|
|
|
# Rule to make rules:
|
|
lua code ".."
|
|
|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
|
|
| for i=2,#aliases do
|
|
| nomsu:defmacro(aliases[i], rewriter, body.src)
|
|
| end
|
|
|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 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
|
|
| \(%body)
|
|
|end
|
|
|
|
rule (%tree as lua) =:
|
|
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 (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) =:
|
|
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
|
|
|
|
# Compiler tools
|
|
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
|
|
|
|
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"
|
|
|