Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2542,6 +2542,8 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
# we want to show bad ASTs reasonably to make errors understandable.
lambda_io = IOContext(io, :SOURCE_SLOTNAMES => false)
show_unquoted_expr_fallback(lambda_io, ex, indent, quote_level)
elseif get(io, beginsym, false) && head in (:begin, :end)
print(io, head)
else
unhandled = true
end
Expand Down
10 changes: 4 additions & 6 deletions base/views.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@ replace_ref_begin_end!(ex) = replace_ref_begin_end_!(ex, nothing)[1]
# replace_ref_begin_end_!(ex,withex) returns (new ex, whether withex was used)
function replace_ref_begin_end_!(ex, withex)
used_withex = false
if isa(ex,Symbol)
if ex === :begin
if isa(ex,Expr)
if ex.head === :begin
withex === nothing && error("Invalid use of begin")
return withex[1], true
elseif ex === :end
elseif ex.head === :end
withex === nothing && error("Invalid use of end")
return withex[2], true
end
elseif isa(ex,Expr)
if ex.head === :ref
elseif ex.head === :ref
ex.args[1], used_withex = replace_ref_begin_end_!(ex.args[1], withex)
S = isa(ex.args[1],Symbol) ? ex.args[1]::Symbol : gensym(:S) # temp var to cache ex.args[1] if needed
used_S = false # whether we actually need S
Expand Down
4 changes: 2 additions & 2 deletions deps/JuliaSyntax.version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JULIASYNTAX_BRANCH = main
JULIASYNTAX_SHA1 = 46723f071d5b2efcb21ca6757788028afb91cc13
JULIASYNTAX_BRANCH = mlechu/fix-end-parsing
JULIASYNTAX_SHA1 = 17be4e33b713d4e0f41f5ae3c5abcaef68bd9c90
JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git
JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
45dd003f87f340d4316fa97e920e1c91
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b80b06044dbacef4ca17140ba7fd3e7ca867dfeebae77e972e5287e3ff18d328884c9f6a5377a4e9c65642614a586c38dd91226a079aa60d74db0225f7ef9fa9

This file was deleted.

This file was deleted.

3 changes: 2 additions & 1 deletion src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@

;; identify some expressions that are safe to repeat
(define (effect-free? e)
(or (not (pair? e)) (ssavalue? e) (sym-dot? e) (quoted? e) (memq (car e) '(null true false))))
(or (not (pair? e)) (ssavalue? e) (sym-dot? e) (quoted? e)
(memq (car e) '(null true false begin end))))

;; get the variable name part of a declaration, x::int => x
(define (decl-var v)
Expand Down
8 changes: 6 additions & 2 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
(define space-sensitive #f)
; seeing `for` stops parsing macro arguments and makes a generator
(define for-generator #f)
; treat 'end' like a normal symbol instead of a reserved word
; treat begin/end like special symbols instead of reserved words
(define end-symbol #f)
; treat newline like ordinary whitespace instead of as a potential separator
(define whitespace-newline #f)
Expand Down Expand Up @@ -1624,7 +1624,7 @@
(parse-imports s word))
((do)
(error "invalid \"do\" syntax"))
(else (error "unhandled reserved word")))))))
(else (error (string "unhandled reserved word " word))))))))

(define (parse-do s)
(with-bindings
Expand Down Expand Up @@ -2545,6 +2545,10 @@
(symbol str)))
((eq? t 'true) '(true))
((eq? t 'false) '(false))
;; issue #57269: a[var"begin"] -> 'begin
;; a[begin] -> '(begin)
((and end-symbol (eq? t 'begin)) '(begin))
((and end-symbol (eq? t 'end)) '(end))
(else t)))

;; parens or tuple
Expand Down
10 changes: 6 additions & 4 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@

;; replace `begin` and `end` for the closest ref expression, so doesn't go inside nested refs
(define (replace-beginend ex a n tuples last)
(cond ((eq? ex 'end) (end-val a n tuples last))
((eq? ex 'begin) (begin-val a n tuples last))
(cond ((equal? ex '(begin)) (begin-val a n tuples last))
((equal? ex '(end)) (end-val a n tuples last))
((or (atom? ex) (quoted? ex)) ex)
((eq? (car ex) 'ref)
;; inside ref only replace within the first argument
Expand Down Expand Up @@ -1612,7 +1612,7 @@
(idxs (cddr lhs))
(rhs (caddr e)))
(let* ((reuse (and (pair? a)
(contains (lambda (x) (eq? x 'end))
(contains (lambda (x) (equal? x '(end)))
idxs)))
(arr (if reuse (make-ssavalue) a))
(stmts (if reuse `((= ,arr ,(expand-forms a))) '()))
Expand Down Expand Up @@ -1870,7 +1870,9 @@
(let ((a (cadr e))
(idxs (cddr e)))
(let* ((reuse (and (pair? a)
(contains (lambda (x) (or (eq? x 'begin) (eq? x 'end)))
(contains (lambda (x)
(or (equal? x '(begin))
(equal? x '(end))))
idxs)))
(arr (if reuse (make-ssavalue) a))
(stmts (if reuse `((= ,arr ,a)) '())))
Expand Down
5 changes: 3 additions & 2 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2377,13 +2377,14 @@ end

# begin/end indices
@weak_test_repr "a[begin, end, (begin; end)]"
@test_broken repr(Base.remove_linenums!(:(a[begin, end, (begin; end)]))) == ":(a[begin, end, (begin;\n end)])"
@test repr(Base.remove_linenums!(:(a[begin, end, (begin; end)]))) == ":(a[begin, end, (begin;\n end)])"
@weak_test_repr "a[begin, end, let x=1; (x+1;); end]"
@test_broken repr(Base.remove_linenums!(:(a[begin, end, let x=1; (x+1;); end]))) ==
@test repr(Base.remove_linenums!(:(a[begin, end, let x=1; (x+1;); end]))) ==
":(a[begin, end, let x = 1\n begin\n x + 1\n end\n end])"
@test_repr "a[(bla;)]"
@test_repr "a[(;;)]"
@weak_test_repr "a[x -> f(x)]"
@test_broken @weak_test_repr """:([1,2,3,4][:end === :end ? end : var"end"])"""

@testset "Base.Iterators" begin
@test sprint(show, enumerate("test")) == "enumerate(\"test\")"
Expand Down
10 changes: 10 additions & 0 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4198,6 +4198,16 @@ module Ambig57404
end
@test Ambig57404.S == 1

# #57269
@testset """var"begin"/var"end" in array index""" begin
@test (let var"end" = 1; (1:10)[var"end"]; end) === 1
@test (let var"end" = 1; (1:10)[end]; end) === 10
@test (let var"begin" = 2; (1:10)[2var"begin" + 1]; end) === 5
@test ((1:10)[end === 10 ? end : begin]) === 10
@test_throws ArgumentError (let var"begin" = nothing; (1:10)[var"begin"]; end)
@test (let a=[1]; a[end]::Int = 100; end) === 100
end

# Issue #56904 - lambda linearized twice
@test (let; try 3; finally try 1; f(() -> x); catch x; end; end; x = 7; end) === 7
@test (let; try 3; finally try 4; finally try 1; f(() -> x); catch x; end; end; end; x = 7; end) === 7
Expand Down
Loading