Skip to content

Commit 70cb057

Browse files
authored
Use K"?" for head of ternary conditional (#85)
This allows `a ? b : c` syntax to be clearly distinguished from normal `if a b else c end` without reparsing syntax trivia. For compatibility we convert to :if for normal Expr
1 parent 9cc6bfe commit 70cb057

File tree

3 files changed

+23
-19
lines changed

3 files changed

+23
-19
lines changed

src/expr.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ function _to_expr(node::SyntaxNode, iteration_spec=false, need_linenodes=true)
2424
return val
2525
end
2626
end
27-
headstr = untokenize(head(node), include_flag_suff=false)
28-
headsym = !isnothing(headstr) ? Symbol(headstr) :
29-
error("Can't untokenize head of kind $(kind(node))")
27+
if kind(node) == K"?"
28+
headsym = :if
29+
else
30+
headstr = untokenize(head(node), include_flag_suff=false)
31+
headsym = !isnothing(headstr) ? Symbol(headstr) :
32+
error("Can't untokenize head of kind $(kind(node))")
33+
end
3034
node_args = children(node)
3135
insert_linenums = (headsym == :block || headsym == :toplevel) && need_linenodes
3236
args = Vector{Any}(undef, length(node_args)*(insert_linenums ? 2 : 1))

src/parser.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ function parse_pair(ps::ParseState)
602602
end
603603

604604
# Parse short form conditional expression
605-
# a ? b : c ==> (if a b c)
605+
# a ? b : c ==> (? a b c)
606606
#
607607
# flisp: parse-cond
608608
function parse_cond(ps::ParseState)
@@ -613,38 +613,38 @@ function parse_cond(ps::ParseState)
613613
return
614614
end
615615
if !preceding_whitespace(t)
616-
# a? b : c => (if a (error-t) b c)
616+
# a? b : c => (? a (error-t) b c)
617617
bump_invisible(ps, K"error", TRIVIA_FLAG,
618618
error="space required before `?` operator")
619619
end
620620
bump(ps, TRIVIA_FLAG) # ?
621621
t = peek_token(ps)
622622
if !preceding_whitespace(t)
623-
# a ?b : c
623+
# a ?b : c ==> (? a (error-t) b c)
624624
bump_invisible(ps, K"error", TRIVIA_FLAG,
625625
error="space required after `?` operator")
626626
end
627627
parse_eq_star(ParseState(ps, range_colon_enabled=false))
628628
t = peek_token(ps)
629629
if !preceding_whitespace(t)
630-
# a ? b: c ==> (if a [ ] [?] [ ] b (error-t) [:] [ ] c)
630+
# a ? b: c ==> (? a b (error-t) c)
631631
bump_invisible(ps, K"error", TRIVIA_FLAG,
632632
error="space required before `:` in `?` expression")
633633
end
634634
if kind(t) == K":"
635635
bump(ps, TRIVIA_FLAG)
636636
else
637-
# a ? b c ==> (if a b (error) c)
637+
# a ? b c ==> (? a b (error-t) c)
638638
bump_invisible(ps, K"error", TRIVIA_FLAG, error="`:` expected in `?` expression")
639639
end
640640
t = peek_token(ps)
641641
if !preceding_whitespace(t)
642-
# a ? b :c ==> (if a [ ] [?] [ ] b [ ] [:] (error-t) c)
642+
# a ? b :c ==> (? a b (error-t) c)
643643
bump_invisible(ps, K"error", TRIVIA_FLAG,
644644
error="space required after `:` in `?` expression")
645645
end
646646
parse_eq_star(ps)
647-
emit(ps, mark, K"if")
647+
emit(ps, mark, K"?")
648648
end
649649

650650
# Parse arrows. Like parse_RtoL, but specialized for --> syntactic operator

test/parser.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ tests = [
5252
"a => b" => "(call-i a => b)"
5353
],
5454
JuliaSyntax.parse_cond => [
55-
"a ? b : c" => "(if a b c)"
56-
"a ?\nb : c" => "(if a b c)"
57-
"a ? b :\nc" => "(if a b c)"
58-
"a ? b : c:d" => "(if a b (call-i c : d))"
55+
"a ? b : c" => "(? a b c)"
56+
"a ?\nb : c" => "(? a b c)"
57+
"a ? b :\nc" => "(? a b c)"
58+
"a ? b : c:d" => "(? a b (call-i c : d))"
5959
# Following are errors but should recover
60-
"a? b : c" => "(if a (error-t) b c)"
61-
"a ?b : c" => "(if a (error-t) b c)"
62-
"a ? b: c" => "(if a b (error-t) c)"
63-
"a ? b :c" => "(if a b (error-t) c)"
64-
"a ? b c" => "(if a b (error-t) c)"
60+
"a? b : c" => "(? a (error-t) b c)"
61+
"a ?b : c" => "(? a (error-t) b c)"
62+
"a ? b: c" => "(? a b (error-t) c)"
63+
"a ? b :c" => "(? a b (error-t) c)"
64+
"a ? b c" => "(? a b (error-t) c)"
6565
],
6666
JuliaSyntax.parse_arrow => [
6767
"x → y" => "(call-i x → y)"

0 commit comments

Comments
 (0)