@@ -468,28 +468,28 @@ function parse_docstring(ps::ParseState, down=parse_eq)
468
468
mark = position (ps)
469
469
atdoc_mark = bump_invisible (ps, K " TOMBSTONE" )
470
470
down (ps)
471
- if peek_behind (ps). kind in KSet " String string"
471
+ if peek_behind (ps). kind == K " string"
472
472
is_doc = true
473
473
k = peek (ps)
474
474
if is_closing_token (ps, k)
475
- # "notdoc" ] ==> "notdoc"
475
+ # "notdoc" ] ==> (string "notdoc")
476
476
is_doc = false
477
477
elseif k == K " NewlineWs"
478
478
k2 = peek (ps, 2 )
479
479
if is_closing_token (ps, k2) || k2 == K " NewlineWs"
480
- # "notdoc" \n] ==> "notdoc"
481
- # "notdoc" \n\n foo ==> "notdoc"
480
+ # "notdoc" \n] ==> (string "notdoc")
481
+ # "notdoc" \n\n foo ==> (string "notdoc")
482
482
is_doc = false
483
483
else
484
484
# Allow a single newline
485
- # "doc" \n foo ==> (macrocall core_@doc "doc" foo)
485
+ # "doc" \n foo ==> (macrocall core_@doc (string "doc") foo)
486
486
bump (ps, TRIVIA_FLAG) # NewlineWs
487
487
end
488
488
else
489
- # "doc" foo ==> (macrocall core_@doc "doc" foo)
489
+ # "doc" foo ==> (macrocall core_@doc (string "doc") foo)
490
490
# "doc $x" foo ==> (macrocall core_@doc (string "doc " x) foo)
491
491
# Allow docstrings with embedded trailing whitespace trivia
492
- # """\n doc\n """ foo ==> (macrocall core_@doc "doc\n" foo)
492
+ # """\n doc\n """ foo ==> (macrocall core_@doc (string-s "doc\n") foo)
493
493
end
494
494
if is_doc
495
495
reset_node! (ps, atdoc_mark, kind= K " core_@doc" )
@@ -1048,11 +1048,12 @@ function parse_juxtapose(ps::ParseState)
1048
1048
if n_terms == 1
1049
1049
bump_invisible (ps, K " *" )
1050
1050
end
1051
- if prev_kind == K "String " || is_string_delim (t)
1051
+ if prev_kind == K "string " || is_string_delim (t)
1052
1052
# issue #20575
1053
1053
#
1054
- # "a""b" ==> (call-i "a" * (error) "b")
1055
- # "a"x ==> (call-i "a" * (error) x)
1054
+ # "a""b" ==> (call-i (string "a") * (error-t) (string "b"))
1055
+ # "a"x ==> (call-i (string "a") * (error-t) x)
1056
+ # "$y"x ==> (call-i (string (string y)) * (error-t) x)
1056
1057
bump_invisible (ps, K " error" , TRIVIA_FLAG,
1057
1058
error= " cannot juxtapose string literal" )
1058
1059
end
@@ -1389,7 +1390,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1389
1390
# @foo (x) ==> (macrocall @foo x)
1390
1391
# @foo (x,y) ==> (macrocall @foo (tuple x y))
1391
1392
# a().@x y ==> (macrocall (error (. (call a) (quote x))) y)
1392
- # [@foo "x" ] ==> (vect (macrocall @foo "x" ))
1393
+ # [@foo x ] ==> (vect (macrocall @foo x ))
1393
1394
finish_macroname (ps, mark, valid_macroname, macro_name_position)
1394
1395
let ps = with_space_sensitive (ps)
1395
1396
# Space separated macro arguments
@@ -1420,7 +1421,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1420
1421
elseif (ps. space_sensitive && preceding_whitespace (t) &&
1421
1422
k in KSet " ( [ { \ Char \" \"\"\" ` ```" )
1422
1423
# [f (x)] ==> (hcat f x)
1423
- # [f "x" ] ==> (hcat f "x" )
1424
+ # [f x ] ==> (hcat f x )
1424
1425
break
1425
1426
elseif k == K " ("
1426
1427
if is_macrocall
@@ -1597,12 +1598,12 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1597
1598
elseif k in KSet " \" \"\"\" ` ``` " &&
1598
1599
! preceding_whitespace (t) && valid_macroname
1599
1600
# Custom string and command literals
1600
- # x"str" ==> (macrocall @x_str "str")
1601
- # x`str` ==> (macrocall @x_cmd "str")
1602
- # x"" ==> (macrocall @x_str "" )
1603
- # x`` ==> (macrocall @x_cmd "" )
1601
+ # x"str" ==> (macrocall @x_str (string-r "str") )
1602
+ # x`str` ==> (macrocall @x_cmd (cmdstring-r "str") )
1603
+ # x"" ==> (macrocall @x_str (string-r "") )
1604
+ # x`` ==> (macrocall @x_cmd (cmdstring-r "") )
1604
1605
# Triple quoted procesing for custom strings
1605
- # r"""\nx""" ==> (macrocall @r_str "x")
1606
+ # r"""\nx""" ==> (macrocall @r_str (string-sr "x") )
1606
1607
# r"""\n x\n y""" ==> (macrocall @r_str (string-sr "x\n" "y"))
1607
1608
# r"""\n x\\n y""" ==> (macrocall @r_str (string-sr "x\\\n" "y"))
1608
1609
#
@@ -1615,11 +1616,11 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1615
1616
k = kind (t)
1616
1617
if ! preceding_whitespace (t) && (k == K " Identifier" || is_keyword (k) || is_word_operator (k) || is_number (k))
1617
1618
# Macro sufficies can include keywords and numbers
1618
- # x"s"y ==> (macrocall @x_str "s" "y")
1619
- # x"s"end ==> (macrocall @x_str "s" "end")
1620
- # x"s"in ==> (macrocall @x_str "s" "in")
1621
- # x"s"2 ==> (macrocall @x_str "s" 2)
1622
- # x"s"10.0 ==> (macrocall @x_str "s" 10.0)
1619
+ # x"s"y ==> (macrocall @x_str (string-r "s") "y")
1620
+ # x"s"end ==> (macrocall @x_str (string-r "s") "end")
1621
+ # x"s"in ==> (macrocall @x_str (string-r "s") "in")
1622
+ # x"s"2 ==> (macrocall @x_str (string-r "s") 2)
1623
+ # x"s"10.0 ==> (macrocall @x_str (string-r "s") 10.0)
1623
1624
suffix_kind = (k == K " Identifier" || is_keyword (k) ||
1624
1625
is_word_operator (k)) ? K " String" : k
1625
1626
bump (ps, remap_kind= suffix_kind)
@@ -1813,7 +1814,7 @@ function parse_resword(ps::ParseState)
1813
1814
parse_unary_prefix (ps)
1814
1815
end
1815
1816
# module A \n a \n b \n end ==> (module true A (block a b))
1816
- # module A \n "x"\na \n end ==> (module true A (block (core_@doc "x" a)))
1817
+ # module A \n "x"\na \n end ==> (module true A (block (core_@doc (string "x") a)))
1817
1818
parse_block (ps, parse_docstring)
1818
1819
bump_closing_token (ps, K " end" )
1819
1820
emit (ps, mark, K " module" )
@@ -3032,8 +3033,7 @@ function parse_string(ps::ParseState, raw::Bool)
3032
3033
indent_ref_len = typemax (Int)
3033
3034
indent_chunks = acquire_positions (ps. stream)
3034
3035
buf = textbuf (ps)
3035
- str_flags = (triplestr ? TRIPLE_STRING_FLAG : EMPTY_FLAGS) |
3036
- (raw ? RAW_STRING_FLAG : EMPTY_FLAGS)
3036
+ chunk_flags = raw ? RAW_STRING_FLAG : EMPTY_FLAGS
3037
3037
bump (ps, TRIVIA_FLAG)
3038
3038
first_chunk = true
3039
3039
n_valid_chunks = 0
@@ -3048,18 +3048,9 @@ function parse_string(ps::ParseState, raw::Bool)
3048
3048
bump (ps, TRIVIA_FLAG)
3049
3049
k = peek (ps)
3050
3050
if k == K " ("
3051
- # "a $(x + y) b" ==> (string "a " (call-i x + y) " b")
3052
- m = position (ps )
3051
+ # "a $(x + y) b" ==> (string "a " (call-i x + y) " b")
3052
+ # "hi$("ho")" ==> (string "hi" (string "ho") )
3053
3053
parse_atom (ps)
3054
- # https://github.com/JuliaLang/julia/pull/38692
3055
- prev = peek_behind (ps)
3056
- if prev. kind == string_chunk_kind
3057
- # Wrap interpolated literal strings in (string) so we can
3058
- # distinguish them from the surrounding text (issue #38501)
3059
- # "hi$("ho")" ==> (string "hi" (string "ho"))
3060
- # "hi$("""ho""")" ==> (string "hi" (string-s "ho"))
3061
- emit (ps, m, K " string" , prev. flags)
3062
- end
3063
3054
elseif k == K " var"
3064
3055
# var identifiers disabled in strings
3065
3056
# "$var" ==> (string var)
@@ -3087,7 +3078,7 @@ function parse_string(ps::ParseState, raw::Bool)
3087
3078
(s == 2 && (buf[first_byte (t)] == UInt8 (' \r ' ) && b == UInt8 (' \n ' )))
3088
3079
end
3089
3080
# First line of triple string is a newline only: mark as trivia.
3090
- # """\nx""" ==> "x"
3081
+ # """\nx""" ==> (string-s "x")
3091
3082
# """\n\nx""" ==> (string-s "\n" "x")
3092
3083
bump (ps, TRIVIA_FLAG)
3093
3084
first_chunk = false
@@ -3097,6 +3088,7 @@ function parse_string(ps::ParseState, raw::Bool)
3097
3088
# Triple-quoted dedenting:
3098
3089
# Various newlines (\n \r \r\n) and whitespace (' ' \t)
3099
3090
# """\n x\n y""" ==> (string-s "x\n" "y")
3091
+ # ```\n x\n y``` ==> (macrocall :(Core.var"@cmd") (cmdstring-sr "x\n" "y"))
3100
3092
# """\r x\r y""" ==> (string-s "x\n" "y")
3101
3093
# """\r\n x\r\n y""" ==> (string-s "x\n" "y")
3102
3094
# Spaces or tabs or mixtures acceptable
@@ -3158,7 +3150,7 @@ function parse_string(ps::ParseState, raw::Bool)
3158
3150
b = buf[last_byte (t)]
3159
3151
prev_chunk_newline = b == UInt8 (' \n ' ) || b == UInt8 (' \r ' )
3160
3152
end
3161
- bump (ps, str_flags )
3153
+ bump (ps, chunk_flags )
3162
3154
first_chunk = false
3163
3155
n_valid_chunks += 1
3164
3156
end
@@ -3187,36 +3179,37 @@ function parse_string(ps::ParseState, raw::Bool)
3187
3179
if had_end_delim
3188
3180
if n_valid_chunks == 0
3189
3181
# Empty strings, or empty after triple quoted processing
3190
- # "" ==> ""
3191
- # """\n """ ==> ""
3192
- bump_invisible (ps, string_chunk_kind, str_flags )
3182
+ # "" ==> (string "")
3183
+ # """\n """ ==> (string-s "")
3184
+ bump_invisible (ps, string_chunk_kind, chunk_flags )
3193
3185
end
3194
3186
bump (ps, TRIVIA_FLAG)
3195
3187
else
3196
3188
# Missing delimiter recovery
3197
- # "str ==> "str" (error)
3189
+ # "str ==> (string "str" (error-t) )
3198
3190
bump_invisible (ps, K " error" , TRIVIA_FLAG, error= " Unterminated string literal" )
3199
3191
end
3200
- if n_valid_chunks > 1 || had_interpolation
3201
- # String interpolations
3202
- # "$x$y$z" ==> (string x y z)
3203
- # "$(x)" ==> (string x)
3204
- # "$x" ==> (string x)
3205
- # """$x""" ==> (string-s x)
3206
- #
3207
- # Strings with embedded whitespace trivia
3208
- # "a\\\nb" ==> (string "a" "b")
3209
- # "a\\\rb" ==> (string "a" "b")
3210
- # "a\\\r\nb" ==> (string "a" "b")
3211
- # "a\\\n \tb" ==> (string "a" "b")
3212
- emit (ps, mark, K " string" , str_flags)
3213
- else
3214
- # Strings with only a single valid string chunk
3215
- # "str" ==> "str"
3216
- # "a\\\n" ==> "a"
3217
- # "a\\\r" ==> "a"
3218
- # "a\\\r\n" ==> "a"
3219
- end
3192
+ # String interpolations
3193
+ # "$x$y$z" ==> (string x y z)
3194
+ # "$(x)" ==> (string x)
3195
+ # "$x" ==> (string x)
3196
+ # """$x""" ==> (string-s x)
3197
+ #
3198
+ # Strings with embedded whitespace trivia
3199
+ # "a\\\nb" ==> (string "a" "b")
3200
+ # "a\\\rb" ==> (string "a" "b")
3201
+ # "a\\\r\nb" ==> (string "a" "b")
3202
+ # "a\\\n \tb" ==> (string "a" "b")
3203
+ #
3204
+ # Strings with only a single valid string chunk
3205
+ # "str" ==> (string "str")
3206
+ # "a\\\n" ==> (string "a")
3207
+ # "a\\\r" ==> (string "a")
3208
+ # "a\\\r\n" ==> (string "a")
3209
+ string_kind = delim_k in KSet "\" \"\"\" " ? K " string" : K " cmdstring"
3210
+ str_flags = (triplestr ? TRIPLE_STRING_FLAG : EMPTY_FLAGS) |
3211
+ (raw ? RAW_STRING_FLAG : EMPTY_FLAGS)
3212
+ emit (ps, mark, string_kind, str_flags)
3220
3213
end
3221
3214
3222
3215
function emit_braces (ps, mark, ckind, cflags)
@@ -3264,7 +3257,7 @@ function parse_atom(ps::ParseState, check_identifiers=true)
3264
3257
# Heuristic recovery
3265
3258
bump (ps)
3266
3259
else
3267
- # Being inside quote makes keywords into identifiers at at the
3260
+ # Being inside quote makes keywords into identifiers at the
3268
3261
# first level of nesting
3269
3262
# :end ==> (quote end)
3270
3263
# :(end) ==> (quote (error (end)))
@@ -3366,9 +3359,9 @@ function parse_atom(ps::ParseState, check_identifiers=true)
3366
3359
elseif is_string_delim (leading_kind)
3367
3360
parse_string (ps, false )
3368
3361
elseif leading_kind in KSet " ` ```"
3369
- # `` ==> (macrocall core_@cmd "" )
3370
- # `cmd` ==> (macrocall core_@cmd "cmd")
3371
- # ```cmd``` ==> (macrocall core_@cmd "cmd"-s )
3362
+ # `` ==> (macrocall core_@cmd (cmdstring-r "") )
3363
+ # `cmd` ==> (macrocall core_@cmd (cmdstring-r "cmd") )
3364
+ # ```cmd``` ==> (macrocall core_@cmd (cmdstring-sr "cmd") )
3372
3365
bump_invisible (ps, K " core_@cmd" )
3373
3366
parse_string (ps, true )
3374
3367
emit (ps, mark, K " macrocall" )
0 commit comments