|
3120 | 3120 | (define (free-vars e) |
3121 | 3121 | (table.keys (free-vars- e (table)))) |
3122 | 3122 |
|
3123 | | -(define (analyze-vars-lambda e env captvars sp new-sp (methsig #f)) |
| 3123 | +(define (vinfo-to-table vi) |
| 3124 | + (let ((tab (table))) |
| 3125 | + (for-each (lambda (v) (put! tab (car v) v)) |
| 3126 | + vi) |
| 3127 | + tab)) |
| 3128 | + |
| 3129 | +(define (analyze-vars-lambda e env captvars sp new-sp methsig tab) |
3124 | 3130 | (let* ((args (lam:args e)) |
3125 | 3131 | (locl (caddr e)) |
3126 | 3132 | (allv (nconc (map arg-name args) locl)) |
3127 | 3133 | (fv (let* ((fv (diff (free-vars (lam:body e)) allv)) |
3128 | 3134 | ;; add variables referenced in declared types for free vars |
3129 | 3135 | (dv (apply nconc (map (lambda (v) |
3130 | | - (let ((vi (var-info-for v env))) |
| 3136 | + (let ((vi (get tab v #f))) |
3131 | 3137 | (if vi (free-vars (vinfo:type vi)) '()))) |
3132 | 3138 | fv)))) |
3133 | 3139 | (append (diff dv fv) fv))) |
|
3147 | 3153 | (not (memq (vinfo:name v) new-sp)) |
3148 | 3154 | (not (memq (vinfo:name v) glo)))) |
3149 | 3155 | env) |
3150 | | - (map make-var-info capt-sp)))) |
3151 | | - (analyze-vars (lam:body e) |
3152 | | - (append vi |
| 3156 | + (map make-var-info capt-sp))) |
| 3157 | + (new-env (append vi |
3153 | 3158 | ;; new environment: add our vars |
3154 | 3159 | (filter (lambda (v) |
3155 | 3160 | (and (not (memq (vinfo:name v) allv)) |
3156 | 3161 | (not (memq (vinfo:name v) glo)))) |
3157 | | - env)) |
3158 | | - cv (delete-duplicates (append new-sp sp))) |
| 3162 | + env)))) |
| 3163 | + (analyze-vars (lam:body e) |
| 3164 | + new-env |
| 3165 | + cv (delete-duplicates (append new-sp sp)) |
| 3166 | + (vinfo-to-table new-env)) |
3159 | 3167 | ;; mark all the vars we capture as captured |
3160 | 3168 | (for-each (lambda (v) (vinfo:set-capt! v #t)) |
3161 | 3169 | cv) |
|
3170 | 3178 | ;; in-place to |
3171 | 3179 | ;; (var-info-lst captured-var-infos ssavalues static_params) |
3172 | 3180 | ;; where var-info-lst is a list of var-info records |
3173 | | -(define (analyze-vars e env captvars sp) |
| 3181 | +(define (analyze-vars e env captvars sp tab) |
3174 | 3182 | (if (or (atom? e) (quoted? e)) |
3175 | 3183 | (begin |
3176 | 3184 | (if (symbol? e) |
3177 | | - (let ((vi (var-info-for e env))) |
| 3185 | + (let ((vi (get tab e #f))) |
3178 | 3186 | (if vi |
3179 | 3187 | (vinfo:set-read! vi #t)))) |
3180 | 3188 | e) |
3181 | 3189 | (case (car e) |
3182 | 3190 | ((local-def) ;; a local that we know has an assignment that dominates all usages |
3183 | | - (let ((vi (var-info-for (cadr e) env))) |
| 3191 | + (let ((vi (get tab (cadr e) #f))) |
3184 | 3192 | (vinfo:set-never-undef! vi #t))) |
3185 | 3193 | ((=) |
3186 | | - (let ((vi (and (symbol? (cadr e)) (var-info-for (cadr e) env)))) |
| 3194 | + (let ((vi (and (symbol? (cadr e)) (get tab (cadr e) #f)))) |
3187 | 3195 | (if vi ; if local or captured |
3188 | 3196 | (begin (if (vinfo:asgn vi) |
3189 | 3197 | (vinfo:set-sa! vi #f) |
3190 | 3198 | (vinfo:set-sa! vi #t)) |
3191 | 3199 | (vinfo:set-asgn! vi #t)))) |
3192 | | - (analyze-vars (caddr e) env captvars sp)) |
| 3200 | + (analyze-vars (caddr e) env captvars sp tab)) |
3193 | 3201 | ((call) |
3194 | | - (let ((vi (var-info-for (cadr e) env))) |
| 3202 | + (let ((vi (get tab (cadr e) #f))) |
3195 | 3203 | (if vi |
3196 | 3204 | (vinfo:set-called! vi #t)) |
3197 | | - (for-each (lambda (x) (analyze-vars x env captvars sp)) |
| 3205 | + (for-each (lambda (x) (analyze-vars x env captvars sp tab)) |
3198 | 3206 | (cdr e)))) |
3199 | 3207 | ((decl) |
3200 | 3208 | ;; handle var::T declaration by storing the type in the var-info |
3201 | 3209 | ;; record. for non-symbols or globals, emit a type assertion. |
3202 | | - (let ((vi (var-info-for (cadr e) env))) |
| 3210 | + (let ((vi (get tab (cadr e) #f))) |
3203 | 3211 | (if vi |
3204 | 3212 | (begin (if (not (equal? (vinfo:type vi) '(core Any))) |
3205 | 3213 | (error (string "multiple type declarations for \"" |
|
3209 | 3217 | "\" declared in inner scope"))) |
3210 | 3218 | (vinfo:set-type! vi (caddr e)))))) |
3211 | 3219 | ((lambda) |
3212 | | - (analyze-vars-lambda e env captvars sp '())) |
| 3220 | + (analyze-vars-lambda e env captvars sp '() #f tab)) |
3213 | 3221 | ((with-static-parameters) |
3214 | 3222 | ;; (with-static-parameters func_expr sp_1 sp_2 ...) |
3215 | 3223 | (assert (eq? (car (cadr e)) 'lambda)) |
3216 | 3224 | (analyze-vars-lambda (cadr e) env captvars sp |
3217 | | - (cddr e))) |
| 3225 | + (cddr e) #f tab)) |
3218 | 3226 | ((method) |
3219 | 3227 | (if (length= e 2) |
3220 | | - (let ((vi (var-info-for (method-expr-name e) env))) |
| 3228 | + (let ((vi (get tab (method-expr-name e) #f))) |
3221 | 3229 | (if vi |
3222 | 3230 | (begin (if (vinfo:asgn vi) |
3223 | 3231 | (vinfo:set-sa! vi #f) |
3224 | 3232 | (vinfo:set-sa! vi #t)) |
3225 | 3233 | (vinfo:set-asgn! vi #t))) |
3226 | 3234 | e) |
3227 | | - (begin (analyze-vars (caddr e) env captvars sp) |
| 3235 | + (begin (analyze-vars (caddr e) env captvars sp tab) |
3228 | 3236 | (assert (eq? (car (cadddr e)) 'lambda)) |
3229 | 3237 | (analyze-vars-lambda (cadddr e) env captvars sp |
3230 | 3238 | (method-expr-static-parameters e) |
3231 | | - (caddr e))))) |
| 3239 | + (caddr e) tab)))) |
3232 | 3240 | ((module toplevel) e) |
3233 | | - (else (for-each (lambda (x) (analyze-vars x env captvars sp)) |
| 3241 | + (else (for-each (lambda (x) (analyze-vars x env captvars sp tab)) |
3234 | 3242 | (cdr e)))))) |
3235 | 3243 |
|
3236 | | -(define (analyze-variables! e) (analyze-vars e '() '() '()) e) |
| 3244 | +(define (analyze-variables! e) (analyze-vars e '() '() '() (table)) e) |
3237 | 3245 |
|
3238 | 3246 | ;; pass 4: closure conversion |
3239 | 3247 |
|
|
0 commit comments