diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2015-11-27 16:55:13 +0000 |
---|---|---|
committer | Richard Maw <richard.maw@codethink.co.uk> | 2015-11-27 17:46:53 +0000 |
commit | 7a07b10c07aeb1138467ded79e708c60032eb46f (patch) | |
tree | d30219f1ec63af32c37dac283921e2371e5b8ed3 | |
parent | 3f9cb85510277f04e1f2b384aabc79c9bf46d86d (diff) | |
download | lace-7a07b10c07aeb1138467ded79e708c60032eb46f.tar.gz |
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.lua | 15 | ||||
-rw-r--r-- | lib/lace/compiler.lua | 19 |
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 |