term-rewrite.scm 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. (define no-match (vector))
  2. (define (compile-system system)
  3. (let* ((sys (compile-system^ system))
  4. (step (lambda (term)
  5. (sys (list term) '())))
  6. (step? (lambda (term box)
  7. (let ((res (step term)))
  8. (if (eq? res no-match)
  9. term
  10. (begin (set-box! box #t)
  11. res))))))
  12. (letrec ((deep-step (lambda (term box)
  13. (if (pair? term)
  14. (step? (cons (car term)
  15. (map (lambda (t) (deep-step t box))
  16. (cdr term)))
  17. box)
  18. term))))
  19. (lambda (term)
  20. (let ((b (box #t)))
  21. (let loop ((term term))
  22. (if (unbox b)
  23. (begin (set-box! b #f)
  24. (loop (deep-step term b)))
  25. term)))))))
  26. (define (compile-system^ system)
  27. (if (null? system)
  28. (lambda (terms env) no-match)
  29. (let* ((pattern (compile-pattern (car (car system)) (box '())))
  30. (result (evaluate (cadr (car system))))
  31. (fk (compile-system^ (cdr system))))
  32. (lambda (terms env)
  33. ((pattern
  34. (lambda (nil env)
  35. (if (null? nil)
  36. (result env)
  37. (fk terms '())))
  38. (lambda ()
  39. (fk terms '())))
  40. terms env)))))
  41. (define (compile-pattern pat seen)
  42. (cond ((or (boolean? pat) (number? pat))
  43. (lambda (sk fk)
  44. (lambda (terms env)
  45. (if (null? terms)
  46. (fk)
  47. (if (equal? (car terms) pat)
  48. (sk (cdr terms) env)
  49. (fk))))))
  50. ((symbol? pat)
  51. (if (member pat (unbox seen))
  52. (lambda (sk fk)
  53. (lambda (terms env)
  54. (if (null? terms)
  55. (fk)
  56. (cond ((assoc pat env) =>
  57. (lambda (entry)
  58. (if (equal? (car terms) (cdr entry))
  59. (sk (cdr terms)
  60. env)
  61. (fk))))
  62. (else (fk))))))
  63. (begin
  64. (set-box! seen (cons pat (unbox seen)))
  65. (lambda (sk fk)
  66. (lambda (terms env)
  67. (if (null? terms)
  68. (fk)
  69. (sk (cdr terms)
  70. (cons (cons pat (car terms)) env))))))))
  71. ((pair? pat)
  72. (let loop ((head (lambda (sk fk)
  73. (lambda (terms env)
  74. (if (null? terms)
  75. (fk)
  76. (let ((term (car terms))
  77. (terms (cdr terms)))
  78. (if (and (pair? term)
  79. (eq? (car term) (car pat))
  80. (= (length term) (length pat)))
  81. (sk (append (cdr term) terms)
  82. env)
  83. (fk)))))))
  84. (tail (map* (lambda (pat) (compile-pattern pat seen)) (cdr pat))))
  85. (if (null? tail)
  86. head
  87. (loop (lambda (sk fk) (head ((car tail) sk fk) fk))
  88. (cdr tail)))))))
  89. (define (lookup v env)
  90. (cond ((assoc v env) => cdr)
  91. (else (error 'lookup "unbound variable" v))))
  92. (define (evaluate term)
  93. (cond ((or (boolean? term) (number? term))
  94. (lambda (env) term))
  95. ((symbol? term)
  96. (lambda (env) (lookup term env)))
  97. ((pair? term)
  98. (let ((head (car term))
  99. (tail (map evaluate (cdr term))))
  100. (lambda (env)
  101. (cons head (map (lambda (arg) (arg env)) tail)))))))