diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 02d1c333404a6..16180129881fd 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -49,7 +49,7 @@ ((not (length> l 8)) (eval `(lambda (x) (not (not (,(if (every symbol? l) 'memq 'memv) x (quote ,l))))))) - ((and (every symbol? l) (not (length> l 20))) + ((and (not (length> l 20)) (every symbol? l)) (eval `(lambda (x) (not (not (memq x (quote ,l))))))) (else diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index ccf566ed87885..cac8c7b5228b9 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -3256,8 +3256,9 @@ ((and (pair? e) (eq? (car e) 'with-static-parameters)) (free-vars- (cadr e) tab)) ((or (atom? e) (quoted? e)) tab) ((eq? (car e) 'lambda) - (let ((bound (lambda-all-vars e))) - (for-each (lambda (v) (if (not (memq v bound)) (put! tab v #t))) + (let ((bound (table))) + (for-each (lambda (b) (put! bound b #t)) (lambda-all-vars e)) + (for-each (lambda (v) (if (not (has? bound v)) (put! tab v #t))) (free-vars (lam:body e)))) tab) (else @@ -3475,13 +3476,13 @@ f(x) = yt(x) (define (convert-lambda lam fname interp capt-sp opaq) (let ((body (add-box-inits-to-body - lam (cl-convert (cadddr lam) fname lam (table) (table) #f interp opaq)))) + lam (cl-convert (cadddr lam) fname lam (table) (table) #f interp opaq (table) (vinfo-to-table (car (lam:vinfo lam))))))) `(lambda ,(lam:args lam) (,(clear-capture-bits (car (lam:vinfo lam))) () ,(caddr (lam:vinfo lam)) ,(delete-duplicates (append (lam:sp lam) capt-sp))) - ,body))) + ,body))) ;; renumber ssavalues assigned in an expr, allowing it to be repeated (define (renumber-assigned-ssavalues e) @@ -3550,10 +3551,10 @@ f(x) = yt(x) ;; declared types. ;; when doing this, the original value needs to be preserved, to ;; ensure the expression `a=b` always returns exactly `b`. -(define (convert-assignment var rhs0 fname lam interp opaq globals) +(define (convert-assignment var rhs0 fname lam interp opaq globals locals) (cond ((symbol? var) - (let* ((vi (assq var (car (lam:vinfo lam)))) + (let* ((vi (get locals var #f)) (cv (assq var (cadr (lam:vinfo lam)))) (vt (or (and vi (vinfo:type vi)) (and cv (vinfo:type cv)) @@ -3568,7 +3569,7 @@ f(x) = yt(x) (equal? rhs0 '(the_exception))) rhs0 (make-ssavalue))) - (rhs (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f #f interp opaq) #t lam)) + (rhs (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f #f interp opaq (table) locals) #t lam)) (ex (cond (closed `(call (core setfield!) ,(if interp `($ ,var) @@ -3687,8 +3688,9 @@ f(x) = yt(x) const atomic null true false ssavalue isdefined toplevel module lambda error gc_preserve_begin gc_preserve_end import using export inline noinline))) -(define (local-in? s lam) - (or (assq s (car (lam:vinfo lam))) +(define (local-in? s lam (tab #f)) + (or (and tab (has? tab s)) + (assq s (car (lam:vinfo lam))) (assq s (cadr (lam:vinfo lam))))) ;; Try to identify never-undef variables, and then clear the `captured` flag for single-assigned, @@ -3843,17 +3845,17 @@ f(x) = yt(x) (define (toplevel-preserving? e) (and (pair? e) (memq (car e) '(if elseif block trycatch tryfinally trycatchelse)))) -(define (map-cl-convert exprs fname lam namemap defined toplevel interp opaq (globals (table))) +(define (map-cl-convert exprs fname lam namemap defined toplevel interp opaq (globals (table)) (locals (table))) (if toplevel (map (lambda (x) (let ((tl (lift-toplevel (cl-convert x fname lam namemap defined (and toplevel (toplevel-preserving? x)) - interp opaq globals)))) + interp opaq globals locals)))) (if (null? (cdr tl)) (car tl) `(block ,@(cdr tl) ,(car tl))))) exprs) - (map (lambda (x) (cl-convert x fname lam namemap defined #f interp opaq globals)) exprs))) + (map (lambda (x) (cl-convert x fname lam namemap defined #f interp opaq globals locals)) exprs))) (define (prepare-lambda! lam) ;; mark all non-arguments as assigned, since locals that are never assigned @@ -3862,11 +3864,11 @@ f(x) = yt(x) (list-tail (car (lam:vinfo lam)) (length (lam:args lam)))) (lambda-optimize-vars! lam)) -(define (cl-convert e fname lam namemap defined toplevel interp opaq (globals (table))) +(define (cl-convert e fname lam namemap defined toplevel interp opaq (globals (table)) (locals (table))) (if (and (not lam) (not (and (pair? e) (memq (car e) '(lambda method macro opaque_closure))))) (if (atom? e) e - (cons (car e) (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals))) + (cons (car e) (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals locals))) (cond ((symbol? e) (define (new-undef-var name) @@ -3885,12 +3887,12 @@ f(x) = yt(x) (val (if (equal? typ '(core Any)) val `(call (core typeassert) ,val - ,(cl-convert typ fname lam namemap defined toplevel interp opaq globals))))) + ,(cl-convert typ fname lam namemap defined toplevel interp opaq globals locals))))) `(block ,@(if (eq? box access) '() `((= ,access ,box))) ,undefcheck ,val))) - (let ((vi (assq e (car (lam:vinfo lam)))) + (let ((vi (get locals e #f)) (cv (assq e (cadr (lam:vinfo lam))))) (cond ((eq? e fname) e) ((memq e (lam:sp lam)) e) @@ -3917,15 +3919,15 @@ f(x) = yt(x) e) ((=) (let ((var (cadr e)) - (rhs (cl-convert (caddr e) fname lam namemap defined toplevel interp opaq globals))) - (convert-assignment var rhs fname lam interp opaq globals))) + (rhs (cl-convert (caddr e) fname lam namemap defined toplevel interp opaq globals locals))) + (convert-assignment var rhs fname lam interp opaq globals locals))) ((local-def) ;; make new Box for local declaration of defined variable - (let ((vi (assq (cadr e) (car (lam:vinfo lam))))) + (let ((vi (get locals (cadr e) #f))) (if (and vi (vinfo:asgn vi) (vinfo:capt vi)) `(= ,(cadr e) (call (core Box))) '(null)))) ((local) ;; convert local declarations to newvar statements - (let ((vi (assq (cadr e) (car (lam:vinfo lam))))) + (let ((vi (get locals (cadr e) #f))) (if (and vi (vinfo:asgn vi) (vinfo:capt vi)) `(= ,(cadr e) (call (core Box))) (if (vinfo:never-undef vi) @@ -3936,12 +3938,12 @@ f(x) = yt(x) e) ((atomic) e) ((const-if-global) - (if (local-in? (cadr e) lam) + (if (local-in? (cadr e) lam locals) '(null) `(const ,(cadr e)))) ((isdefined) ;; convert isdefined expr to function for closure converted variables (let* ((sym (cadr e)) - (vi (and (symbol? sym) (assq sym (car (lam:vinfo lam))))) + (vi (and (symbol? sym) (get locals sym #f))) (cv (and (symbol? sym) (assq sym (cadr (lam:vinfo lam)))))) (cond ((eq? sym fname) e) ((memq sym (lam:sp lam)) e) @@ -3981,13 +3983,13 @@ f(x) = yt(x) (lam2 (if short #f (cadddr e))) (vis (if short '(() () ()) (lam:vinfo lam2))) (cvs (map car (cadr vis))) - (local? (lambda (s) (and lam (symbol? s) (local-in? s lam)))) + (local? (lambda (s) (and lam (symbol? s) (local-in? s lam locals)))) (local (and (not (outerref? (cadr e))) (local? name))) (sig (and (not short) (caddr e))) (sp-inits (if (or short (not (eq? (car sig) 'block))) '() (map-cl-convert (butlast (cdr sig)) - fname lam namemap defined toplevel interp opaq globals))) + fname lam namemap defined toplevel interp opaq globals locals))) (sig (and sig (if (eq? (car sig) 'block) (last sig) sig)))) @@ -4014,10 +4016,11 @@ f(x) = yt(x) ;; anonymous functions with keyword args generate global ;; functions that refer to the type of a local function (rename-sig-types sig namemap) - fname lam namemap defined toplevel interp opaq globals) + fname lam namemap defined toplevel interp opaq globals locals) ,(let ((body (add-box-inits-to-body lam2 - (cl-convert (cadddr lam2) 'anon lam2 (table) (table) #f interp opaq)))) + (cl-convert (cadddr lam2) 'anon lam2 (table) (table) #f interp opaq (table) + (vinfo-to-table (car (lam:vinfo lam2))))))) `(lambda ,(cadr lam2) (,(clear-capture-bits (car vis)) ,@(cdr vis)) @@ -4028,7 +4031,7 @@ f(x) = yt(x) (newlam (compact-and-renumber (linearize (car exprs)) 'none 0))) `(toplevel-butfirst (block ,@sp-inits - (method ,name ,(cl-convert sig fname lam namemap defined toplevel interp opaq globals) + (method ,name ,(cl-convert sig fname lam namemap defined toplevel interp opaq globals locals) ,(julia-bq-macro newlam))) ,@top-stmts)))) @@ -4131,7 +4134,7 @@ f(x) = yt(x) (append (map (lambda (gs tvar) (make-assignment gs `(call (core TypeVar) ',tvar (core Any)))) closure-param-syms closure-param-names) - `((method #f ,(cl-convert arg-defs fname lam namemap defined toplevel interp opaq globals) + `((method #f ,(cl-convert arg-defs fname lam namemap defined toplevel interp opaq globals locals) ,(convert-lambda lam2 (if iskw (caddr (lam:args lam2)) @@ -4170,7 +4173,7 @@ f(x) = yt(x) (begin (put! defined name #t) `(toplevel-butfirst - ,(convert-assignment name mk-closure fname lam interp opaq globals) + ,(convert-assignment name mk-closure fname lam interp opaq globals locals) ,@typedef ,@(map (lambda (v) `(moved-local ,v)) moved-vars) ,@sp-inits @@ -4178,42 +4181,43 @@ f(x) = yt(x) ((lambda) ;; happens inside (thunk ...) and generated function bodies (for-each (lambda (vi) (vinfo:set-asgn! vi #t)) (list-tail (car (lam:vinfo e)) (length (lam:args e)))) + (lambda-optimize-vars! e) (let ((body (map-cl-convert (cdr (lam:body e)) 'anon - (lambda-optimize-vars! e) + e (table) (table) (null? (cadr e)) ;; only toplevel thunks have 0 args - interp opaq globals))) + interp opaq globals (vinfo-to-table (car (lam:vinfo e)))))) `(lambda ,(cadr e) (,(clear-capture-bits (car (lam:vinfo e))) () ,@(cddr (lam:vinfo e))) (block ,@body)))) ;; remaining `::` expressions are type assertions ((|::|) - (cl-convert `(call (core typeassert) ,@(cdr e)) fname lam namemap defined toplevel interp opaq globals)) + (cl-convert `(call (core typeassert) ,@(cdr e)) fname lam namemap defined toplevel interp opaq globals locals)) ;; remaining `decl` expressions are only type assertions if the ;; argument is global or a non-symbol. ((decl) (cond ((and (symbol? (cadr e)) - (local-in? (cadr e) lam)) + (local-in? (cadr e) lam locals)) '(null)) (else (cl-convert - (let ((ref (binding-to-globalref (cadr e)))) - (if ref - (begin - (put! globals ref #t) - `(block - (toplevel-only set_binding_type! ,(cadr e)) - (call (core set_binding_type!) ,(cadr ref) (inert ,(caddr ref)) ,(caddr e)))) - `(call (core typeassert) ,@(cdr e)))) - fname lam namemap defined toplevel interp opaq globals)))) + (let ((ref (binding-to-globalref (cadr e)))) + (if ref + (begin + (put! globals ref #t) + `(block + (toplevel-only set_binding_type! ,(cadr e)) + (call (core set_binding_type!) ,(cadr ref) (inert ,(caddr ref)) ,(caddr e)))) + `(call (core typeassert) ,@(cdr e)))) + fname lam namemap defined toplevel interp opaq globals locals)))) ;; `with-static-parameters` expressions can be removed now; used only by analyze-vars ((with-static-parameters) - (cl-convert (cadr e) fname lam namemap defined toplevel interp opaq globals)) + (cl-convert (cadr e) fname lam namemap defined toplevel interp opaq globals locals)) (else (cons (car e) - (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals)))))))) + (map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals locals)))))))) (define (closure-convert e) (cl-convert e #f #f (table) (table) #f #f #f)) @@ -4257,6 +4261,7 @@ f(x) = yt(x) (current-loc #f) (rett #f) (global-const-error #f) + (vinfo-table (vinfo-to-table (car (lam:vinfo lam)))) (arg-map #f) ;; map arguments to new names if they are assigned (label-counter 0) ;; counter for generating label addresses (label-map (table)) ;; maps label names to generated addresses @@ -4734,7 +4739,7 @@ f(x) = yt(x) ;; avoid duplicate newvar nodes (if (and (not (and (pair? code) (equal? (car code) e))) ;; exclude deleted vars - (assq (cadr e) (car (lam:vinfo lam)))) + (has? vinfo-table (cadr e))) (emit e) #f)) ((global) ; keep global declarations as statements