diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2015-11-10 07:56:30 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2015-11-10 07:56:30 +0000 |
commit | e35d5fe83fbce97f7ff110e62cb503406f4a32f8 (patch) | |
tree | d60f456ca2deb7b4586fae9217ef7035a898fec6 | |
parent | e7d8eb32504541c1f5549def12123b2375efa4e3 (diff) | |
download | lace-e35d5fe83fbce97f7ff110e62cb503406f4a32f8.tar.gz |
Allow sub sub defines
-rw-r--r-- | lib/lace/compiler.lua | 48 | ||||
-rw-r--r-- | test/test-lace.compile-subdefine2.rules | 1 | ||||
-rw-r--r-- | test/test-lace.compiler.lua | 5 | ||||
-rw-r--r-- | test/test-lace.engine-subsubdefine-error.rules | 1 | ||||
-rw-r--r-- | test/test-lace.engine-subsubdefine-works.rules | 1 | ||||
-rw-r--r-- | test/test-lace.engine.lua | 23 |
6 files changed, 58 insertions, 21 deletions
diff --git a/lib/lace/compiler.lua b/lib/lace/compiler.lua index 05bf047..7b3c504 100644 --- a/lib/lace/compiler.lua +++ b/lib/lace/compiler.lua @@ -61,29 +61,19 @@ local function _setposition(context, ruleset, linenr) context._lace.linenr = linenr end -local function compile_one_line(compcontext, line) - -- The line is a rule, so we don't need to think about that. The - -- first entry is a command. - local cmdname = line.content[1].str - local cmdfn = _command(compcontext, cmdname) - if type(cmdfn) ~= "function" then - return err.error("Unknown command: " .. cmdname, {1}) - end - - local args = {} - local rules = {} - for i = 1, #line.content do - if line.content[i].sub then - -- We have encountered a subdefine - -- We thusly need to magically construct a define. - local sub = line.content[i].sub +local function transfer_args(compcontext, content, rules) + local args, err = {} + for i = 1, #content do + if content[i].sub then + local sub = content[i].sub local defnr = compcontext._lace.magic_define_nr local definename = "__autodef"..tostring(defnr) compcontext._lace.magic_define_nr = defnr + 1 local definefn = _command(compcontext, "define") - local subargs = {} - for j = 1, #sub do - subargs[j] = sub[j].str or "{}" + local subargs + rules, subargs = transfer_args(compcontext, sub, rules) + if type(rules) ~= "table" then + return rules, subargs end local definerule, err = definefn(compcontext, "define", definename, unpack(subargs)) @@ -92,13 +82,29 @@ local function compile_one_line(compcontext, line) err.words = {i} return definerule, err end - args[i] = definename + args[#args+1] = definename rules[#rules+1] = definerule else - args[i] = line.content[i].str + args[#args+1] = content[i].str end end + return rules, args +end + +local function compile_one_line(compcontext, line) + -- The line is a rule, so we don't need to think about that. The + -- first entry is a command. + local cmdname = line.content[1].str + local cmdfn = _command(compcontext, cmdname) + if type(cmdfn) ~= "function" then + return err.error("Unknown command: " .. cmdname, {1}) + end + local rules, args = transfer_args(compcontext, line.content, {}) + if type(rules) ~= "table" then + return rules, args + end + local linerule, err = cmdfn(compcontext, unpack(args)) if type(linerule) ~= "table" then return linerule, err diff --git a/test/test-lace.compile-subdefine2.rules b/test/test-lace.compile-subdefine2.rules new file mode 100644 index 0000000..a753015 --- /dev/null +++ b/test/test-lace.compile-subdefine2.rules @@ -0,0 +1 @@ +allow "OK" {anyof {equal user daniel} {equal user geoff}} diff --git a/test/test-lace.compiler.lua b/test/test-lace.compiler.lua index 28d68e6..d6a26a2 100644 --- a/test/test-lace.compiler.lua +++ b/test/test-lace.compiler.lua @@ -393,6 +393,11 @@ function suite.okay_subdefine() assert(result, msg) end +function suite.okay_nested_subdefine() + local result, msg = compiler.compile(comp_context, "subdefine2") + assert(result, msg) +end + local count_ok = 0 for _, testname in ipairs(testnames) do -- print("Run: " .. testname) diff --git a/test/test-lace.engine-subsubdefine-error.rules b/test/test-lace.engine-subsubdefine-error.rules new file mode 100644 index 0000000..78022af --- /dev/null +++ b/test/test-lace.engine-subsubdefine-error.rules @@ -0,0 +1 @@ +allow "FAIL" {anyof {equal jeff banana} {error}} diff --git a/test/test-lace.engine-subsubdefine-works.rules b/test/test-lace.engine-subsubdefine-works.rules new file mode 100644 index 0000000..1fd3ee8 --- /dev/null +++ b/test/test-lace.engine-subsubdefine-works.rules @@ -0,0 +1 @@ +allow "PASS" {anyof {equal jeff harry} {equal jeff geoff}} diff --git a/test/test-lace.engine.lua b/test/test-lace.engine.lua index b3c38fd..e8721fc 100644 --- a/test/test-lace.engine.lua +++ b/test/test-lace.engine.lua @@ -266,6 +266,29 @@ function suite.subdefine_err_reported() assert(line4 == " ^^^^^^^", "The fourth line highlights relevant words") end +function suite.subsubdefine_works() + local ruleset, msg = lace.compiler.compile(comp_context, "subsubdefine-works") + assert(type(ruleset) == "table", "Ruleset did not compile") + local ectx = {jeff = "geoff"} + local result, msg = lace.engine.run(ruleset, ectx) + assert(result, msg) + assert(result == "allow", "Result should be allow") + assert(msg == "PASS", "Message should be pass") +end + +function suite.subsubdefine_err_reported() + local ruleset, msg = lace.compiler.compile(comp_context, "subsubdefine-error") + assert(type(ruleset) == "table", "Ruleset did not compile") + local ectx = {error = true} + local result, msg = lace.engine.run(ruleset, ectx) + assert(result == false, "Did not error out") + local line1, line2, line3, line4 = msg:match("^([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)$") + assert(line1 == "woah", "The first line must mention the error") + assert(line2 == "real-subsubdefine-error :: 1", "The second line is where the error happened") + assert(line3 == 'allow "FAIL" {anyof {equal jeff banana} {error}}', "The third line is the original line") + assert(line4 == " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", "The fourth line highlights relevant words") +end + local count_ok = 0 for _, testname in ipairs(testnames) do -- print("Run: " .. testname) |