You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.2 KiB
Lua
48 lines
1.2 KiB
Lua
--- 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_ '
|
|
|