node-equal.scm 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/node/node-equal.scm
  8. ;;;
  9. ;;; Determining if two nodes are functionally identical.
  10. (define-module (ps-compiler node node-equal)
  11. #:use-module (prescheme scheme48)
  12. #:use-module (ps-compiler node node)
  13. #:use-module (ps-compiler node variable)
  14. #:export (node-equal?))
  15. (define (node-equal? n1 n2)
  16. (if (call-node? n1)
  17. (and (call-node? n2)
  18. (call-node-eq? n1 n2))
  19. (value-node-eq? n1 n2)))
  20. ;; Compare two call nodes. The arguments to the nodes are compared
  21. ;; starting from the back to do leaf nodes first (usually).
  22. (define (call-node-eq? n1 n2)
  23. (and (= (call-arg-count n1) (call-arg-count n2))
  24. (= (call-exits n1) (call-exits n2))
  25. (eq? (call-primop n1) (call-primop n2))
  26. (let ((v1 (call-args n1))
  27. (v2 (call-args n2)))
  28. (let loop ((i (- (vector-length v1) '1)))
  29. (cond ((< i '0)
  30. #t)
  31. ((node-equal? (vector-ref v1 i) (vector-ref v2 i))
  32. (loop (- i '1)))
  33. (else
  34. #f))))))
  35. ;; Compare two value nodes. Reference nodes are the same if they refer to the
  36. ;; same variable or if they refer to corresponding variables in the two node
  37. ;; trees. Primop and literal nodes must be identical. Lambda nodes are compared
  38. ;; by their own procedure.
  39. (define (value-node-eq? n1 n2)
  40. (cond ((neq? (node-variant n1) (node-variant n2))
  41. #f)
  42. ((reference-node? n1)
  43. (let ((v1 (reference-variable n1))
  44. (v2 (reference-variable n2)))
  45. (or (eq? v1 v2) (eq? v1 (variable-flag v2)))))
  46. ((literal-node? n1)
  47. (and (eq? (literal-value n1) (literal-value n2))
  48. (eq? (literal-type n1) (literal-type n2))))
  49. ((lambda-node? n1)
  50. (lambda-node-eq? n1 n2))))
  51. ;; Lambda nodes are identical if they have identical variable lists and identical
  52. ;; bodies. The variables of N1 are stored in the flag fields of the variables of
  53. ;; N2 for the use of VALUE-NODE-EQ?.
  54. (define (lambda-node-eq? n1 n2)
  55. (let ((v1 (lambda-variables n1))
  56. (v2 (lambda-variables n2)))
  57. (let ((ok? (let loop ((v1 v1) (v2 v2))
  58. (cond ((null? v1)
  59. (if (null? v2)
  60. (call-node-eq? (lambda-body n1) (lambda-body n2))
  61. #f))
  62. ((null? v2) #f)
  63. ((variable-eq? (car v1) (car v2))
  64. (loop (cdr v1) (cdr v2)))
  65. (else #f)))))
  66. (map (lambda (v) (if v (set-variable-flag! v #f))) v2)
  67. ok?)))
  68. (define (variable-eq? v1 v2)
  69. (cond ((not v1)
  70. (not v2))
  71. ((not v2) #f)
  72. ((eq? (variable-type v1) (variable-type v2))
  73. (set-variable-flag! v2 v1)
  74. #t)
  75. (else #f)))