diff options
author | chai <chaifix@163.com> | 2021-11-17 23:03:07 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-11-17 23:03:07 +0800 |
commit | 27d6efb5f5a076f825fe2da1875e0cabaf02b4e7 (patch) | |
tree | 44f301110bc2ea742908ed92a78eba0803cd3b60 /Tools/LuaMacro/macro/try.lua | |
parent | b34310c631989551054d456eb47aaab5ded266a4 (diff) |
+ LuaMacro
Diffstat (limited to 'Tools/LuaMacro/macro/try.lua')
-rw-r--r-- | Tools/LuaMacro/macro/try.lua | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/Tools/LuaMacro/macro/try.lua b/Tools/LuaMacro/macro/try.lua new file mode 100644 index 0000000..8e49eb0 --- /dev/null +++ b/Tools/LuaMacro/macro/try.lua @@ -0,0 +1,47 @@ +--- A try/except block. +-- This generates syntactical sugar around `pcal`l, and correctly +-- distinguishes between the try block finishing naturally and +-- explicitly using 'return' with no value. This is handled by +-- converting any no value `return` to `return nil`. +-- +-- Apart from the usual creation of a closure, this uses a table +-- to capture all the results. Not likely to win speed contests, +-- but intended to be correct. +-- @module macro.try + +local M = require 'macro' + +local function pack (...) + local args = {...} + args.n = select('#',...) + return args +end + +function pcall_(fn,...) + return pack(pcall(fn,...)) +end + +local function check_return_value(get,put) + local t,v = get:next() + put:space() + if t=='keyword' and (v=='end' or v=='else' or v=='until') then + put:keyword 'nil' + end + return put(t,v) +end + + +M.define('RR_',M.make_scoped_handler('return',check_return_value)) + + +--- A try macro, paired with except. +-- +-- try +-- maybe_something_bad() +-- except (e) +-- print(e) +-- end +-- @macro try +M.define 'try do local r_ = pcall_(function() RR_ ' +M.define 'except(e) end); if r_[1] then if r_.n > 1 then return unpack(r_,2,r_.n) end else local e = r_[2] _END_END_ ' + |