diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 74f2c28ca875f..2ba3cb5a42661 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1296,7 +1296,7 @@ function map!{F}(f::F, dest::AbstractArray, A::AbstractArray) return dest end -function map_to!{T,F}(f::F, offs, st, dest::AbstractArray{T}, A::AbstractArray) +function map_to!{T,F}(f::F, offs, st, dest::AbstractArray{T}, A) # map to dest array, checking the type of each result. if a result does not # match, widen the result type and re-dispatch. i = offs @@ -1318,9 +1318,12 @@ function map_to!{T,F}(f::F, offs, st, dest::AbstractArray{T}, A::AbstractArray) return dest end +_default_eltype(f::Type) = f +_default_eltype(f) = Union{} + function map(f, A::AbstractArray) if isempty(A) - return isa(f,Type) ? similar(A,f) : similar(A) + return similar(A, _default_eltype(f)) end st = start(A) A1, st = next(A, st) @@ -1338,7 +1341,7 @@ function map!{F}(f::F, dest::AbstractArray, A::AbstractArray, B::AbstractArray) return dest end -function map_to!{T,F}(f::F, offs, dest::AbstractArray{T}, A::AbstractArray, B::AbstractArray) +function map_to!{T,F}(f::F, offs, st, dest::AbstractArray{T}, A, B) for i = offs:length(A) @inbounds Ai, Bi = A[i], B[i] el = f(Ai, Bi) @@ -1358,12 +1361,12 @@ end function map(f, A::AbstractArray, B::AbstractArray) shp = promote_shape(size(A),size(B)) if prod(shp) == 0 - return similar(A, promote_type(eltype(A),eltype(B)), shp) + return similar(A, _default_eltype(f), shp) end first = f(A[1], B[1]) dest = similar(A, typeof(first), shp) dest[1] = first - return map_to!(f, 2, dest, A, B) + return map_to!(f, 2, nothing, dest, A, B) end ## N argument @@ -1400,7 +1403,7 @@ end function map(f, As::AbstractArray...) shape = mapreduce(size, promote_shape, As) if prod(shape) == 0 - return similar(As[1], promote_eltype(As...), shape) + return similar(As[1], Union{}, shape) end first = f(map(a->a[1], As)...) dest = similar(As[1], typeof(first), shape) diff --git a/base/array.jl b/base/array.jl index 3454c9e3cb0bb..eaa8e29c9fb67 100644 --- a/base/array.jl +++ b/base/array.jl @@ -387,7 +387,9 @@ end function push!{T}(a::Array{T,1}, item) # convert first so we don't grow the array if the assignment won't work - itemT = convert(T, item) + if T !== Union{} + itemT = convert(T, item) + end ccall(:jl_array_grow_end, Void, (Any, UInt), a, 1) a[end] = itemT return a diff --git a/base/boot.jl b/base/boot.jl index 0317b08a31685..8cd70669170e5 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -341,6 +341,7 @@ unsafe_convert{T}(::Type{T}, x::T) = x (::Type{Array{T}}){T}(m::Int, n::Int, o::Int) = Array{T,3}(m, n, o) # TODO: possibly turn these into deprecations +Array{T,N}(::Type{T}, d::NTuple{N,Int}) = Array{T}(d) Array{T}(::Type{T}, d::Int...) = Array{T}(d) Array{T}(::Type{T}, m::Int) = Array{T,1}(m) Array{T}(::Type{T}, m::Int,n::Int) = Array{T,2}(m,n) diff --git a/base/essentials.jl b/base/essentials.jl index 2afd23a9a00e8..95908eb2bf75e 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -193,3 +193,17 @@ const (:) = Colon() # For passing constants through type inference immutable Val{T} end + +immutable Generator{F,I} + f::F + iter::I +end + +start(g::Generator) = start(g.iter) +done(g::Generator, s) = done(g.iter, s) +function next(g::Generator, s) + v, s2 = next(g.iter, s) + g.f(v), s2 +end + +collect(g::Generator) = map(g.f, g.iter) diff --git a/base/inference.jl b/base/inference.jl index 12b36a5ded01b..f1e6842bf993f 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -25,7 +25,6 @@ type StaticVarInfo gensym_types::Array{Any,1} # types of the GenSym's in this function vinfo::Array{Any,1} # variable properties label_counter::Int # index of the current highest label for this function - fedbackvars::ObjectIdDict mod::Module end @@ -53,7 +52,7 @@ function StaticVarInfo(linfo::LambdaStaticData, ast=linfo.ast) else sp = svec() end - StaticVarInfo(sp, vars, gensym_types, vinflist, nl, ObjectIdDict(), linfo.module) + StaticVarInfo(sp, vars, gensym_types, vinflist, nl, linfo.module) end type VarState @@ -1070,8 +1069,7 @@ function abstract_eval(e::ANY, vtypes, sv::StaticVarInfo) return abstract_eval_constant(e) end e = e::Expr - # handle: - # call null new & static_typeof + # handle: call null new & if is(e.head,:call) t = abstract_eval_call(e, vtypes, sv) elseif is(e.head,:null) @@ -1089,40 +1087,6 @@ function abstract_eval(e::ANY, vtypes, sv::StaticVarInfo) elseif is(e.head,:&) abstract_eval(e.args[1], vtypes, sv) t = Any - elseif is(e.head,:static_typeof) - var = e.args[1] - t = abstract_eval(var, vtypes, sv) - if isa(t,DataType) && typeseq(t,t.name.primary) - # remove unnecessary typevars - t = t.name.primary - end - if is(t,Bottom) - # if we haven't gotten fed-back type info yet, return Bottom. otherwise - # Bottom is the actual type of the variable, so return Type{Bottom}. - if haskey(sv.fedbackvars, var) - t = Type{Bottom} - end - elseif isleaftype(t) - t = Type{t} - elseif isleaftype(inference_stack.types) - if isa(t,TypeVar) - t = Type{t.ub} - else - t = Type{t} - end - else - # if there is any type uncertainty in the arguments, we are - # effectively predicting what static_typeof will say when - # the function is compiled with actual arguments. in that case - # abstract types yield Type{<:T} instead of Type{T}. - # this doesn't really model the situation perfectly, but - # "isleaftype(inference_stack.types)" should be good enough. - if isa(t,TypeVar) - t = Type{t} - else - t = Type{TypeVar(:_,t)} - end - end elseif is(e.head,:method) t = (length(e.args) == 1) ? Any : Void elseif is(e.head,:copyast) @@ -1678,10 +1642,6 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV recpts = IntSet() # statements that depend recursively on our value W = IntSet() - @label typeinf_top - - typegotoredo = false - # exception handlers cur_hand = () handler_at = Any[ () for i=1:n ] @@ -1753,24 +1713,6 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV s[l] = stupdate(s[l], changes, vars) end end - elseif is(hd,:type_goto) - for i = 2:length(stmt.args) - var = stmt.args[i]::GenSym - # Store types that need to be fed back via type_goto - # in gensym_init. After finishing inference, if any - # of these types changed, start over with the fed-back - # types known from the beginning. - # See issue #3821 (using !typeseq instead of !subtype), - # and issue #7810. - id = var.id+1 - vt = gensym_types[id] - ot = gensym_init[id] - if ot===NF || !typeseq(vt,ot) - gensym_init[id] = vt - typegotoredo = true - end - sv.fedbackvars[var] = true - end elseif is(hd,:return) pc´ = n+1 rt = abstract_eval(stmt.args[1], s[pc], sv) @@ -1835,16 +1777,6 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV end end - if typegotoredo - # if any type_gotos changed, clear state and restart. - for ll = 2:length(s) - s[ll] = () - end - empty!(W) - gensym_types[:] = gensym_init - frame.result = curtype - @goto typeinf_top - end for i = 1:length(gensym_types) if gensym_types[i] === NF gensym_types[i] = Union{} @@ -1931,7 +1863,7 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::StaticVarInfo, decls, undefs) e = e::Expr head = e.head - if is(head,:static_typeof) || is(head,:line) || is(head,:const) + if is(head,:line) || is(head,:const) return e #elseif is(head,:gotoifnot) || is(head,:return) # e.typ = Any @@ -2168,9 +2100,6 @@ function effect_free(e::ANY, sv, allow_volatile::Bool) end if isa(e,Expr) e = e::Expr - if e.head === :static_typeof - return true - end ea = e.args if e.head === :call if is_known_call_p(e, is_pure_builtin, sv) diff --git a/base/iterator.jl b/base/iterator.jl index c1873700d47e5..1f59cd2fb626b 100644 --- a/base/iterator.jl +++ b/base/iterator.jl @@ -292,3 +292,55 @@ eltype{I1,I2}(::Type{Prod{I1,I2}}) = tuple_type_cons(eltype(I1), eltype(I2)) x = prod_next(p, st) ((x[1][1],x[1][2]...), x[2]) end + +immutable GeneratorND{F,I<:AbstractProdIterator} + f::F + iter::I + + (::Type{GeneratorND}){F}(f::F, iters...) = (P = product(iters...); new{F,typeof(P)}(f, P)) +end + +start(g::GeneratorND) = start(g.iter) +done(g::GeneratorND, s) = done(g.iter, s) +function next(g::GeneratorND, s) + v, s2 = next(g.iter, s) + g.f(v...), s2 +end + +_size(p::Prod2) = (length(p.a), length(p.b)) +_size(p::Prod) = (length(p.a), _size(p.b)...) + +size(g::GeneratorND) = _size(g.iter) + +function collect(g::GeneratorND) + sz = size(g) + if prod(sz) == 0 + return Array(Union{}, sz) + end + st = start(g.iter) + A1, st = next(g.iter, st) + first = g.f(A1...) + dest = Array(typeof(first), sz) + dest[1] = first + return map_to!(xs->g.f(xs...), 2, st, dest, g.iter) +end + +# special case for 2d +function collect{F,P<:Prod2}(g::GeneratorND{F,P}) + f = g.f + a = g.iter.a + b = g.iter.b + sz = size(g) + if prod(sz) == 0 + return Array(Union{}, sz) + end + fst = f(first(a), first(b)) # TODO: don't recompute this in the loop + dest = Array(typeof(fst), sz) + for j in b + for i in a + val = f(i, j) # TODO: handle type changes + @inbounds dest[i, j] = val + end + end + return dest +end diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 714f92f178d85..90119fa83ed0c 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -2436,8 +2436,8 @@ end function vcat(X::SparseMatrixCSC...) num = length(X) - mX = [ size(x, 1) for x in X ] - nX = [ size(x, 2) for x in X ] + mX = Int[ size(x, 1) for x in X ] + nX = Int[ size(x, 2) for x in X ] m = sum(mX) n = nX[1] @@ -2454,7 +2454,7 @@ function vcat(X::SparseMatrixCSC...) Ti = promote_type(Ti, eltype(X[i].rowval)) end - nnzX = [ nnz(x) for x in X ] + nnzX = Int[ nnz(x) for x in X ] nnz_res = sum(nnzX) colptr = Array(Ti, n + 1) rowval = Array(Ti, nnz_res) @@ -2496,8 +2496,8 @@ end function hcat(X::SparseMatrixCSC...) num = length(X) - mX = [ size(x, 1) for x in X ] - nX = [ size(x, 2) for x in X ] + mX = Int[ size(x, 1) for x in X ] + nX = Int[ size(x, 2) for x in X ] m = mX[1] for i = 2 : num if mX[i] != m; throw(DimensionMismatch("")); end @@ -2508,7 +2508,7 @@ function hcat(X::SparseMatrixCSC...) Ti = promote_type(map(x->eltype(x.rowval), X)...) colptr = Array(Ti, n + 1) - nnzX = [ nnz(x) for x in X ] + nnzX = Int[ nnz(x) for x in X ] nnz_res = sum(nnzX) rowval = Array(Ti, nnz_res) nzval = Array(Tv, nnz_res) @@ -2551,8 +2551,8 @@ Concatenate matrices block-diagonally. Currently only implemented for sparse mat """ function blkdiag(X::SparseMatrixCSC...) num = length(X) - mX = [ size(x, 1) for x in X ] - nX = [ size(x, 2) for x in X ] + mX = Int[ size(x, 1) for x in X ] + nX = Int[ size(x, 2) for x in X ] m = sum(mX) n = sum(nX) @@ -2560,7 +2560,7 @@ function blkdiag(X::SparseMatrixCSC...) Ti = promote_type(map(x->eltype(x.rowval), X)...) colptr = Array(Ti, n + 1) - nnzX = [ nnz(x) for x in X ] + nnzX = Int[ nnz(x) for x in X ] nnz_res = sum(nnzX) rowval = Array(Ti, nnz_res) nzval = Array(Tv, nnz_res) @@ -2761,7 +2761,7 @@ function trace{Tv}(A::SparseMatrixCSC{Tv}) s end -diag(A::SparseMatrixCSC) = [d for d in SpDiagIterator(A)] +diag{Tv}(A::SparseMatrixCSC{Tv}) = Tv[d for d in SpDiagIterator(A)] function diagm{Tv,Ti}(v::SparseMatrixCSC{Tv,Ti}) if (size(v,1) != 1 && size(v,2) != 1) diff --git a/deps/Makefile b/deps/Makefile index 0bc0e25503cea..a709102f0a1e3 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -670,6 +670,7 @@ $(eval $(call LLVM_PATCH,llvm-3.7.1)) else ifeq ($(LLVM_VER),3.7.1) $(eval $(call LLVM_PATCH,llvm-3.7.1)) $(eval $(call LLVM_PATCH,llvm-3.7.1_2)) +$(eval $(call LLVM_PATCH,llvm-3.7.1_3)) $(LLVM_SRC_DIR)/llvm-3.7.1_2.patch-applied: $(LLVM_SRC_DIR)/llvm-3.7.1.patch-applied endif # LLVM_VER diff --git a/deps/llvm-3.7.1_3.patch b/deps/llvm-3.7.1_3.patch new file mode 100644 index 0000000000000..c955da9a0e26b --- /dev/null +++ b/deps/llvm-3.7.1_3.patch @@ -0,0 +1,16 @@ +Index: /lib/Analysis/ScalarEvolutionExpander.cpp +=================================================================== +--- /lib/Analysis/ScalarEvolutionExpander.cpp ++++ /lib/Analysis/ScalarEvolutionExpander.cpp +@@ -1273,6 +1273,11 @@ + if (!SE.dominates(Step, L->getHeader())) { + PostLoopScale = Step; + Step = SE.getConstant(Normalized->getType(), 1); ++ if (!PostLoopOffset) { ++ // otherwise, Start is known to already be a constant zero ++ PostLoopOffset = Start; ++ Start = SE.getConstant(Normalized->getType(), 0); ++ } + Normalized = + cast(SE.getAddRecExpr( + Start, Step, Normalized->getLoop(), diff --git a/doc/requirements.txt b/doc/requirements.txt index e471f48715431..effc1bdd35f6b 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,2 +1,2 @@ --e git+https://github.com/JuliaLang/JuliaDoc.git@85c83a5c4ecd1716e0aa858d73322cc2058bc7b1#egg=JuliaDoc +-e git+https://github.com/JuliaLang/JuliaDoc.git@fe343066983b33e6451c441bbe99a91d97a7e095#egg=JuliaDoc -e git+https://github.com/snide/sphinx_rtd_theme.git@21e875d3a53ce897089ad690d897252f6063349d#egg=sphinx_rtd_theme diff --git a/src/alloc.c b/src/alloc.c index 9861d5e5f003b..d6a8cfe51f8ef 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -87,12 +87,11 @@ jl_sym_t *null_sym; jl_sym_t *body_sym; jl_sym_t *method_sym; jl_sym_t *enter_sym; jl_sym_t *leave_sym; jl_sym_t *exc_sym; jl_sym_t *error_sym; -jl_sym_t *static_typeof_sym; jl_sym_t *new_sym; jl_sym_t *using_sym; jl_sym_t *const_sym; jl_sym_t *thunk_sym; jl_sym_t *anonymous_sym; jl_sym_t *underscore_sym; jl_sym_t *abstracttype_sym; jl_sym_t *bitstype_sym; -jl_sym_t *compositetype_sym; jl_sym_t *type_goto_sym; +jl_sym_t *compositetype_sym; jl_sym_t *global_sym; jl_sym_t *list_sym; jl_sym_t *dot_sym; jl_sym_t *newvar_sym; jl_sym_t *boundscheck_sym; jl_sym_t *inbounds_sym; diff --git a/src/codegen.cpp b/src/codegen.cpp index 0b8df9f16b413..f2637833efb3b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3552,20 +3552,6 @@ static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, b else if (head == null_sym) { return ghostValue(jl_void_type); } - else if (head == static_typeof_sym) { - jl_value_t *extype = expr_type((jl_value_t*)ex, ctx); - if (jl_is_type_type(extype)) { - extype = jl_tparam0(extype); - if (jl_is_typevar(extype)) - extype = ((jl_tvar_t*)extype)->ub; - } - else { - extype = (jl_value_t*)jl_any_type; - } - if (jl_is_tuple_type(extype)) - jl_add_linfo_root(ctx->linfo, extype); - return mark_julia_const(extype); - } else if (head == new_sym) { jl_value_t *ty = expr_type(args[0], ctx); size_t nargs = jl_array_len(ex->args); @@ -3705,7 +3691,7 @@ static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, b return ghostValue(jl_void_type); } // some expression types are metadata and can be ignored - if (valuepos || !(head == line_sym || head == type_goto_sym)) { + if (valuepos || !(head == line_sym)) { if (head == abstracttype_sym || head == compositetype_sym || head == bitstype_sym) { jl_errorf("type definition not allowed inside a local scope"); diff --git a/src/interpreter.c b/src/interpreter.c index d006b5496e250..cb244c198adb9 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -219,9 +219,6 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ng else if (ex->head == exc_sym) { return jl_exception_in_transit; } - else if (ex->head == static_typeof_sym) { - return (jl_value_t*)jl_any_type; - } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(fname)); diff --git a/src/jltypes.c b/src/jltypes.c index c2390c960d0cc..fe66b96213127 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3590,7 +3590,6 @@ void jl_init_types(void) exc_sym = jl_symbol("the_exception"); enter_sym = jl_symbol("enter"); leave_sym = jl_symbol("leave"); - static_typeof_sym = jl_symbol("static_typeof"); new_sym = jl_symbol("new"); const_sym = jl_symbol("const"); global_sym = jl_symbol("global"); @@ -3601,7 +3600,6 @@ void jl_init_types(void) abstracttype_sym = jl_symbol("abstract_type"); bitstype_sym = jl_symbol("bits_type"); compositetype_sym = jl_symbol("composite_type"); - type_goto_sym = jl_symbol("type_goto"); toplevel_sym = jl_symbol("toplevel"); dot_sym = jl_symbol("."); boundscheck_sym = jl_symbol("boundscheck"); diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 9c2430ef69502..2b7eae9dee637 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1397,22 +1397,23 @@ (define (parse-comma-separated-assignments s) (parse-comma-separated s parse-eq*)) +(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"))))) + ; as above, but allows both "i=r" and "i in r" (define (parse-comma-separated-iters s) (let loop ((ranges '())) - (let ((r (parse-eq* s))) - (let ((r (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"))))) - (case (peek-token s) - ((#\,) (take-token s) (loop (cons r ranges))) - (else (reverse! (cons r ranges)))))))) + (let ((r (parse-iteration-spec s))) + (case (peek-token s) + ((#\,) (take-token s) (loop (cons r ranges))) + (else (reverse! (cons r ranges))))))) (define (parse-space-separated-exprs s) (with-space-sensitive @@ -1469,6 +1470,12 @@ (begin (take-token s) (loop (cons nxt lst)))) ((eqv? c #\;) (loop (cons nxt lst))) ((equal? c closer) (loop (cons nxt lst))) + ((eq? c 'for) + (take-token s) + (let ((gen (parse-generator s nxt #f))) + (if (eqv? (require-token s) #\,) + (take-token s)) + (loop (cons gen lst)))) ;; newline character isn't detectable here #;((eqv? c #\newline) (error "unexpected line break in argument list")) @@ -1513,7 +1520,7 @@ (define (parse-comprehension s first closer) (let ((r (parse-comma-separated-iters s))) (if (not (eqv? (require-token s) closer)) - (error (string "expected " closer)) + (error (string "expected \"" closer "\"")) (take-token s)) `(comprehension ,first ,@r))) @@ -1523,6 +1530,12 @@ `(dict_comprehension ,@(cdr c)) (error "invalid dict comprehension")))) +(define (parse-generator s first allow-comma) + (let ((r (if allow-comma + (parse-comma-separated-iters s) + (list (parse-iteration-spec s))))) + `(generator ,first ,@r))) + (define (parse-matrix s first closer gotnewline) (define (fix head v) (cons head (reverse v))) (define (update-outer v outer) @@ -1951,6 +1964,13 @@ `(tuple ,ex) ;; value in parentheses (x) ex)) + ((eq? t 'for) + (take-token s) + (let ((gen (parse-generator s ex #t))) + (if (eqv? (require-token s) #\) ) + (take-token s) + (error "expected \")\"")) + gen)) (else ;; tuple (x,) (x,y) (x...) etc. (if (eqv? t #\, ) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index d8d0005e36121..ed155d122e8e2 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1846,79 +1846,43 @@ (lower-ccall name RT (cdr argtypes) args)))) e)) - 'comprehension + 'generator (lambda (e) - (expand-forms (lower-comprehension #f (cadr e) (cddr e)))) + (let ((expr (cadr e)) + (vars (map cadr (cddr e))) + (ranges (map caddr (cddr e)))) + (let* ((names (map (lambda (v) (if (symbol? v) v (gensy))) vars)) + (stmts (apply append + (map (lambda (v arg) (if (symbol? v) + '() + `((= ,v ,arg)))) + vars names)))) + (expand-forms + (expand-binding-forms + `(call (top ,(if (length> ranges 1) 'GeneratorND 'Generator)) + (-> (tuple ,@names) (block ,@stmts ,expr)) + ,@ranges)))))) + + 'comprehension + (lambda (e) (expand-forms + `(call (top collect) (generator ,(cadr e) ,@(cddr e))))) 'typed_comprehension - (lambda (e) - (expand-forms (lower-comprehension (cadr e) (caddr e) (cdddr e)))) + (lambda (e) (expand-forms + (lower-comprehension (cadr e) (caddr e) (cdddr e)))) 'dict_comprehension - (lambda (e) - (expand-forms (lower-dict-comprehension (cadr e) (cddr e)))) + (lambda (e) (expand-forms + `(call (top Dict) (generator ,(cadr e) ,@(cddr e))))) 'typed_dict_comprehension - (lambda (e) - (expand-forms (lower-typed-dict-comprehension (cadr e) (caddr e) (cdddr e)))))) - -(define (lower-nd-comprehension atype expr ranges) - (let ((result (make-jlgensym)) - (ri (gensy)) - (oneresult (gensy))) - ;; evaluate one expression to figure out type and size - ;; compute just one value by inserting a break inside loops - (define (evaluate-one ranges) - (if (null? ranges) - `(= ,oneresult ,expr) - (if (eq? (car ranges) `:) - (evaluate-one (cdr ranges)) - `(for ,(car ranges) - (block ,(evaluate-one (cdr ranges)) - (break)) )))) - - ;; compute the dimensions of the result - (define (compute-dims ranges oneresult-dim) - (if (null? ranges) - (list) - (if (eq? (car ranges) `:) - (cons `(call (top size) ,oneresult ,oneresult-dim) - (compute-dims (cdr ranges) (+ oneresult-dim 1))) - (cons `(call (top length) ,(caddr (car ranges))) - (compute-dims (cdr ranges) oneresult-dim)) ))) - - ;; construct loops to cycle over all dimensions of an n-d comprehension - (define (construct-loops ranges iters oneresult-dim) - (if (null? ranges) - (if (null? iters) - `(block (call (top setindex!) ,result ,expr ,ri) - (= ,ri (call (top +) ,ri) 1)) - `(block (call (top setindex!) ,result (ref ,expr ,@(reverse iters)) ,ri) - (= ,ri (call (top +) ,ri 1))) ) - (if (eq? (car ranges) `:) - (let ((i (make-jlgensym))) - `(for (= ,i (: 1 (call (top size) ,oneresult ,oneresult-dim))) - ,(construct-loops (cdr ranges) (cons i iters) (+ oneresult-dim 1)) )) - `(for ,(car ranges) - ,(construct-loops (cdr ranges) iters oneresult-dim) )))) - - ;; Evaluate the comprehension - `(scope-block - (block - (local ,oneresult) - ,(evaluate-one ranges) - (= ,result (call (top Array) ,(if atype atype `(call (top eltype) ,oneresult)) - ,@(compute-dims ranges 1))) - (= ,ri 1) - ,(construct-loops (reverse ranges) (list) 1) - ,result )))) + (lambda (e) (expand-forms + `(call (call (top apply_type) (top Dict) ,@(cdr (cadr e))) + (generator ,(caddr e) ,@(cdddr e))))))) (define (lower-comprehension atype expr ranges) - (if (any (lambda (x) (eq? x ':)) ranges) - (lower-nd-comprehension atype expr ranges) (let ((result (make-jlgensym)) (ri (gensy)) - (initlabl (if atype #f (make-jlgensym))) (oneresult (make-jlgensym)) (lengths (map (lambda (x) (make-jlgensym)) ranges)) (states (map (lambda (x) (gensy)) ranges)) @@ -1929,7 +1893,6 @@ (define (construct-loops ranges rv is states lengths) (if (null? ranges) `(block (= ,oneresult ,expr) - ,@(if atype '() `((type_goto ,initlabl ,oneresult))) (inbounds false) (call (top setindex!) ,result ,oneresult ,ri) (inbounds pop) @@ -1955,79 +1918,10 @@ ,.(map (lambda (v r) `(= ,v (call (top length) ,r))) lengths rv) (scope-block (block - ,@(if atype '() `((label ,initlabl))) - (= ,result (call (top Array) - ,(if atype atype `(static_typeof ,oneresult)) - ,@lengths)) + (= ,result (call (top Array) ,atype ,@lengths)) (= ,ri 1) ,(construct-loops (reverse ranges) (reverse rv) is states (reverse lengths)) - ,result)))))) - -(define (lower-dict-comprehension expr ranges) - (let ((result (make-jlgensym)) - (initlabl (make-jlgensym)) - (onekey (make-jlgensym)) - (oneval (make-jlgensym)) - (rv (map (lambda (x) (make-jlgensym)) ranges))) - - ;; construct loops to cycle over all dimensions of an n-d comprehension - (define (construct-loops ranges) - (if (null? ranges) - `(block (= ,onekey ,(cadr expr)) - (= ,oneval ,(caddr expr)) - (type_goto ,initlabl ,onekey ,oneval) - (call (top setindex!) ,result ,oneval ,onekey)) - `(for ,(car ranges) - (block - ;; *** either this or force all for loop vars local - ,.(map (lambda (r) `(local ,r)) - (lhs-vars (cadr (car ranges)))) - ,(construct-loops (cdr ranges)))))) - - ;; Evaluate the comprehension - (let ((loopranges - (map (lambda (r v) `(= ,(cadr r) ,v)) ranges rv))) - `(block - ,.(map (lambda (v r) `(= ,v ,(caddr r))) rv ranges) - (scope-block - (block - #;,@(map (lambda (r) `(local ,r)) - (apply append (map (lambda (r) (lhs-vars (cadr r))) ranges))) - (label ,initlabl) - (= ,result (call (curly (top Dict) - (static_typeof ,onekey) - (static_typeof ,oneval)))) - ,(construct-loops (reverse loopranges)) - ,result)))))) - -(define (lower-typed-dict-comprehension atypes expr ranges) - (if (not (and (length= atypes 3) - (eq? (car atypes) '=>))) - (error "invalid \"typed_dict_comprehension\" syntax") - (let ( (result (make-jlgensym)) - (rs (map (lambda (x) (make-jlgensym)) ranges)) ) - - ;; construct loops to cycle over all dimensions of an n-d comprehension - (define (construct-loops ranges rs) - (if (null? ranges) - `(call (top setindex!) ,result ,(caddr expr) ,(cadr expr)) - `(for (= ,(cadr (car ranges)) ,(car rs)) - (block - ;; *** either this or force all for loop vars local - ,.(map (lambda (r) `(local ,r)) - (lhs-vars (cadr (car ranges)))) - ,(construct-loops (cdr ranges) (cdr rs)))))) - - ;; Evaluate the comprehension - `(block - ,.(map make-assignment rs (map caddr ranges)) - (= ,result (call (curly (top Dict) ,(cadr atypes) ,(caddr atypes)))) - (scope-block - (block - #;,@(map (lambda (r) `(local ,r)) - (apply append (map (lambda (r) (lhs-vars (cadr r))) ranges))) - ,(construct-loops (reverse ranges) (reverse rs)) - ,result)))))) + ,result))))) (define (lhs-vars e) (cond ((symbol? e) (list e)) @@ -3306,12 +3200,6 @@ So far only the second case can actually occur. (let ((l (make-label))) (put! label-map (cadr e) l) (emit `(goto ,l)))))) - ((type_goto) (let((m (get label-map (cadr e) #f))) - (if m - (emit `(type_goto ,m ,@(cddr e))) - (let ((l (make-label))) - (put! label-map (cadr e) l) - (emit `(type_goto ,l ,@(cddr e))))))) ;; exception handlers are lowered using ;; (enter L) - push handler with catch block at label L ;; (leave n) - pop N exception handlers diff --git a/src/julia.h b/src/julia.h index 620724c8606d1..0e0384c4acbd7 100644 --- a/src/julia.h +++ b/src/julia.h @@ -600,11 +600,10 @@ extern jl_sym_t *null_sym; extern jl_sym_t *body_sym; extern jl_sym_t *method_sym; extern jl_sym_t *enter_sym; extern jl_sym_t *leave_sym; extern jl_sym_t *exc_sym; extern jl_sym_t *new_sym; -extern jl_sym_t *static_typeof_sym; extern jl_sym_t *const_sym; extern jl_sym_t *thunk_sym; extern jl_sym_t *anonymous_sym; extern jl_sym_t *underscore_sym; extern jl_sym_t *abstracttype_sym; extern jl_sym_t *bitstype_sym; -extern jl_sym_t *compositetype_sym; extern jl_sym_t *type_goto_sym; +extern jl_sym_t *compositetype_sym; extern jl_sym_t *global_sym; extern jl_sym_t *unused_sym; extern jl_sym_t *boundscheck_sym; extern jl_sym_t *inbounds_sym; extern jl_sym_t *copyast_sym; extern jl_sym_t *fastmath_sym; diff --git a/src/toplevel.c b/src/toplevel.c index 24592a6d17766..3a70ff3920121 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -244,7 +244,6 @@ int jl_has_intrinsics(jl_lambda_info_t *li, jl_expr_t *e, jl_module_t *m) { if (jl_array_len(e->args) == 0) return 0; - if (e->head == static_typeof_sym) return 1; jl_value_t *e0 = jl_exprarg(e,0); if (e->head == call_sym) { jl_value_t *sv = jl_static_eval(e0, NULL, m, li, 0, 0);