summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-10 07:56:30 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-10 07:56:30 +0000
commite35d5fe83fbce97f7ff110e62cb503406f4a32f8 (patch)
treed60f456ca2deb7b4586fae9217ef7035a898fec6
parente7d8eb32504541c1f5549def12123b2375efa4e3 (diff)
downloadlace-e35d5fe83fbce97f7ff110e62cb503406f4a32f8.tar.gz
Allow sub sub defines
-rw-r--r--lib/lace/compiler.lua48
-rw-r--r--test/test-lace.compile-subdefine2.rules1
-rw-r--r--test/test-lace.compiler.lua5
-rw-r--r--test/test-lace.engine-subsubdefine-error.rules1
-rw-r--r--test/test-lace.engine-subsubdefine-works.rules1
-rw-r--r--test/test-lace.engine.lua23
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)