@@ -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
@@ -2452,11 +2455,11 @@ function parse_import_atsym(ps::ParseState, allow_quotes=true)
2452
2455
end
2453
2456
end
2454
2457
b = peek_behind (ps, pos)
2455
- if warn_parens && b. orig_kind != K ".. "
2458
+ if warn_parens && b. kind != K "dots "
2456
2459
emit_diagnostic (ps, mark, warning= " parentheses are not required here" )
2457
2460
end
2458
2461
ok = (b. is_leaf && (b. kind == K " Identifier" || is_operator (b. kind))) ||
2459
- (! b. is_leaf && b. kind in KSet " $ var" )
2462
+ (! b. is_leaf && ( b. kind in KSet " $ var" || b . kind == K " dots " ) )
2460
2463
if ! ok
2461
2464
emit (ps, mark, K " error" , error= " expected identifier" )
2462
2465
end
@@ -2565,10 +2568,6 @@ function parse_import_path(ps::ParseState)
2565
2568
end
2566
2569
if k == K " ."
2567
2570
bump (ps)
2568
- elseif k == K " .."
2569
- bump_split (ps, (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS))
2570
- elseif k == K " ..."
2571
- bump_split (ps, (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS), (1 ,K " ." ,EMPTY_FLAGS))
2572
2571
else
2573
2572
break
2574
2573
end
@@ -2587,6 +2586,17 @@ function parse_import_path(ps::ParseState)
2587
2586
# import A.⋆.f ==> (import (importpath A ⋆ f))
2588
2587
next_tok = peek_token (ps, 2 )
2589
2588
if is_operator (kind (next_tok))
2589
+ if kind (next_tok) == K " ." && peek (ps, 3 ) == K " ."
2590
+ # Import the .. operator
2591
+ # import A... ==> (import (importpath A (dots-2)))
2592
+ bump_disallowed_space (ps)
2593
+ bump (ps, TRIVIA_FLAG)
2594
+ dotmark = position (ps)
2595
+ bump (ps, TRIVIA_FLAG)
2596
+ bump (ps, TRIVIA_FLAG)
2597
+ emit (ps, dotmark, K " dots" , set_numeric_flags (2 ))
2598
+ continue
2599
+ end
2590
2600
if preceding_whitespace (t)
2591
2601
# Whitespace in import path allowed but discouraged
2592
2602
# import A .== ==> (import (importpath A ==))
@@ -2599,10 +2609,6 @@ function parse_import_path(ps::ParseState)
2599
2609
end
2600
2610
bump (ps, TRIVIA_FLAG)
2601
2611
parse_import_atsym (ps)
2602
- elseif k == K " ..."
2603
- # Import the .. operator
2604
- # import A... ==> (import (importpath A ..))
2605
- bump_split (ps, (1 ,K " ." ,TRIVIA_FLAG), (2 ,K " .." ,EMPTY_FLAGS))
2606
2612
elseif k in KSet " NewlineWs ; , : EndMarker"
2607
2613
# import A; B ==> (import (importpath A))
2608
2614
break
@@ -3472,6 +3478,16 @@ function parse_atom(ps::ParseState, check_identifiers=true, has_unary_prefix=fal
3472
3478
# . ==> (error .)
3473
3479
emit (ps, mark, K " error" , error= " invalid identifier" )
3474
3480
end
3481
+ elseif kind (leading_tok) == K " ." && peek (ps, 2 ) == K " ." && peek (ps, 3 ) == K " ."
3482
+ # ...
3483
+ bump (ps, TRIVIA_FLAG)
3484
+ bump (ps, TRIVIA_FLAG)
3485
+ bump (ps, TRIVIA_FLAG)
3486
+ emit (ps, mark, K " dots" , set_numeric_flags (3 ))
3487
+ if check_identifiers
3488
+ # ... ==> (error ...)
3489
+ emit (ps, mark, K " error" , error= " invalid identifier" )
3490
+ end
3475
3491
elseif is_error (leading_kind)
3476
3492
# Errors for bad tokens are emitted in validate_tokens() rather than
3477
3493
# here.
@@ -3559,9 +3575,9 @@ function parse_atom(ps::ParseState, check_identifiers=true, has_unary_prefix=fal
3559
3575
@label is_operator
3560
3576
# + ==> +
3561
3577
# .+ ==> (. +)
3562
- bump_dotted (ps, leading_dot, emit_dot_node= true , remap_kind=
3578
+ bump_dotted (ps, leading_dot, leading_tok, emit_dot_node= true , remap_kind=
3563
3579
is_syntactic_operator (leading_kind) ? leading_kind : K " Identifier" )
3564
- if check_identifiers && ! is_valid_identifier (leading_kind)
3580
+ if check_identifiers && ! ( is_valid_identifier (leading_kind) || (leading_dot && leading_kind == K " . " ) )
3565
3581
# += ==> (error (op= +))
3566
3582
# ? ==> (error ?)
3567
3583
# .+= ==> (error (. (op= +)))
0 commit comments