@@ -258,6 +258,84 @@ function expand_for(ctx, ex)
258
258
]
259
259
end
260
260
261
+ function match_try (ex)
262
+ @chk numchildren (ex) > 1 " Invalid `try` form"
263
+ try_ = ex[1 ]
264
+ catch_and_exc = nothing
265
+ exc_var = nothing
266
+ catch_ = nothing
267
+ finally_ = nothing
268
+ else_ = nothing
269
+ for e in ex[2 : end ]
270
+ k = kind (e)
271
+ if k == K " catch" && isnothing (catch_)
272
+ @chk numchildren (e) == 2 " Invalid `catch` form"
273
+ if ! (kind (e[1 ]) == K " Bool" && e[1 ]. value === false )
274
+ # TODO : Fix this strange AST wart upstream?
275
+ exc_var = e[1 ]
276
+ end
277
+ catch_ = e[2 ]
278
+ catch_and_exc = e
279
+ elseif k == K " else" && isnothing (else_)
280
+ @chk numchildren (e) == 1
281
+ else_ = e[1 ]
282
+ elseif k == K " finally" && isnothing (finally_)
283
+ @chk numchildren (e) == 1
284
+ finally_ = e[1 ]
285
+ else
286
+ throw (LoweringError (ex, " Invalid clause in `try` form" ))
287
+ end
288
+ end
289
+ (try_, catch_and_exc, exc_var, catch_, else_, finally_)
290
+ end
291
+
292
+ function expand_try (ctx, ex)
293
+ (try_, catch_and_exc, exc_var, catch_, else_, finally_) = match_try (ex)
294
+
295
+ if ! isnothing (finally_)
296
+ # TODO : check unmatched symbolic gotos in try.
297
+ end
298
+
299
+ try_body = @ast ctx try_ [K " scope_block" (scope_type= :neutral ) try_]
300
+
301
+ if isnothing (catch_)
302
+ try_block = try_body
303
+ else
304
+ if ! isnothing (exc_var) && ! is_identifier_like (exc_var)
305
+ throw (LoweringError (exc_var, " Expected an identifier as exception variable" ))
306
+ end
307
+ try_block = @ast ctx ex [K " trycatchelse"
308
+ try_body
309
+ [K " scope_block" (catch_and_exc, scope_type= :neutral )
310
+ if ! isnothing (exc_var)
311
+ if ! is_identifier_like (exc_var)
312
+ throw (LoweringError (exc_var, " Expected an identifier as exception variable" ))
313
+ end
314
+ [K " block"
315
+ [K " =" (exc_var) exc_var [K " the_exception" ]]
316
+ catch_
317
+ ]
318
+ else
319
+ catch_
320
+ end
321
+ ]
322
+ if ! isnothing (else_)
323
+ [K " scope_block" (else_, scope_type= :neutral ) else_]
324
+ end
325
+ ]
326
+ end
327
+
328
+ # Add finally block
329
+ if isnothing (finally_)
330
+ try_block
331
+ else
332
+ @ast ctx ex [K " tryfinally"
333
+ try_block
334
+ [K " scope_block" (finally_, scope_type= :neutral ) finally_]
335
+ ]
336
+ end
337
+ end
338
+
261
339
# Strip variable type declarations from within a `local` or `global`, returning
262
340
# the stripped expression. Works recursively with complex left hand side
263
341
# assignments containing tuple destructuring. Eg, given
@@ -750,6 +828,8 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
750
828
expand_forms_2 (ctx, children (ex))...
751
829
]
752
830
end
831
+ elseif k == K " try"
832
+ expand_try (ctx, ex)
753
833
elseif k == K " tuple"
754
834
# TODO : named tuples
755
835
expand_forms_2 (ctx, @ast ctx ex [K " call"
0 commit comments