pmatch.scm 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. ;;; pmatch, a simple matcher
  2. ;;; Copyright (C) 2009, 2010, 2012 Free Software Foundation, Inc
  3. ;;; Copyright (C) 2005,2006,2007 Oleg Kiselyov
  4. ;;; Copyright (C) 2007 Daniel P. Friedman
  5. ;;;
  6. ;;; This library is free software; you can redistribute it and/or
  7. ;;; modify it under the terms of the GNU Lesser General Public
  8. ;;; License as published by the Free Software Foundation; either
  9. ;;; version 3 of the License, or (at your option) any later version.
  10. ;;;
  11. ;;; This library is distributed in the hope that it will be useful,
  12. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. ;;; Lesser General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU Lesser General Public
  17. ;;; License along with this library; if not, write to the Free Software
  18. ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. ;;; Originally written by Oleg Kiselyov for LeanTAP in Kanren, which is
  20. ;;; available under the MIT license.
  21. ;;;
  22. ;;; http://kanren.cvs.sourceforge.net/viewvc/kanren/kanren/mini/leanTAP.scm?view=log
  23. ;;;
  24. ;;; This version taken from:
  25. ;;; αKanren: A Fresh Name in Nominal Logic Programming
  26. ;;; by William E. Byrd and Daniel P. Friedman
  27. ;;; Proceedings of the 2007 Workshop on Scheme and Functional Programming
  28. ;;; Université Laval Technical Report DIUL-RT-0701
  29. ;;; To be clear: the original code is MIT-licensed, and the modifications
  30. ;;; made to it by Guile are under Guile's license (currently LGPL v3+).
  31. ;;; Code:
  32. (define-module (system base pmatch)
  33. #:export-syntax (pmatch))
  34. (define-syntax-rule (pmatch e cs ...)
  35. (let ((v e)) (pmatch1 v cs ...)))
  36. (define-syntax pmatch1
  37. (syntax-rules (else guard)
  38. ((_ v) (if #f #f))
  39. ((_ v (else e0 e ...)) (let () e0 e ...))
  40. ((_ v (pat (guard g ...) e0 e ...) cs ...)
  41. (let ((fk (lambda () (pmatch1 v cs ...))))
  42. (ppat v pat
  43. (if (and g ...) (let () e0 e ...) (fk))
  44. (fk))))
  45. ((_ v (pat e0 e ...) cs ...)
  46. (let ((fk (lambda () (pmatch1 v cs ...))))
  47. (ppat v pat (let () e0 e ...) (fk))))))
  48. (define-syntax ppat
  49. (syntax-rules (_ quote unquote)
  50. ((_ v _ kt kf) kt)
  51. ((_ v () kt kf) (if (null? v) kt kf))
  52. ((_ v (quote lit) kt kf)
  53. (if (equal? v (quote lit)) kt kf))
  54. ((_ v (unquote var) kt kf) (let ((var v)) kt))
  55. ((_ v (x . y) kt kf)
  56. (if (pair? v)
  57. (let ((vx (car v)) (vy (cdr v)))
  58. (ppat vx x (ppat vy y kt kf) kf))
  59. kf))
  60. ((_ v lit kt kf) (if (eq? v (quote lit)) kt kf))))