Skip to content

Commit 6d97a8a

Browse files
simeonschaubLilithHafner
authored andcommitted
add syntax for empty n-dimensional arrays (JuliaLang#41618)
1 parent 1d696ba commit 6d97a8a

File tree

4 files changed

+69
-18
lines changed

4 files changed

+69
-18
lines changed

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ New language features
1919
* Mutable struct fields may now be annotated as `const` to prevent changing
2020
them after construction, providing for greater clarity and optimization
2121
ability of these objects ([#43305]).
22+
* Empty n-dimensional arrays can now be created using multiple semicolons inside square brackets, i.e. `[;;;]` creates a 0×0×0 `Array`. ([#41618])
2223

2324
Language changes
2425
----------------

src/ast.scm

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
((typed_hcat) (string (deparse (cadr e))
142142
(deparse (cons 'hcat (cddr e)))))
143143
((ncat) (string #\[ (deparse-arglist (cddr e) (string (deparse-semicolons (cadr e)) " "))
144-
(if (= (length (cddr e)) 1)
144+
(if (<= (length (cddr e)) 1)
145145
(deparse-semicolons (cadr e))
146146
"") #\]))
147147
((typed_ncat) (string (deparse (cadr e))

src/julia-parser.scm

+33-17
Original file line numberDiff line numberDiff line change
@@ -2016,24 +2016,40 @@
20162016
(where-enabled #t)
20172017
(whitespace-newline #f)
20182018
(for-generator #t))
2019-
(if (eqv? (require-token s) closer)
2020-
(begin (take-token s)
2021-
'())
2022-
(let* ((first (parse-eq* s))
2023-
(t (peek-token s)))
2024-
(cond ((or (eqv? t #\,) (eqv? t closer))
2025-
(parse-vect s first closer))
2026-
((eq? t 'for)
2027-
(expect-space-before s 'for)
2028-
(take-token s)
2029-
(parse-comprehension s first closer))
2030-
((eqv? t #\newline)
2019+
(let ((t (require-token s)))
2020+
(cond ((eqv? t closer)
2021+
(take-token s)
2022+
'())
2023+
((eqv? t #\;)
2024+
(take-token s)
2025+
(define (loop (n 1))
2026+
(let ((t (with-whitespace-newline (require-token s))))
20312027
(take-token s)
2032-
(if (memv (peek-token s) (list #\, closer))
2033-
(parse-vect s first closer)
2034-
(parse-array s first closer #t last-end-symbol)))
2035-
(else
2036-
(parse-array s first closer #f last-end-symbol)))))))
2028+
(cond ((eqv? t #\;)
2029+
(if (ts:space? s)
2030+
(error (string "unexpected space inside "
2031+
(deparse `(ncat ,n)) " expression")))
2032+
(loop (+ n 1)))
2033+
((eqv? t closer) `(ncat ,n))
2034+
(else (error (string "unexpected \"" t "\" inside "
2035+
(deparse `(ncat ,n)) " expression"))))))
2036+
(loop))
2037+
(else
2038+
(let* ((first (parse-eq* s))
2039+
(t (peek-token s)))
2040+
(cond ((or (eqv? t #\,) (eqv? t closer))
2041+
(parse-vect s first closer))
2042+
((eq? t 'for)
2043+
(expect-space-before s 'for)
2044+
(take-token s)
2045+
(parse-comprehension s first closer))
2046+
((eqv? t #\newline)
2047+
(take-token s)
2048+
(if (memv (peek-token s) (list #\, closer))
2049+
(parse-vect s first closer)
2050+
(parse-array s first closer #t last-end-symbol)))
2051+
(else
2052+
(parse-array s first closer #f last-end-symbol)))))))))
20372053

20382054
(define (kw-to-= e) (if (kwarg? e) (cons '= (cdr e)) e))
20392055
(define (=-to-kw e) (if (assignment? e) (cons 'kw (cdr e)) e))

test/syntax.jl

+34
Original file line numberDiff line numberDiff line change
@@ -3088,3 +3088,37 @@ function checkUserAccess(u::User)
30883088
return false
30893089
end
30903090
""")
3091+
3092+
@testset "empty nd arrays" begin
3093+
@test :([]) == Expr(:vect)
3094+
@test :([;]) == Expr(:ncat, 1)
3095+
@test :([;;]) == Expr(:ncat, 2)
3096+
@test :([;;;]) == Expr(:ncat, 3)
3097+
3098+
@test [] == Array{Any}(undef, 0)
3099+
@test [;] == Array{Any}(undef, 0)
3100+
@test [;;] == Array{Any}(undef, 0, 0)
3101+
@test [;;;] == Array{Any}(undef, 0, 0, 0)
3102+
3103+
@test :(T[]) == Expr(:ref, :T)
3104+
@test :(T[;]) == Expr(:typed_ncat, :T, 1)
3105+
@test :(T[;;]) == Expr(:typed_ncat, :T, 2)
3106+
@test :(T[;;;]) == Expr(:typed_ncat, :T, 3)
3107+
3108+
@test Int[] == Array{Int}(undef, 0)
3109+
@test Int[;] == Array{Int}(undef, 0)
3110+
@test Int[;;] == Array{Int}(undef, 0, 0)
3111+
@test Int[;;;] == Array{Int}(undef, 0, 0, 0)
3112+
3113+
@test :([ ]) == Expr(:vect)
3114+
@test :([
3115+
]) == Expr(:vect)
3116+
@test :([ ;; ]) == Expr(:ncat, 2)
3117+
@test :([
3118+
;;
3119+
]) == Expr(:ncat, 2)
3120+
3121+
@test_throws ParseError Meta.parse("[; ;]")
3122+
@test_throws ParseError Meta.parse("[;; ;]")
3123+
@test_throws ParseError Meta.parse("[;\n;]")
3124+
end

0 commit comments

Comments
 (0)