diff --git a/NEWS.md b/NEWS.md index 0e615c6b47e7a4..285b617fe3564b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -114,11 +114,6 @@ Language changes macro. Instead, the string is first unindented and then `x_str` is invoked, as if the string had been single-quoted ([#10228]). - * Colons (`:`) within indexing expressions are no longer lowered to the range - `1:end`. Instead, the `:` identifier is passed directly. Custom array types - that implement `getindex` or `setindex!` methods must also extend those - methods to support arguments of type `Colon` ([#10331]). - Command line option changes --------------------------- @@ -1429,7 +1424,6 @@ Too numerous to mention. [#10180]: https://github.com/JuliaLang/julia/issues/10180 [#10228]: https://github.com/JuliaLang/julia/issues/10228 [#10328]: https://github.com/JuliaLang/julia/issues/10328 -[#10331]: https://github.com/JuliaLang/julia/issues/10331 [#10332]: https://github.com/JuliaLang/julia/issues/10332 [#10333]: https://github.com/JuliaLang/julia/issues/10333 [#10380]: https://github.com/JuliaLang/julia/issues/10380 diff --git a/base/array.jl b/base/array.jl index 614dfe5563efa2..72ba29d1254472 100644 --- a/base/array.jl +++ b/base/array.jl @@ -343,20 +343,6 @@ function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int}) end return A end -function setindex!(A::Array, x, ::Colon) - for i in 1:length(A) - @inbounds A[i] = x - end - return A -end -function setindex!(A::Array, X::AbstractArray, ::Colon) - setindex_shape_check(X, length(A)) - i = 0 - for x in X - @inbounds A[i+=1] = x - end - return A -end # Faster contiguous setindex! with copy! setindex!{T}(A::Array{T}, X::Array{T}, I::UnitRange{Int}) = (checkbounds(A, I); unsafe_setindex!(A, X, I)) @@ -378,6 +364,7 @@ function unsafe_setindex!{T}(A::Array{T}, X::Array{T}, ::Colon) return A end + # efficiently grow an array function _growat!(a::Vector, i::Integer, delta::Integer) diff --git a/doc/manual/arrays.rst b/doc/manual/arrays.rst index 2c571e7df46ee0..5a0c79d1a14873 100644 --- a/doc/manual/arrays.rst +++ b/doc/manual/arrays.rst @@ -222,10 +222,9 @@ The general syntax for indexing into an n-dimensional array A is:: where each ``I_k`` may be: 1. A scalar integer -2. A ``Range`` of the form ``a:b``, or ``a:b:c`` -3. A ``:`` or ``Colon()`` to select entire dimensions -4. An arbitrary integer vector, including the empty vector ``[]`` -5. A boolean vector +2. A ``Range`` of the form ``:``, ``a:b``, or ``a:b:c`` +3. An arbitrary integer vector, including the empty vector ``[]`` +4. A boolean vector The result ``X`` generally has dimensions ``(length(I_1), length(I_2), ..., length(I_n))``, with location @@ -287,11 +286,10 @@ The general syntax for assigning values in an n-dimensional array A is:: where each ``I_k`` may be: -1. A scalar integer -2. A ``Range`` of the form ``a:b``, or ``a:b:c`` -3. A ``:`` or ``Colon()`` to select entire dimensions -4. An arbitrary integer vector, including the empty vector ``[]`` -5. A boolean vector +1. A scalar value +2. A ``Range`` of the form ``:``, ``a:b``, or ``a:b:c`` +3. An arbitrary integer vector, including the empty vector ``[]`` +4. A boolean vector If ``X`` is an array, its size must be ``(length(I_1), length(I_2), ..., length(I_n))``, and the value in location ``i_1, i_2, ..., i_n`` of ``A`` is overwritten with diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index d8b97429481c15..2ed890996bdff0 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -301,17 +301,18 @@ (define (expand-compare-chain e) (car (expand-vector-compare e))) -;; return the appropriate computation for an `end` symbol for indexing -;; the array `a` in the `n`th index. -;; `tuples` are a list of the splatted arguments that precede index `n` -;; `last` = is this last index? -;; returns a call to endof(a), trailingsize(a,n), or size(a,n) +;; last = is this last index? (define (end-val a n tuples last) (if (null? tuples) (if last (if (= n 1) `(call (top endof) ,a) `(call (top trailingsize) ,a ,n)) + #;`(call (top div) + (call (top length) ,a) + (call (top *) + ,@(map (lambda (d) `(call (top size) ,a ,(1+ d))) + (iota (- n 1))))) `(call (top size) ,a ,n)) (let ((dimno `(call (top +) ,(- n (length tuples)) ,.(map (lambda (t) `(call (top length) ,t)) @@ -320,7 +321,8 @@ `(call (top trailingsize) ,a ,dimno) `(call (top size) ,a ,dimno))))) -; replace `end` for the closest ref expression, so doesn't go inside nested refs +; replace end inside ex with (call (top size) a n) +; affects only the closest ref expression, so doesn't go inside nested refs (define (replace-end ex a n tuples last) (cond ((eq? ex 'end) (end-val a n tuples last)) ((or (atom? ex) (quoted? ex)) ex) @@ -333,7 +335,29 @@ (map (lambda (x) (replace-end x a n tuples last)) (cdr ex)))))) -;; go through indices and replace the `end` symbol +; translate index x from colons to ranges +(define (expand-index-colon x) + (cond ((eq? x ':) `(call colon 1 end)) + ((and (pair? x) + (eq? (car x) ':)) + (cond ((length= x 3) + (if (eq? (caddr x) ':) + ;; (: a :) a: + `(call colon ,(cadr x) end) + ;; (: a b) + `(call colon ,(cadr x) ,(caddr x)))) + ((length= x 4) + (if (eq? (cadddr x) ':) + ;; (: a b :) a:b: + `(call colon ,(cadr x) ,(caddr x) end) + ;; (: a b c) + `(call colon ,@(cdr x)))) + (else x))) + (else x))) + +;; : inside indexing means 1:end +;; expand end to size(a,n), +;; or div(length(a), prod(size(a)[1:(n-1)])) for the last index ;; a = array being indexed, i = list of indexes ;; returns (values index-list stmts) where stmts are statements that need ;; to execute first. @@ -362,7 +386,8 @@ (cons `(... ,g) ret)))) (loop (cdr lst) (+ n 1) stmts tuples - (cons (replace-end idx a n tuples last) ret))))))) + (cons (replace-end (expand-index-colon idx) a n tuples last) + ret))))))) (define (make-decl n t) `(|::| ,n ,t))