node-equal.scm 2.5 KB

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