Skip to content

Commit

Permalink
Merge pull request JuliaLang#10331 from JuliaLang/mb/colon-indexing
Browse files Browse the repository at this point in the history
Move Colon translation out of the parser
  • Loading branch information
mbauman committed Jun 12, 2015
2 parents b51ac33 + ca99175 commit 53a222f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 41 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ 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
---------------------------

Expand Down Expand Up @@ -1424,6 +1429,7 @@ 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
Expand Down
15 changes: 14 additions & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,20 @@ 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))
Expand All @@ -364,7 +378,6 @@ 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)
Expand Down
16 changes: 9 additions & 7 deletions doc/manual/arrays.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,10 @@ 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. An arbitrary integer vector, including the empty vector ``[]``
4. A boolean vector
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

The result ``X`` generally has dimensions
``(length(I_1), length(I_2), ..., length(I_n))``, with location
Expand Down Expand Up @@ -286,10 +287,11 @@ The general syntax for assigning values in an n-dimensional array A is::

where each ``I_k`` may be:

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
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

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
Expand Down
41 changes: 8 additions & 33 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -301,18 +301,17 @@
(define (expand-compare-chain e)
(car (expand-vector-compare e)))

;; last = is this last index?
;; 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)
(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))
Expand All @@ -321,8 +320,7 @@
`(call (top trailingsize) ,a ,dimno)
`(call (top size) ,a ,dimno)))))

; replace end inside ex with (call (top size) a n)
; affects only the closest ref expression, so doesn't go inside nested refs
; replace `end` for 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)
Expand All @@ -335,29 +333,7 @@
(map (lambda (x) (replace-end x a n tuples last))
(cdr ex))))))

; 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
;; go through indices and replace the `end` symbol
;; a = array being indexed, i = list of indexes
;; returns (values index-list stmts) where stmts are statements that need
;; to execute first.
Expand Down Expand Up @@ -386,8 +362,7 @@
(cons `(... ,g) ret))))
(loop (cdr lst) (+ n 1)
stmts tuples
(cons (replace-end (expand-index-colon idx) a n tuples last)
ret)))))))
(cons (replace-end idx a n tuples last) ret)))))))

(define (make-decl n t) `(|::| ,n ,t))

Expand Down

0 comments on commit 53a222f

Please sign in to comment.