|
377 | 377 | (let ((parent-scope (cons (list env m) parent-scope))
|
378 | 378 | (body (cadr e))
|
379 | 379 | (m (caddr e)))
|
380 |
| - (resolve-expansion-vars-with-new-env body env m parent-scope inarg))) |
| 380 | + (resolve-expansion-vars-with-new-env body env m parent-scope inarg #t))) |
381 | 381 |
|
382 | 382 | ;; todo: trycatch
|
383 | 383 | (else
|
|
407 | 407 | (and (eq? (car e) '=) (length= e 3)
|
408 | 408 | (eventually-call? (cadr e))))))
|
409 | 409 |
|
| 410 | +;; count hygienic / escape pairs |
| 411 | +;; and fold together a list resulting from applying the function to |
| 412 | +;; and block at the same hygienic scope |
| 413 | +(define (resume-on-escape lam e nblocks) |
| 414 | + (if (or (not (pair? e)) (quoted? e)) |
| 415 | + '() |
| 416 | + (cond ((memq (car e) '(lambda module toplevel)) |
| 417 | + '()) |
| 418 | + ((eq? (car e) 'hygienic-scope) |
| 419 | + (resume-on-escape lam (cadr e) (+ nblocks 1))) |
| 420 | + ((eq? (car e) 'escape) |
| 421 | + (if (= nblocks 0) |
| 422 | + (lam (cadr e)) |
| 423 | + (resume-on-escape lam (cadr e) (- nblocks 1)))) |
| 424 | + (else |
| 425 | + (foldl (lambda (a l) (append! l (resume-on-escape lam a nblocks))) |
| 426 | + '() |
| 427 | + (cdr e)))))) |
| 428 | + |
410 | 429 | (define (find-declared-vars-in-expansion e decl (outer #t))
|
411 | 430 | (cond ((or (not (pair? e)) (quoted? e)) '())
|
412 | 431 | ((eq? (car e) 'escape) '())
|
413 |
| - ((eq? (car e) 'hygienic-scope) '()) |
| 432 | + ((eq? (car e) 'hygienic-scope) |
| 433 | + (resume-on-escape (lambda (e) (find-declared-vars-in-expansion e decl outer)) (cadr e) 0)) |
414 | 434 | ((eq? (car e) decl) (map decl-var* (cdr e)))
|
415 | 435 | ((and (not outer) (function-def? e)) '())
|
416 | 436 | (else
|
|
421 | 441 | (define (find-assigned-vars-in-expansion e (outer #t))
|
422 | 442 | (cond ((or (not (pair? e)) (quoted? e)) '())
|
423 | 443 | ((eq? (car e) 'escape) '())
|
424 |
| - ((eq? (car e) 'hygienic-scope) '()) |
| 444 | + ((eq? (car e) 'hygienic-scope) |
| 445 | + (resume-on-escape (lambda (e) (find-assigned-vars-in-expansion e outer)) (cadr e) 0)) |
425 | 446 | ((and (not outer) (function-def? e))
|
426 | 447 | ;; pick up only function name
|
427 | 448 | (let ((fname (cond ((eq? (car e) '=) (decl-var* (cadr e)))
|
|
501 | 522 | (error (string "macro \"" (cadr e) "\" not defined")))
|
502 | 523 | (if (and (pair? form) (eq? (car form) 'error))
|
503 | 524 | (error (cadr form)))
|
504 |
| - (let ((form (car form)) ;; form is the expression returned from expand-macros |
505 |
| - (modu (cdr form))) ;; modu is the macro's def module |
506 |
| - `(hygienic-scope |
507 |
| - ,(julia-expand-macros- (cons modu m) (rename-symbolic-labels form) (- max-depth 1)) |
508 |
| - ,modu)))) |
| 525 | + (let* ((modu (cdr form)) ;; modu is the macro's def module |
| 526 | + (form (car form)) ;; form is the expression returned from expand-macros |
| 527 | + (form (julia-expand-macros- (cons modu m) form (- max-depth 1)))) |
| 528 | + (if (and (pair? form) (eq? (car form) 'escape)) |
| 529 | + (cadr form) ; immediately fold away (hygienic-scope (escape ...)) |
| 530 | + `(hygienic-scope ,form ,modu))))) |
509 | 531 | ((eq? (car e) 'module) e)
|
510 | 532 | ((eq? (car e) 'escape)
|
511 | 533 | (let ((m (if (null? m) m (cdr m))))
|
|
0 commit comments