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

fix #9503 plus another proposal on comparison and iteration syntax #15524

Merged
merged 2 commits into from
Mar 18, 2016
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
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Language changes
* A warning is always given when a method is overwritten (previously, this was done only when the new
and old definitions were in separate modules) ([#14759]).

* `A <: B` is parsed as `Expr(:(<:), :A, :B)` in all cases ([#9503]). This also applies to the
`>:` operator.

* Simple 2-argument comparisons like `A < B` are parsed as calls intead of using the
`:comparison` expression type.

Command-line option changes
---------------------------

Expand Down Expand Up @@ -1690,6 +1696,7 @@ Too numerous to mention.
[#9434]: https://github.com/JuliaLang/julia/issues/9434
[#9452]: https://github.com/JuliaLang/julia/issues/9452
[#9487]: https://github.com/JuliaLang/julia/issues/9487
[#9503]: https://github.com/JuliaLang/julia/issues/9503
[#9569]: https://github.com/JuliaLang/julia/issues/9569
[#9575]: https://github.com/JuliaLang/julia/issues/9575
[#9578]: https://github.com/JuliaLang/julia/issues/9578
Expand Down Expand Up @@ -1793,4 +1800,6 @@ Too numerous to mention.
[#14469]: https://github.com/JuliaLang/julia/issues/14469
[#14759]: https://github.com/JuliaLang/julia/issues/14759
[#14798]: https://github.com/JuliaLang/julia/issues/14798
[#15192]: https://github.com/JuliaLang/julia/issues/15192
[#15242]: https://github.com/JuliaLang/julia/issues/15242
[#15258]: https://github.com/JuliaLang/julia/issues/15258
4 changes: 2 additions & 2 deletions base/linalg/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,15 @@ end

function det(C::Cholesky)
dd = one(eltype(C))
for i in 1:size(C.factors,1) dd *= abs2(C.factors[i,i]) end
for i in 1:size(C.factors,1); dd *= abs2(C.factors[i,i]) end
dd
end

det(C::CholeskyPivoted) = C.rank < size(C.factors, 1) ? real(zero(eltype(C))) : prod(abs2(diag(C.factors)))

function logdet(C::Cholesky)
dd = zero(eltype(C))
for i in 1:size(C.factors,1) dd += log(C.factors[i,i]) end
for i in 1:size(C.factors,1); dd += log(C.factors[i,i]) end
dd + dd # instead of 2.0dd which can change the type
end

Expand Down
6 changes: 3 additions & 3 deletions base/linalg/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ function expm!{T<:BlasFloat}(A::StridedMatrix{T})
LAPACK.gesv!(V-U, X)

if s > 0 # squaring to reverse dividing by power of 2
for t=1:si X *= X end
for t=1:si; X *= X end
end
end

Expand All @@ -264,10 +264,10 @@ function expm!{T<:BlasFloat}(A::StridedMatrix{T})
end

if ilo > 1 # apply lower permutations in reverse order
for j in (ilo-1):-1:1 rcswap!(j, Int(scale[j]), X) end
for j in (ilo-1):-1:1; rcswap!(j, Int(scale[j]), X) end
end
if ihi < n # apply upper permutations in forward order
for j in (ihi+1):n rcswap!(j, Int(scale[j]), X) end
for j in (ihi+1):n; rcswap!(j, Int(scale[j]), X) end
end
X
end
Expand Down
2 changes: 1 addition & 1 deletion base/sparse/cholmod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,7 @@ end
function logdet{Tv<:VTypes}(F::Factor{Tv})
f = unsafe_load(get(F.p))
res = zero(Tv)
for d in diag(F) res += log(abs(d)) end
for d in diag(F); res += log(abs(d)) end
f.is_ll!=0 ? 2res : res
end

Expand Down
4 changes: 2 additions & 2 deletions base/sparse/linalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import Base.LinAlg: checksquare

# Convert from 1-based to 0-based indices
function decrement!{T<:Integer}(A::AbstractArray{T})
for i in 1:length(A) A[i] -= one(T) end
for i in 1:length(A); A[i] -= one(T) end
A
end
decrement{T<:Integer}(A::AbstractArray{T}) = decrement!(copy(A))

# Convert from 0-based to 1-based indices
function increment!{T<:Integer}(A::AbstractArray{T})
for i in 1:length(A) A[i] += one(T) end
for i in 1:length(A); A[i] += one(T) end
A
end
increment{T<:Integer}(A::AbstractArray{T}) = increment!(copy(A))
Expand Down
2 changes: 1 addition & 1 deletion base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3084,7 +3084,7 @@ spdiagm(B::AbstractVector, d::Number=0) = spdiagm((B,), (d,))
function expandptr{T<:Integer}(V::Vector{T})
if V[1] != 1 throw(ArgumentError("first index must be one")) end
res = similar(V, (Int64(V[end]-1),))
for i in 1:(length(V)-1), j in V[i]:(V[i+1] - 1) res[j] = i end
for i in 1:(length(V)-1), j in V[i]:(V[i+1] - 1); res[j] = i end
res
end

Expand Down
2 changes: 1 addition & 1 deletion base/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ getindex(s::AbstractString, i::Integer) = s[Int(i)]
getindex{T<:Integer}(s::AbstractString, r::UnitRange{T}) = s[Int(first(r)):Int(last(r))]
# TODO: handle other ranges with stride ±1 specially?
getindex(s::AbstractString, v::AbstractVector) =
sprint(length(v), io->(for i in v write(io,s[i]) end))
sprint(length(v), io->(for i in v; write(io,s[i]) end))

symbol(s::AbstractString) = symbol(bytestring(s))

Expand Down
5 changes: 5 additions & 0 deletions base/test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ Returns a `Pass` `Result` if it does, a `Fail` `Result` if it is
"""
macro test(ex)
orig_ex = Expr(:quote,ex)
# Normalize comparison operator calls to :comparison expressions
if isa(ex, Expr) && ex.head == :call && length(ex.args)==3 &&
Base.operator_precedence(ex.args[1]) == Base.operator_precedence(:(==))
ex = Expr(:comparison, ex.args[2], ex.args[1], ex.args[3])
end
# If the test is a comparison
if isa(ex, Expr) && ex.head == :comparison
# Generate a temporary for every term in the expression
Expand Down
55 changes: 31 additions & 24 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -780,12 +780,21 @@
(let loop ((ex (parse-pipes s))
(first #t))
(let ((t (peek-token s)))
(if (not (is-prec-comparison? t))
ex
(begin (take-token s)
(if first
(loop (list 'comparison ex t (parse-pipes s)) #f)
(loop (append ex (list t (parse-pipes s))) #f)))))))
(cond ((is-prec-comparison? t)
(begin (take-token s)
(if first
(loop (list 'comparison ex t (parse-pipes s)) #f)
(loop (append ex (list t (parse-pipes s))) #f))))
(first ex)
((length= ex 4)
;; only a single comparison; special chained syntax not required
(let ((op (caddr ex))
(arg1 (cadr ex))
(arg2 (cadddr ex)))
(if (or (eq? op '|<:|) (eq? op '|>:|))
`(,op ,arg1 ,arg2)
`(call ,op ,arg1 ,arg2))))
(else ex)))))

(define closing-token?
(let ((closer? (Set '(else elseif catch finally #\, #\) #\] #\} #\;))))
Expand Down Expand Up @@ -905,13 +914,6 @@
(else
ex)))))

;; convert (comparison a <: b) to (<: a b)
(define (subtype-syntax e)
(if (and (pair? e) (eq? (car e) 'comparison)
(length= e 4) (eq? (caddr e) '|<:|))
`(<: ,(cadr e) ,(cadddr e))
e))

(define (parse-unary-prefix s)
(let ((op (peek-token s)))
(if (syntactic-unary-op? op)
Expand Down Expand Up @@ -1031,8 +1033,7 @@
(string (deparse ex) " " (deparse t))
(string (deparse ex) (deparse t))))
(take-token s)
(loop (list* 'curly ex
(map subtype-syntax (parse-arglist s #\} )))))
(loop (list* 'curly ex (parse-arglist s #\} ))))
((#\")
(if (and (symbol? ex) (not (operator? ex))
(not (ts:space? s)))
Expand Down Expand Up @@ -1066,7 +1067,7 @@
" expected \"end\", got \"" t "\""))))))

(define (parse-subtype-spec s)
(subtype-syntax (parse-comparison s)))
(parse-comparison s))

;; parse expressions or blocks introduced by syntactic reserved words
(define (parse-resword s word)
Expand Down Expand Up @@ -1399,14 +1400,20 @@

;; as above, but allows both "i=r" and "i in r"
(define (parse-iteration-spec s)
(let ((r (parse-eq* s)))
(cond ((and (pair? r) (eq? (car r) '=)) r)
((eq? r ':) r)
((and (length= r 4) (eq? (car r) 'comparison)
(or (eq? (caddr r) 'in) (eq? (caddr r) '∈)))
`(= ,(cadr r) ,(cadddr r)))
(else
(error "invalid iteration specification")))))
(let* ((lhs (parse-pipes s))
(t (peek-token s)))
(cond ((memq t '(= in ∈))
(take-token s)
(let* ((rhs (parse-pipes s))
(t (peek-token s)))
#;(if (not (or (closing-token? t) (newline? t)))
;; should be: (error "invalid iteration specification")
(syntax-deprecation s (string "for " (deparse `(= ,lhs ,rhs)) " " t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any test for the deprecated syntax?

(string "for " (deparse `(= ,lhs ,rhs)) "; " t)))
`(= ,lhs ,rhs)))
((and (eq? lhs ':) (closing-token? t))
':)
(else (error "invalid iteration specification")))))

(define (parse-comma-separated-iters s)
(let loop ((ranges '()))
Expand Down
9 changes: 6 additions & 3 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,10 @@
`(call (top next) ,coll ,state))
,body))))))))

;; convert an operator parsed as (op a b) to (call op a b)
(define (syntactic-op-to-call e)
`(call ,(car e) ,(expand-forms (cadr e)) ,(expand-forms (caddr e))))

;; table mapping expression head to a function expanding that form
(define expand-table
(table
Expand Down Expand Up @@ -1518,9 +1522,8 @@
(lambda (e)
`(call (top getfield) ,(expand-forms (cadr e)) ,(expand-forms (caddr e))))

'in
(lambda (e)
`(call in ,(expand-forms (cadr e)) ,(expand-forms (caddr e))))
'|<:| syntactic-op-to-call
'|>:| syntactic-op-to-call

'const expand-const-decl
'local expand-local-or-global-decl
Expand Down
14 changes: 10 additions & 4 deletions test/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ let
("5.≥x", "5.>=x"),
("5.≤x", "5.<=x")]
ex1 = parse(ex1); ex2 = parse(ex2)
@test ex1.head === :comparison && (ex1.head === ex2.head)
@test ex1.args[1] === 5 && ex2.args[1] === 5
@test is(eval(Main, ex1.args[2]), eval(Main, ex2.args[2]))
@test ex1.head === :call && (ex1.head === ex2.head)
@test ex1.args[2] === 5 && ex2.args[2] === 5
@test is(eval(Main, ex1.args[1]), eval(Main, ex2.args[1]))
@test ex1.args[3] === :x && (ex1.args[3] === ex2.args[3])
end
end
Expand Down Expand Up @@ -291,7 +291,7 @@ for T in (UInt8,UInt16,UInt32,UInt64)
@test_throws OverflowError parse(T,string(big(typemax(T))+1))
end

@test parse("1 == 2|>3") == Expr(:comparison, 1, :(==), Expr(:call, :(|>), 2, 3))
@test parse("1 == 2|>3") == Expr(:call, :(==), 1, Expr(:call, :(|>), 2, 3))

# issue #12501 and pr #12502
parse("""
Expand Down Expand Up @@ -365,3 +365,9 @@ let a⊂b = reduce(&, x ∈ b for x in a) && length(b)>length(a)
@test !([1,2] ⊂ [1,3,4])
@test !([1,2] ⊂ [1,2])
end

# issue #9503
@test parse("x<:y") == Expr(:(<:), :x, :y)
@test parse("x>:y") == Expr(:(>:), :x, :y)
@test parse("x<:y<:z").head === :comparison
@test parse("x>:y<:z").head === :comparison