summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2015-11-27 16:55:13 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2015-11-27 17:46:53 +0000
commit7a07b10c07aeb1138467ded79e708c60032eb46f (patch)
treed30219f1ec63af32c37dac283921e2371e5b8ed3
parent3f9cb85510277f04e1f2b384aabc79c9bf46d86d (diff)
downloadlace-7a07b10c07aeb1138467ded79e708c60032eb46f.tar.bz2
lace.builtin.define: Record the definition in error words
This wraps the defined function to record the line and word offset that the function was defined at. Because we abuse the define command to define subexpressions, we also have to undo that.
-rw-r--r--lib/lace/builtin.lua15
-rw-r--r--lib/lace/compiler.lua19
2 files changed, 34 insertions, 0 deletions
diff --git a/lib/lace/builtin.lua b/lib/lace/builtin.lua
index 99d5d11..2785389 100644
--- a/lib/lace/builtin.lua
+++ b/lib/lace/builtin.lua
@@ -250,7 +250,22 @@ local function _controlfn(ctx, name)
return cfn
end
+local function wrap_call_definition_location(rule, defn)
+ local fn = defn.fn
+ function defn.fn(...)
+ local res, msg = fn(...)
+ if res == nil then
+ msg = err.offset(msg, 2)
+ msg = err.augment(msg, rule.source, rule.linenr)
+ return nil, msg
+ end
+ return res, msg
+ end
+ return defn
+end
+
local function _do_define(exec_context, rule, name, defn)
+ defn = wrap_call_definition_location(rule, defn)
local res, msg = engine.define(exec_context, name, defn)
if res == nil then
msg = err.augment(msg, rule.source, rule.linenr)
diff --git a/lib/lace/compiler.lua b/lib/lace/compiler.lua
index ec680e6..1c3aa01 100644
--- a/lib/lace/compiler.lua
+++ b/lib/lace/compiler.lua
@@ -82,6 +82,25 @@ local function transfer_args(compcontext, content, rules)
msg.words = {i}
return definerule, msg
end
+
+ -- Fix up error location offset
+ -- The error words are offset by 2 because the "define" token and name,
+ -- but we're abusing the define command for something without those,
+ -- we are responsible for offsetting the errors back.
+ local bindname = definerule.fn
+ function definerule.fn(exec_context, rule, name, defn)
+ local fn = defn.fn
+ function defn.fn(...)
+ local res, msg = fn(...)
+ if res == nil then
+ msg = err.offset(msg, -2)
+ return nil, msg
+ end
+ return res, msg
+ end
+ return bindname(exec_context, rule, name, defn)
+ end
+
args[#args+1] = definename
rules[#rules+1] = definerule
else