Skip to content

Commit

Permalink
Remove TRY_CATCH_FINALLY_FLAG (#123)
Browse files Browse the repository at this point in the history
A flag is a waste for this; we can just use a different kind for this
horrible edge case.
  • Loading branch information
c42f authored Oct 14, 2022
1 parent 5f158b1 commit 384f745
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 15 deletions.
7 changes: 4 additions & 3 deletions src/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,19 @@ function _to_expr(node::SyntaxNode; iteration_spec=false, need_linenodes=true,
pushfirst!(args, args[end])
pop!(args)
end
elseif headsym == :try
elseif headsym in (:try, :try_finally_catch)
# Try children in source order:
# try_block catch_var catch_block else_block finally_block
# Expr ordering:
# try_block catch_var catch_block [finally_block] [else_block]
catch_ = nothing
if has_flags(node, TRY_CATCH_AFTER_FINALLY_FLAG)
if headsym === :try_finally_catch
catch_ = pop!(args)
catch_var = pop!(args)
end
finally_ = pop!(args)
else_ = pop!(args)
if has_flags(node, TRY_CATCH_AFTER_FINALLY_FLAG)
if headsym === :try_finally_catch
pop!(args)
pop!(args)
push!(args, catch_var)
Expand All @@ -176,6 +176,7 @@ function _to_expr(node::SyntaxNode; iteration_spec=false, need_linenodes=true,
if else_ !== false
push!(args, else_)
end
headsym = :try
elseif headsym == :filter
pushfirst!(args, last(args))
pop!(args)
Expand Down
2 changes: 2 additions & 0 deletions src/kinds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,8 @@ const _kind_names =
"flatten"
"comprehension"
"typed_comprehension"
# Special kind for compatibility with the ever-ugly try-finally-catch ordering
"try_finally_catch"
"END_SYNTAX_KINDS"
]

Expand Down
3 changes: 0 additions & 3 deletions src/parse_stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ const DOTOP_FLAG = RawFlags(1<<2)
const TRIPLE_STRING_FLAG = RawFlags(1<<3)
# Set when a string or identifier needs "raw string" unescaping
const RAW_STRING_FLAG = RawFlags(1<<4)
# try-finally-catch
const TRY_CATCH_AFTER_FINALLY_FLAG = RawFlags(1<<5)
# Record whether operator has a suffix
const SUFFIXED_FLAG = RawFlags(1<<6)

Expand Down Expand Up @@ -75,7 +73,6 @@ function untokenize(head::SyntaxHead; unique=true, include_flag_suff=true)
is_infix(head) && (str = str*"i")
has_flags(head, TRIPLE_STRING_FLAG) && (str = str*"s")
has_flags(head, RAW_STRING_FLAG) && (str = str*"r")
has_flags(head, TRY_CATCH_AFTER_FINALLY_FLAG) && (str = str*"f")
is_suffixed(head) && (str = str*"S")
n = numeric_flags(head)
n != 0 && (str = str*string(n))
Expand Down
7 changes: 4 additions & 3 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,7 @@ end
#
# flisp: embedded in parse_resword
function parse_try(ps)
out_kind = K"try"
mark = position(ps)
bump(ps, TRIVIA_FLAG)
parse_block(ps)
Expand Down Expand Up @@ -2132,15 +2133,15 @@ function parse_try(ps)
# in which these blocks execute.
bump_trivia(ps)
if !has_catch && peek(ps) == K"catch"
# try x finally y catch e z end ==> (try-f (block x) false false false (block y) e (block z))
flags |= TRY_CATCH_AFTER_FINALLY_FLAG
# try x finally y catch e z end ==> (try_finally_catch (block x) false false false (block y) e (block z))
out_kind = K"try_finally_catch"
m = position(ps)
parse_catch(ps)
emit_diagnostic(ps, m, position(ps),
warning="`catch` after `finally` will execute out of order")
end
bump_closing_token(ps, K"end")
emit(ps, mark, K"try", flags)
emit(ps, mark, out_kind, flags)
end

function parse_catch(ps::ParseState)
Expand Down
22 changes: 16 additions & 6 deletions test/parser.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
function test_parse(production, code; v=v"1.6")
function test_parse(production, code; v=v"1.6", expr=false)
stream = ParseStream(code, version=v)
production(ParseState(stream))
t = build_tree(GreenNode, stream, wrap_toplevel_as_kind=K"None")
source = SourceFile(code)
s = SyntaxNode(source, t)
if kind(s) == K"None"
join([sprint(show, MIME("text/x.sexpression"), c) for c in children(s)], ' ')
if expr
JuliaSyntax.remove_linenums!(Expr(s))
else
sprint(show, MIME("text/x.sexpression"), s)
if kind(s) == K"None"
join([sprint(show, MIME("text/x.sexpression"), c) for c in children(s)], ' ')
else
sprint(show, MIME("text/x.sexpression"), s)
end
end
end

Expand Down Expand Up @@ -482,7 +486,8 @@ tests = [
((v=v"1.8",), "try else end") => "(try (block) false false (error (block)) false)"
((v=v"1.7",), "try catch ; else end") => "(try (block) false (block) (error (block)) false)"
# finally before catch :-(
"try x finally y catch e z end" => "(try-f (block x) false false false (block y) e (block z))"
"try x finally y catch e z end" => "(try_finally_catch (block x) false false false (block y) e (block z))" =>
Expr(:try, Expr(:block, :x), :e, Expr(:block, :z), Expr(:block, :y))
],
JuliaSyntax.parse_imports => [
"import A as B: x" => "(import (: (error (as (. A) B)) (. x)))"
Expand Down Expand Up @@ -816,7 +821,12 @@ broken_tests = [
else
opts = NamedTuple()
end
@test test_parse(production, input; opts...) == output
if output isa Pair
@test test_parse(production, input; opts...) == output[1]
@test test_parse(production, input; opts..., expr=true) == output[2]
else
@test test_parse(production, input; opts...) == output
end
end
end
@testset "Broken $production" for (production, test_specs) in broken_tests
Expand Down

0 comments on commit 384f745

Please sign in to comment.