@@ -371,7 +371,7 @@ function parse_RtoL(ps::ParseState, down, is_op, self)
371
371
down(ps)
372
372
isdot, tk = peek_dotted_op_token(ps)
373
373
if is_op(tk)
374
- bump_dotted (ps, isdot, remap_kind= K " Identifier" )
374
+ bump_dotted(ps, isdot, tk, remap_kind=K"Identifier")
375
375
self(ps)
376
376
emit(ps, mark, isdot ? K"dotcall" : K"call", INFIX_FLAG)
377
377
end
@@ -598,7 +598,7 @@ function parse_assignment_with_initial_ex(ps::ParseState, mark, down::T) where {
598
598
# a .~ b ==> (dotcall-i a ~ b)
599
599
# [a ~ b c] ==> (hcat (call-i a ~ b) c)
600
600
# [a~b] ==> (vect (call-i a ~ b))
601
- bump_dotted (ps, isdot, remap_kind= K " Identifier" )
601
+ bump_dotted(ps, isdot, t, remap_kind=K"Identifier")
602
602
bump_trivia(ps)
603
603
parse_assignment(ps, down)
604
604
emit(ps, mark, isdot ? K"dotcall" : K"call", INFIX_FLAG)
@@ -617,7 +617,7 @@ function parse_assignment_with_initial_ex(ps::ParseState, mark, down::T) where {
617
617
(-1, K"Identifier", EMPTY_FLAGS), # op
618
618
(1, K"=", TRIVIA_FLAG))
619
619
else
620
- bump_dotted (ps, isdot, TRIVIA_FLAG)
620
+ bump_dotted(ps, isdot, t, TRIVIA_FLAG)
621
621
end
622
622
bump_trivia(ps)
623
623
# Syntax Edition TODO: We'd like to call `down` here when
@@ -743,7 +743,7 @@ function parse_arrow(ps::ParseState)
743
743
# x <--> y ==> (call-i x <--> y)
744
744
# x .--> y ==> (dotcall-i x --> y)
745
745
# x -->₁ y ==> (call-i x -->₁ y)
746
- bump_dotted (ps, isdot, remap_kind= K " Identifier" )
746
+ bump_dotted(ps, isdot, t, remap_kind=K"Identifier")
747
747
parse_arrow(ps)
748
748
emit(ps, mark, isdot ? K"dotcall" : K"call", INFIX_FLAG)
749
749
end
@@ -771,7 +771,7 @@ function parse_lazy_cond(ps::ParseState, down, is_op, self)
771
771
(isdot, t) = peek_dotted_op_token(ps)
772
772
k = kind(t)
773
773
if is_op(k)
774
- bump_dotted (ps, isdot, TRIVIA_FLAG)
774
+ bump_dotted(ps, isdot, t, TRIVIA_FLAG)
775
775
self(ps)
776
776
emit(ps, mark, isdot ? dotted(k) : k, flags(t))
777
777
if isdot
@@ -819,7 +819,7 @@ function parse_comparison(ps::ParseState, subtype_comparison=false)
819
819
while ((isdot, t) = peek_dotted_op_token(ps); is_prec_comparison(t))
820
820
n_comparisons += 1
821
821
op_dotted = isdot
822
- op_pos = bump_dotted (ps, isdot, emit_dot_node= true , remap_kind= K " Identifier" )
822
+ op_pos = bump_dotted(ps, isdot, t, emit_dot_node=true, remap_kind=K"Identifier")
823
823
parse_pipe_lt(ps)
824
824
end
825
825
if n_comparisons == 1
@@ -873,15 +873,16 @@ end
873
873
function parse_range(ps::ParseState)
874
874
mark = position(ps)
875
875
parse_invalid_ops(ps)
876
+
876
877
(initial_dot, initial_tok) = peek_dotted_op_token(ps)
877
878
initial_kind = kind(initial_tok)
878
- if initial_kind != K " :" && is_prec_colon (initial_kind)
879
- # a..b ==> (call-i a .. b)
879
+ if initial_kind != K":" && ( is_prec_colon(initial_kind) || (initial_dot && initial_kind == K".") )
880
+ # a..b ==> (call-i a (dots-2) b)
880
881
# a … b ==> (call-i a … b)
881
882
# a .… b ==> (dotcall-i a … b)
882
- bump_dotted (ps, initial_dot, remap_kind= K " Identifier" )
883
+ bump_dotted(ps, initial_dot, initial_tok, remap_kind=K"Identifier")
883
884
parse_invalid_ops(ps)
884
- emit (ps, mark, initial_dot ? K " dotcall" : K " call" , INFIX_FLAG)
885
+ emit(ps, mark, ( initial_dot && initial_kind != K".") ? K"dotcall" : K"call", INFIX_FLAG)
885
886
elseif initial_kind == K":" && ps.range_colon_enabled
886
887
# a ? b : c:d ==> (? a b (call-i c : d))
887
888
n_colons = 0
@@ -948,8 +949,10 @@ function parse_range(ps::ParseState)
948
949
# x... ==> (... x)
949
950
# x:y... ==> (... (call-i x : y))
950
951
# x..y... ==> (... (call-i x .. y)) # flisp parser fails here
951
- if peek (ps) == K " .. ."
952
+ if peek(ps) == K"." && peek(ps, 2) == K"." && peek(ps, 3) == K" ."
952
953
bump(ps, TRIVIA_FLAG)
954
+ bump(ps, TRIVIA_FLAG) # second dot
955
+ bump(ps, TRIVIA_FLAG) # third dot
953
956
emit(ps, mark, K"...")
954
957
end
955
958
end
@@ -965,7 +968,7 @@ function parse_invalid_ops(ps::ParseState)
965
968
parse_expr(ps)
966
969
while ((isdot, t) = peek_dotted_op_token(ps); kind(t) in KSet"ErrorInvalidOperator Error**")
967
970
bump_trivia(ps)
968
- bump_dotted (ps, isdot)
971
+ bump_dotted(ps, isdot, t )
969
972
parse_expr(ps)
970
973
emit(ps, mark, isdot ? K"dotcall" : K"call", INFIX_FLAG)
971
974
end
@@ -1006,7 +1009,7 @@ function parse_with_chains(ps::ParseState, down, is_op, chain_ops)
1006
1009
# [x+y + z] ==> (vect (call-i x + y z))
1007
1010
break
1008
1011
end
1009
- bump_dotted (ps, isdot, remap_kind= K " Identifier" )
1012
+ bump_dotted(ps, isdot, t, remap_kind=K"Identifier")
1010
1013
down(ps)
1011
1014
if kind(t) in chain_ops && !is_suffixed(t) && !isdot
1012
1015
# a + b + c ==> (call-i a + b c)
@@ -1258,7 +1261,7 @@ function parse_unary(ps::ParseState)
1258
1261
#
1259
1262
# (The flisp parser only considers commas before `;` and thus gets this
1260
1263
# last case wrong)
1261
- op_pos = bump_dotted (ps, op_dotted, emit_dot_node= true , remap_kind= K " Identifier" )
1264
+ op_pos = bump_dotted(ps, op_dotted, op_t, emit_dot_node=true, remap_kind=K"Identifier")
1262
1265
1263
1266
space_before_paren = preceding_whitespace(t2)
1264
1267
if space_before_paren
@@ -1352,12 +1355,12 @@ function parse_unary(ps::ParseState)
1352
1355
# -0x1 ==> (call-pre - 0x01)
1353
1356
# - 2 ==> (call-pre - 2)
1354
1357
# .-2 ==> (dotcall-pre - 2)
1355
- op_pos = bump_dotted (ps, op_dotted, remap_kind= K " Identifier" )
1358
+ op_pos = bump_dotted(ps, op_dotted, op_t, remap_kind=K"Identifier")
1356
1359
else
1357
1360
# /x ==> (call-pre (error /) x)
1358
1361
# +₁ x ==> (call-pre (error +₁) x)
1359
1362
# .<: x ==> (dotcall-pre (error (. <:)) x)
1360
- bump_dotted (ps, op_dotted, emit_dot_node= true , remap_kind= K " Identifier" )
1363
+ bump_dotted(ps, op_dotted, op_t, emit_dot_node=true, remap_kind=K"Identifier")
1361
1364
op_pos = emit(ps, mark, K"error", error="not a unary operator")
1362
1365
end
1363
1366
parse_unary(ps)
@@ -1388,7 +1391,7 @@ end
1388
1391
function parse_factor_with_initial_ex(ps::ParseState, mark)
1389
1392
parse_decl_with_initial_ex(ps, mark)
1390
1393
if ((isdot, t) = peek_dotted_op_token(ps); is_prec_power(kind(t)))
1391
- bump_dotted (ps, isdot, remap_kind= K " Identifier" )
1394
+ bump_dotted(ps, isdot, t, remap_kind=K"Identifier")
1392
1395
parse_factor_after(ps)
1393
1396
emit(ps, mark, isdot ? K"dotcall" : K"call", INFIX_FLAG)
1394
1397
end
@@ -2476,11 +2479,11 @@ function parse_import_atsym(ps::ParseState, allow_quotes=true)
2476
2479
end
2477
2480
end
2478
2481
b = peek_behind(ps, pos)
2479
- if warn_parens && b. orig_kind != K ".. "
2482
+ if warn_parens && b.kind != K"dots "
2480
2483
emit_diagnostic(ps, mark, warning="parentheses are not required here")
2481
2484
end
2482
2485
ok = (b.is_leaf && (b.kind == K"Identifier" || is_operator(b.kind))) ||
2483
- (! b. is_leaf && b. kind in KSet " $ var" )
2486
+ (!b.is_leaf && ( b.kind in KSet"$ var" || b.kind == K"dots") )
2484
2487
if !ok
2485
2488
emit(ps, mark, K"error", error="expected identifier")
2486
2489
end
@@ -2589,10 +2592,6 @@ function parse_import_path(ps::ParseState)
2589
2592
end
2590
2593
if k == K"."
2591
2594
bump(ps)
2592
- elseif k == K " .."
2593
- bump_split (ps, (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS))
2594
- elseif k == K " ..."
2595
- bump_split (ps, (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS))
2596
2595
else
2597
2596
break
2598
2597
end
@@ -2611,6 +2610,17 @@ function parse_import_path(ps::ParseState)
2611
2610
# import A.⋆.f ==> (import (importpath A ⋆ f))
2612
2611
next_tok = peek_token(ps, 2)
2613
2612
if is_operator(kind(next_tok))
2613
+ if kind(next_tok) == K"." && peek(ps, 3) == K"."
2614
+ # Import the .. operator
2615
+ # import A... ==> (import (importpath A (dots-2)))
2616
+ bump_disallowed_space(ps)
2617
+ bump(ps, TRIVIA_FLAG)
2618
+ dotmark = position(ps)
2619
+ bump(ps, TRIVIA_FLAG)
2620
+ bump(ps, TRIVIA_FLAG)
2621
+ emit(ps, dotmark, K"dots", set_numeric_flags(2))
2622
+ continue
2623
+ end
2614
2624
if preceding_whitespace(t)
2615
2625
# Whitespace in import path allowed but discouraged
2616
2626
# import A .== ==> (import (importpath A ==))
@@ -2623,10 +2633,6 @@ function parse_import_path(ps::ParseState)
2623
2633
end
2624
2634
bump(ps, TRIVIA_FLAG)
2625
2635
parse_import_atsym(ps)
2626
- elseif k == K " ..."
2627
- # Import the .. operator
2628
- # import A... ==> (import (importpath A ..))
2629
- bump_split (ps, (1 ,K " ." ,TRIVIA_FLAG), (2 ,K " .." ,EMPTY_FLAGS))
2630
2636
elseif k in KSet"NewlineWs ; , : EndMarker"
2631
2637
# import A; B ==> (import (importpath A))
2632
2638
break
@@ -3496,6 +3502,16 @@ function parse_atom(ps::ParseState, check_identifiers=true, has_unary_prefix=fal
3496
3502
# . ==> (error .)
3497
3503
emit(ps, mark, K"error", error="invalid identifier")
3498
3504
end
3505
+ elseif kind(leading_tok) == K"." && peek(ps, 2) == K"." && peek(ps, 3) == K"."
3506
+ # ...
3507
+ bump(ps, TRIVIA_FLAG)
3508
+ bump(ps, TRIVIA_FLAG)
3509
+ bump(ps, TRIVIA_FLAG)
3510
+ emit(ps, mark, K"dots", set_numeric_flags(3))
3511
+ if check_identifiers
3512
+ # ... ==> (error ...)
3513
+ emit(ps, mark, K"error", error="invalid identifier")
3514
+ end
3499
3515
elseif is_error(leading_kind)
3500
3516
# Errors for bad tokens are emitted in validate_tokens() rather than
3501
3517
# here.
@@ -3583,9 +3599,9 @@ function parse_atom(ps::ParseState, check_identifiers=true, has_unary_prefix=fal
3583
3599
@label is_operator
3584
3600
# + ==> +
3585
3601
# .+ ==> (. +)
3586
- bump_dotted (ps, leading_dot, emit_dot_node= true , remap_kind=
3602
+ bump_dotted(ps, leading_dot, leading_tok, emit_dot_node=true, remap_kind=
3587
3603
is_syntactic_operator(leading_kind) ? leading_kind : K"Identifier")
3588
- if check_identifiers && ! is_valid_identifier (leading_kind)
3604
+ if check_identifiers && !( is_valid_identifier(leading_kind) || (leading_dot && leading_kind == K".") )
3589
3605
# += ==> (error (op= +))
3590
3606
# ? ==> (error ?)
3591
3607
# .+= ==> (error (. (op= +)))
0 commit comments