summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-09 22:41:02 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-09 22:41:02 +0000
commite7d8eb32504541c1f5549def12123b2375efa4e3 (patch)
tree608576ec94b63244376b9f7ecb202fc76d8c76e9
parent85693cd4ab8d1c3b26901c88a736541b484891eb (diff)
downloadlace-e7d8eb32504541c1f5549def12123b2375efa4e3.tar.gz
Support sub-definition using braces
-rw-r--r--lib/lace/compiler.lua30
-rw-r--r--test/test-lace.compile-subdefine1.rules1
-rw-r--r--test/test-lace.compiler.lua13
-rw-r--r--test/test-lace.engine-subdefine-error.rules2
-rw-r--r--test/test-lace.engine-subdefine-works.rules2
-rw-r--r--test/test-lace.engine.lua21
6 files changed, 67 insertions, 2 deletions
diff --git a/lib/lace/compiler.lua b/lib/lace/compiler.lua
index 86c96df..05bf047 100644
--- a/lib/lace/compiler.lua
+++ b/lib/lace/compiler.lua
@@ -71,15 +71,40 @@ local function compile_one_line(compcontext, line)
end
local args = {}
+ local rules = {}
for i = 1, #line.content do
- args[i] = line.content[i].str
+ 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 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 "{}"
+ end
+ local definerule, err = definefn(compcontext, "define", definename,
+ unpack(subargs))
+ if type(definerule) ~= "table" then
+ -- for now, we lock the error to the whole sublex
+ err.words = {i}
+ return definerule, err
+ end
+ args[i] = definename
+ rules[#rules+1] = definerule
+ else
+ args[i] = line.content[i].str
+ end
end
local linerule, err = cmdfn(compcontext, unpack(args))
if type(linerule) ~= "table" then
return linerule, err
end
- return {linerule}, err
+ rules[#rules+1] = linerule
+ return rules, err
end
--- Internal ruleset compilation.
@@ -212,6 +237,7 @@ local function compile_ruleset(ctx, src, cnt)
}
}
ctx._lace.linenr = 1
+ ctx._lace.magic_define_nr = 1
end
local ok, ret, msg = xpcall(function()
return internal_compile_ruleset(ctx, src, cnt)
diff --git a/test/test-lace.compile-subdefine1.rules b/test/test-lace.compile-subdefine1.rules
new file mode 100644
index 0000000..c917225
--- /dev/null
+++ b/test/test-lace.compile-subdefine1.rules
@@ -0,0 +1 @@
+allow "Hurrah" {equal jeff}
diff --git a/test/test-lace.compiler.lua b/test/test-lace.compiler.lua
index 412f93c..28d68e6 100644
--- a/test/test-lace.compiler.lua
+++ b/test/test-lace.compiler.lua
@@ -143,6 +143,14 @@ local comp_context = {
nocompile = function()
return err.error("NOCOMPILE", {2})
end,
+ equal = function(ctx, eq, key, value)
+ return {
+ fn = function(ectx, ekey, evalue)
+ return ectx[ekey] == evalue
+ end,
+ args = { key, value },
+ }
+ end,
},
},
}
@@ -380,6 +388,11 @@ function suite.defaults_propagate()
assert(result, msg)
end
+function suite.okay_subdefine()
+ local result, msg = compiler.compile(comp_context, "subdefine1")
+ assert(result, msg)
+end
+
local count_ok = 0
for _, testname in ipairs(testnames) do
-- print("Run: " .. testname)
diff --git a/test/test-lace.engine-subdefine-error.rules b/test/test-lace.engine-subdefine-error.rules
new file mode 100644
index 0000000..9b0856d
--- /dev/null
+++ b/test/test-lace.engine-subdefine-error.rules
@@ -0,0 +1,2 @@
+deny "Boo" {equal jeff geoff}
+allow "Yay" {error}
diff --git a/test/test-lace.engine-subdefine-works.rules b/test/test-lace.engine-subdefine-works.rules
new file mode 100644
index 0000000..5454b07
--- /dev/null
+++ b/test/test-lace.engine-subdefine-works.rules
@@ -0,0 +1,2 @@
+default deny
+allow "PASS" {equal jeff geoff}
diff --git a/test/test-lace.engine.lua b/test/test-lace.engine.lua
index 7a39904..b3c38fd 100644
--- a/test/test-lace.engine.lua
+++ b/test/test-lace.engine.lua
@@ -245,6 +245,27 @@ function suite.unknownanyof()
assert(line4 == " ^^^^", "The fourth line highlights relevant words")
end
+function suite.subdefine_works()
+ local ruleset, msg = lace.compiler.compile(comp_context, "subdefine-works")
+ assert(type(ruleset) == "table", "Ruleset did not compile")
+ local ectx = {jeff = "geoff"}
+ local result, msg = lace.engine.run(ruleset, ectx)
+ assert(result, msg)
+end
+
+function suite.subdefine_err_reported()
+ local ruleset, msg = lace.compiler.compile(comp_context, "subdefine-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-subdefine-error :: 2", "The second line is where the error happened")
+ assert(line3 == 'allow "Yay" {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)