shadow.scm 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Deal with shadowed variables.
  4. ; When a variable is shadowed by a variable, split the existing shared
  5. ; location into two replacement locations.
  6. ; name (structure-ref p name) (define name ...) within a single template
  7. ; will lose big.
  8. ;(define *replaced-locations* '()) ;alist of (old rep ((uid ...) . new))
  9. (define (shadow-location! old p-uids new replacement)
  10. (if (location-defined? old)
  11. (set-contents! replacement (contents old)))
  12. (set-location-id! old
  13. (vector replacement p-uids new))
  14. (set-location-defined?! old #f)) ;so that exceptions will be raised
  15. (define maybe-replace-location
  16. (let ((memv memv))
  17. (lambda (loc p-uid) ;Package's unique id
  18. (let ((foo (location-id loc)))
  19. (if (vector? foo)
  20. (maybe-replace-location
  21. (if (memv p-uid (vector-ref foo 1))
  22. (vector-ref foo 2)
  23. (vector-ref foo 0))
  24. p-uid)
  25. loc)))))
  26. ; Exception handler:
  27. (define (deal-with-replaced-variables succeed)
  28. (lambda (opcode reason loc template index . rest)
  29. (if (= reason (enum exception undefined-global))
  30. (deal-with-replaced-variable opcode reason loc template index rest
  31. succeed)
  32. (apply signal-global-exception opcode reason loc rest))))
  33. (define (deal-with-replaced-variable opcode reason loc template index rest
  34. succeed)
  35. (primitive-catch
  36. (lambda (cont)
  37. (if (eq? (template-ref template index) loc)
  38. (let* ((p-uid (template-package-id template))
  39. (new (maybe-replace-location loc p-uid)))
  40. (if (eq? new loc)
  41. (apply signal-global-exception opcode reason loc rest)
  42. (begin (template-set! template index new)
  43. ;(note 'deal-with-replaced-variable "Replaced location" loc new p-uid)
  44. (if (location-defined? new)
  45. (succeed new rest)
  46. (apply signal-global-exception opcode reason loc new rest)))))
  47. (assertion-violation 'deal-with-replaced-variable
  48. "lossage in deal-with-replaced-variables"
  49. loc index)))))
  50. (define (signal-global-exception opcode reason loc . rest)
  51. (signal-condition
  52. (condition
  53. (construct-vm-exception opcode reason)
  54. (make-assertion-violation)
  55. (make-who-condition (enumerand->name opcode op))
  56. (make-message-condition
  57. (if (location-defined? loc)
  58. "unassigned variable"
  59. "undefined variable"))
  60. (make-irritants-condition
  61. (cons (or (location-name loc) loc)
  62. (let ((pack (location-package-name loc)))
  63. (if pack
  64. (cons pack rest)
  65. rest)))))))
  66. (define-vm-exception-handler (enum op global)
  67. (deal-with-replaced-variables
  68. (lambda (loc more-args)
  69. (contents loc))))
  70. (define-vm-exception-handler (enum op set-global!)
  71. (deal-with-replaced-variables
  72. (lambda (loc more-args)
  73. (set-contents! loc (car more-args)))))