Skip to content

Commit

Permalink
add syntax for empty n-dimensional arrays (#41618)
Browse files Browse the repository at this point in the history
  • Loading branch information
simeonschaub authored Jan 11, 2022
1 parent 7a4b43f commit 18b825b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 18 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ New language features
* Mutable struct fields may now be annotated as `const` to prevent changing
them after construction, providing for greater clarity and optimization
ability of these objects ([#43305]).
* Empty n-dimensional arrays can now be created using multiple semicolons inside square brackets, i.e. `[;;;]` creates a 0×0×0 `Array`. ([#41618])

Language changes
----------------
Expand Down
2 changes: 1 addition & 1 deletion src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
((typed_hcat) (string (deparse (cadr e))
(deparse (cons 'hcat (cddr e)))))
((ncat) (string #\[ (deparse-arglist (cddr e) (string (deparse-semicolons (cadr e)) " "))
(if (= (length (cddr e)) 1)
(if (<= (length (cddr e)) 1)
(deparse-semicolons (cadr e))
"") #\]))
((typed_ncat) (string (deparse (cadr e))
Expand Down
50 changes: 33 additions & 17 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2016,24 +2016,40 @@
(where-enabled #t)
(whitespace-newline #f)
(for-generator #t))
(if (eqv? (require-token s) closer)
(begin (take-token s)
'())
(let* ((first (parse-eq* s))
(t (peek-token s)))
(cond ((or (eqv? t #\,) (eqv? t closer))
(parse-vect s first closer))
((eq? t 'for)
(expect-space-before s 'for)
(take-token s)
(parse-comprehension s first closer))
((eqv? t #\newline)
(let ((t (require-token s)))
(cond ((eqv? t closer)
(take-token s)
'())
((eqv? t #\;)
(take-token s)
(define (loop (n 1))
(let ((t (with-whitespace-newline (require-token s))))
(take-token s)
(if (memv (peek-token s) (list #\, closer))
(parse-vect s first closer)
(parse-array s first closer #t last-end-symbol)))
(else
(parse-array s first closer #f last-end-symbol)))))))
(cond ((eqv? t #\;)
(if (ts:space? s)
(error (string "unexpected space inside "
(deparse `(ncat ,n)) " expression")))
(loop (+ n 1)))
((eqv? t closer) `(ncat ,n))
(else (error (string "unexpected \"" t "\" inside "
(deparse `(ncat ,n)) " expression"))))))
(loop))
(else
(let* ((first (parse-eq* s))
(t (peek-token s)))
(cond ((or (eqv? t #\,) (eqv? t closer))
(parse-vect s first closer))
((eq? t 'for)
(expect-space-before s 'for)
(take-token s)
(parse-comprehension s first closer))
((eqv? t #\newline)
(take-token s)
(if (memv (peek-token s) (list #\, closer))
(parse-vect s first closer)
(parse-array s first closer #t last-end-symbol)))
(else
(parse-array s first closer #f last-end-symbol)))))))))

(define (kw-to-= e) (if (kwarg? e) (cons '= (cdr e)) e))
(define (=-to-kw e) (if (assignment? e) (cons 'kw (cdr e)) e))
Expand Down
34 changes: 34 additions & 0 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3088,3 +3088,37 @@ function checkUserAccess(u::User)
return false
end
""")

@testset "empty nd arrays" begin
@test :([]) == Expr(:vect)
@test :([;]) == Expr(:ncat, 1)
@test :([;;]) == Expr(:ncat, 2)
@test :([;;;]) == Expr(:ncat, 3)

@test [] == Array{Any}(undef, 0)
@test [;] == Array{Any}(undef, 0)
@test [;;] == Array{Any}(undef, 0, 0)
@test [;;;] == Array{Any}(undef, 0, 0, 0)

@test :(T[]) == Expr(:ref, :T)
@test :(T[;]) == Expr(:typed_ncat, :T, 1)
@test :(T[;;]) == Expr(:typed_ncat, :T, 2)
@test :(T[;;;]) == Expr(:typed_ncat, :T, 3)

@test Int[] == Array{Int}(undef, 0)
@test Int[;] == Array{Int}(undef, 0)
@test Int[;;] == Array{Int}(undef, 0, 0)
@test Int[;;;] == Array{Int}(undef, 0, 0, 0)

@test :([ ]) == Expr(:vect)
@test :([
]) == Expr(:vect)
@test :([ ;; ]) == Expr(:ncat, 2)
@test :([
;;
]) == Expr(:ncat, 2)

@test_throws ParseError Meta.parse("[; ;]")
@test_throws ParseError Meta.parse("[;; ;]")
@test_throws ParseError Meta.parse("[;\n;]")
end

0 comments on commit 18b825b

Please sign in to comment.