3 function try_with_builder(x)
4 local block, handlers = x[1], x[3]
5 local result, exn, endmark =
6 mlp.gensym "_result", mlp.gensym "_exn", mlp.gensym "_endmark"
7 local function parse_exn_handler (x)
8 local exn_test, block = x[1], x[2]
9 return { +{ -{exn_test} <= -{exn} }, block }
11 local catchers = table.flatten (table.map(parse_exn_handler, handlers))
13 table.insert (catchers, { `Call{ `Id "error", exn } } )
14 table.insert (block, `Return{ endmark })
16 local -{endmark} = { }
17 local -{result} = { pcall (function() -{block} end) }
18 if -{result}[1] then -- no exception raised
19 if -{result}[2] ~= -{endmark} then -- user-caused return: propagate it
20 table.remove( -{result}, 1)
21 return unpack( -{result})
23 else -- an error/exception occured
24 local -{exn} = -{result}[2]
29 mlp.block.terminators:add{ "|", "with" }
30 mlp.lexer:add{ "try", "with", "->" }
31 mlp.stat:add{ name="try block",
32 "try", mlp.block, "with",
34 gg.list{ name="exception catchers list",
35 gg.sequence{ name="exception catching case",
36 mlp.expr, "->", mlp.block },
37 separators = "|", terminators = "end" },
39 builder = try_with_builder }