Created
April 22, 2021 09:51
-
-
Save FPGro/7cd5cd0e724ff135de66e5fc1027c129 to your computer and use it in GitHub Desktop.
Catch the monkey
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A more convenient syntax for try/catch clauses. | |
You know that you want it! | |
Instead of the boring old: | |
```julia | |
try | |
foo() | |
catch e | |
bar(e) | |
finally | |
baz() | |
end | |
``` | |
you can now write the far more legible: | |
```julia | |
π£ = foo | |
π₯ = bar | |
π = baz | |
@π begin | |
π | |
π£() | |
π(π₯) | |
π₯(π₯) | |
π | |
π() | |
end | |
``` | |
""" | |
macro π(monkeyexpression::Expr) | |
monkeyexpression.head == :block || error("You have to wrap this in a begin...end block, sorry!") | |
newexpr = Expr(:block) | |
tryblock = Expr(:block) | |
catchme = false | |
catchblock = false | |
finallyblock = nothing | |
state = :start # where are we in the expression | |
for sub in monkeyexpression.args | |
if state == :start | |
if sub isa Symbol && sub == :π | |
state = :try | |
elseif sub isa LineNumberNode | |
push!(newexpr.args, sub) | |
else | |
error("Missing π") | |
end | |
elseif state == :try | |
if sub isa Symbol && sub == :π | |
state = :catch | |
catchblock = Expr(:block) | |
elseif sub isa Expr && sub.args[1] == :π | |
state = :catch | |
catchblock = Expr(:block) | |
if length(sub.args) == 2 | |
catchme = sub.args[2] | |
else | |
error("Can only catch a single error at once, duh!") | |
end | |
elseif sub isa Symbol && sub == :π | |
state = :finally | |
finallyblock = Expr(:block) | |
else | |
push!(tryblock.args, sub) | |
end | |
elseif state == :catch | |
if sub isa Symbol && sub == :π | |
state = :finally | |
finallyblock = Expr(:block) | |
else | |
push!(catchblock.args, sub) | |
end | |
elseif state == :finally | |
push!(finallyblock.args, sub) | |
end | |
end | |
tryexpr = Expr(:try, tryblock, catchme, catchblock) | |
if !isnothing(finallyblock) | |
push!(tryexpr.args, finallyblock) | |
end | |
push!(newexpr.args, tryexpr) | |
return newexpr | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment