peg-tree-utils.scm 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. (library (peg-tree-utils)
  2. (export find-in-tree
  3. find-in-tree*
  4. tree-refs)
  5. (import
  6. (except (rnrs base) let-values)
  7. (only (guile) lambda* λ
  8. current-output-port
  9. simple-format)
  10. (srfi srfi-1))
  11. (define find-in-tree
  12. (λ (peg-tree label equal-test)
  13. (define traverse
  14. (λ (peg-tree label)
  15. (cond
  16. [(null? peg-tree) #f]
  17. [(pair? (car peg-tree))
  18. (or (traverse (first peg-tree) label)
  19. (traverse (cdr peg-tree) label))]
  20. [(symbol? (car peg-tree))
  21. (cond
  22. [(equal-test (car peg-tree) label)
  23. (car (cdr peg-tree))]
  24. [else
  25. (traverse (cdr peg-tree) label)])]
  26. [else
  27. (traverse (cdr peg-tree) label)])))
  28. (traverse peg-tree label)))
  29. (define tree-refs
  30. (lambda* (peg-tree refs #:key (equal-test eq?))
  31. (let traverse ([tree° peg-tree]
  32. [refs° refs])
  33. (cond
  34. [(null? refs°) tree°]
  35. [(null? tree°) #f]
  36. [(pair? (car tree°))
  37. (or (traverse (car tree°) refs°)
  38. (traverse (cdr tree°) refs°))]
  39. [(symbol? (car tree°))
  40. (cond
  41. ;; success case
  42. [(equal-test (car tree°) (car refs°))
  43. (traverse (cdr tree°) (cdr refs°))]
  44. [else
  45. (traverse (cdr tree°) refs°)])]
  46. [else
  47. (traverse (cdr tree°) refs°)]))))
  48. (define find-in-tree*
  49. (λ (peg-tree filter-proc)
  50. (define traverse
  51. (λ (subtree cont)
  52. ;; (simple-format (current-output-port)
  53. ;; "working with subtree ~a\n"
  54. ;; subtree)
  55. (cond
  56. [(null? subtree) (cont)]
  57. [(pair? (first subtree))
  58. (traverse (first subtree)
  59. (λ () (traverse (cdr subtree) cont)))]
  60. [(filter-proc (first subtree))
  61. (cons subtree (cont))]
  62. [else
  63. (traverse (cdr subtree) cont)])))
  64. (traverse peg-tree (λ () '())))))