|
2704 | 2704 | (let ((vi (var-info-for (cadr e) env))) |
2705 | 2705 | (vinfo:set-never-undef! vi #t))) |
2706 | 2706 | ((=) |
2707 | | - (let ((vi (var-info-for (cadr e) env))) |
2708 | | - (if vi |
| 2707 | + (let ((vi (and (symbol? (cadr e)) (var-info-for (cadr e) env)))) |
| 2708 | + (if vi ; if local or captured |
2709 | 2709 | (begin (if (vinfo:asgn vi) |
2710 | 2710 | (vinfo:set-sa! vi #f) |
2711 | 2711 | (vinfo:set-sa! vi #t)) |
@@ -2848,35 +2848,45 @@ f(x) = yt(x) |
2848 | 2848 | ;; when doing this, the original value needs to be preserved, to |
2849 | 2849 | ;; ensure the expression `a=b` always returns exactly `b`. |
2850 | 2850 | (define (convert-assignment var rhs0 fname lam interp) |
2851 | | - (let* ((vi (assq var (car (lam:vinfo lam)))) |
2852 | | - (cv (assq var (cadr (lam:vinfo lam)))) |
2853 | | - (vt (or (and vi (vinfo:type vi)) |
2854 | | - (and cv (vinfo:type cv)) |
2855 | | - '(core Any))) |
2856 | | - (closed (and cv (vinfo:asgn cv) (vinfo:capt cv))) |
2857 | | - (capt (and vi (vinfo:asgn vi) (vinfo:capt vi)))) |
2858 | | - (if (and (not closed) (not capt) (equal? vt '(core Any))) |
2859 | | - `(= ,var ,rhs0) |
2860 | | - (let* ((rhs1 (if (or (ssavalue? rhs0) (simple-atom? rhs0) |
2861 | | - (equal? rhs0 '(the_exception))) |
2862 | | - rhs0 |
2863 | | - (make-ssavalue))) |
2864 | | - (rhs (if (equal? vt '(core Any)) |
2865 | | - rhs1 |
2866 | | - (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f interp)))) |
2867 | | - (ex (cond (closed `(call (core setfield!) |
2868 | | - ,(if interp |
2869 | | - `($ ,var) |
2870 | | - `(call (core getfield) ,fname (inert ,var))) |
2871 | | - (inert contents) |
2872 | | - ,rhs)) |
2873 | | - (capt `(call (core setfield!) ,var (inert contents) ,rhs)) |
2874 | | - (else `(= ,var ,rhs))))) |
2875 | | - (if (eq? rhs1 rhs0) |
2876 | | - `(block ,ex ,rhs0) |
2877 | | - `(block (= ,rhs1 ,rhs0) |
2878 | | - ,ex |
2879 | | - ,rhs1)))))) |
| 2851 | + (cond |
| 2852 | + ((symbol? var) |
| 2853 | + (let* ((vi (assq var (car (lam:vinfo lam)))) |
| 2854 | + (cv (assq var (cadr (lam:vinfo lam)))) |
| 2855 | + (vt (or (and vi (vinfo:type vi)) |
| 2856 | + (and cv (vinfo:type cv)) |
| 2857 | + '(core Any))) |
| 2858 | + (closed (and cv (vinfo:asgn cv) (vinfo:capt cv))) |
| 2859 | + (capt (and vi (vinfo:asgn vi) (vinfo:capt vi)))) |
| 2860 | + (if (and (not closed) (not capt) (equal? vt '(core Any))) |
| 2861 | + `(= ,var ,rhs0) |
| 2862 | + (let* ((rhs1 (if (or (ssavalue? rhs0) (simple-atom? rhs0) |
| 2863 | + (equal? rhs0 '(the_exception))) |
| 2864 | + rhs0 |
| 2865 | + (make-ssavalue))) |
| 2866 | + (rhs (if (equal? vt '(core Any)) |
| 2867 | + rhs1 |
| 2868 | + (convert-for-type-decl rhs1 (cl-convert vt fname lam #f #f interp)))) |
| 2869 | + (ex (cond (closed `(call (core setfield!) |
| 2870 | + ,(if interp |
| 2871 | + `($ ,var) |
| 2872 | + `(call (core getfield) ,fname (inert ,var))) |
| 2873 | + (inert contents) |
| 2874 | + ,rhs)) |
| 2875 | + (capt `(call (core setfield!) ,var (inert contents) ,rhs)) |
| 2876 | + (else `(= ,var ,rhs))))) |
| 2877 | + (if (eq? rhs1 rhs0) |
| 2878 | + `(block ,ex ,rhs0) |
| 2879 | + `(block (= ,rhs1 ,rhs0) |
| 2880 | + ,ex |
| 2881 | + ,rhs1)))))) |
| 2882 | + ((and (pair? var) (or (eq? (car var) 'outerref) |
| 2883 | + (eq? (car var) 'globalref))) |
| 2884 | + |
| 2885 | + `(= ,var ,rhs0)) |
| 2886 | + ((ssavalue? var) |
| 2887 | + `(= ,var ,rhs0)) |
| 2888 | + (else |
| 2889 | + (error (string "invalid assignment location \"" (deparse var) "\""))))) |
2880 | 2890 |
|
2881 | 2891 | ;; replace leading (function) argument type with `typ` |
2882 | 2892 | (define (fix-function-arg-type te typ iskw namemap type-sp) |
@@ -3063,9 +3073,7 @@ f(x) = yt(x) |
3063 | 3073 | ((=) |
3064 | 3074 | (let ((var (cadr e)) |
3065 | 3075 | (rhs (cl-convert (caddr e) fname lam namemap toplevel interp))) |
3066 | | - (if (ssavalue? var) |
3067 | | - `(= ,var ,rhs) |
3068 | | - (convert-assignment var rhs fname lam interp)))) |
| 3076 | + (convert-assignment var rhs fname lam interp))) |
3069 | 3077 | ((local-def) ;; make new Box for local declaration of defined variable |
3070 | 3078 | (let ((vi (assq (cadr e) (car (lam:vinfo lam))))) |
3071 | 3079 | (if (and vi (vinfo:asgn vi) (vinfo:capt vi)) |
@@ -3107,10 +3115,10 @@ f(x) = yt(x) |
3107 | 3115 | (lam2 (if short #f (cadddr e))) |
3108 | 3116 | (vis (if short '(() () ()) (lam:vinfo lam2))) |
3109 | 3117 | (cvs (map car (cadr vis))) |
3110 | | - (local? (lambda (s) (and (symbol? s) |
| 3118 | + (local? (lambda (s) (and lam (symbol? s) |
3111 | 3119 | (or (assq s (car (lam:vinfo lam))) |
3112 | 3120 | (assq s (cadr (lam:vinfo lam))))))) |
3113 | | - (local (and lam (local? name))) |
| 3121 | + (local (local? name)) |
3114 | 3122 | (sig (and (not short) (caddr e))) |
3115 | 3123 | (sp-inits (if (or short (not (eq? (car sig) 'block))) |
3116 | 3124 | '() |
@@ -3187,7 +3195,7 @@ f(x) = yt(x) |
3187 | 3195 | (and (symbol? s) |
3188 | 3196 | (not (eq? name s)) |
3189 | 3197 | (not (memq s capt-sp)) |
3190 | | - (or ;(local? s) ; TODO: make this work for local variables too? |
| 3198 | + (or ;(local? s) ; TODO: error for local variables |
3191 | 3199 | (memq s (lam:sp lam))))))) |
3192 | 3200 | (caddr methdef) |
3193 | 3201 | (lambda (e) (cadr e))))) |
@@ -3313,7 +3321,7 @@ f(x) = yt(x) |
3313 | 3321 | ;; numbered slots (or be simple immediate values), and then those will be the |
3314 | 3322 | ;; only possible returned values. |
3315 | 3323 | (define (compile-body e vi lam) |
3316 | | - (let ((code '()) |
| 3324 | + (let ((code '()) ;; statements (emitted in reverse order) |
3317 | 3325 | (filename 'none) |
3318 | 3326 | (first-line #t) |
3319 | 3327 | (current-loc #f) |
@@ -3615,13 +3623,12 @@ f(x) = yt(x) |
3615 | 3623 | (if (not (and (pair? code) (equal? (car code) e))) |
3616 | 3624 | (emit e) |
3617 | 3625 | #f)) |
3618 | | - ((global) ; remove global declarations |
| 3626 | + ((global) ; keep global declarations as statements |
3619 | 3627 | (if value (error "misplaced \"global\" declaration")) |
3620 | 3628 | (let ((vname (cadr e))) |
3621 | | - (if (var-info-for vname vi) |
3622 | | - ;; issue #7264 |
| 3629 | + (if (var-info-for vname vi) ;; issue #7264 |
3623 | 3630 | (error (string "`global " vname "`: " vname " is local variable in the enclosing scope")) |
3624 | | - #f))) |
| 3631 | + (emit e)))) |
3625 | 3632 | ((local-def) #f) |
3626 | 3633 | ((local) #f) |
3627 | 3634 | ((implicit-global) #f) |
|
0 commit comments