Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Move Colon translation out of the parser #10331

Merged
merged 2 commits into from
Jun 12, 2015
Merged
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
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 @@ -1422,6 +1427,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 @@ -347,6 +347,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 @@ -368,7 +382,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