This repository has been archived by the owner on Apr 17, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pattern-matcher.scm
79 lines (72 loc) · 1.79 KB
/
pattern-matcher.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
;;; pattern-matcher.scm
;;; The pattern-matching package
;;;
;;; Programmer: Mayer Goldberg, 2016
(define match
(letrec ((match
(lambda (pat e ret-dict ret-no-match)
(cond ((and (pair? pat) (pair? e))
(match (car pat) (car e)
(lambda (car-dict)
(match (cdr pat) (cdr e)
(lambda (cdr-dict)
(ret-dict
(append car-dict cdr-dict)))
ret-no-match))
ret-no-match))
((and (vector? pat) (vector? e)
(= (vector-length pat)
(vector-length e)))
(match
(vector->list pat)
(vector->list e)
ret-dict
ret-no-match))
;; match with unification
((procedure? pat)
(if (pat e)
(ret-dict `(,e))
(ret-no-match)))
((or (and (char? pat) (char? e) (char=? pat e))
(and (string? pat)
(string? e)
(string=? pat e))
(and (symbol? pat) (symbol? e) (eq? pat e))
(and (number? pat) (number? e) (= pat e))
(eq? pat e))
(ret-dict '()))
(else (ret-no-match))))))
(lambda (pat e ret-match ret-no-match)
(match pat e
(lambda (dict) (apply ret-match dict))
ret-no-match))))
(define ?
(lambda (name . guards)
(lambda (e)
(andmap
(lambda (pred?)
(pred? e))
guards))))
;;; composing patterns
(define pattern-rule
(lambda (pat handler)
(lambda (e failure)
(match pat e handler failure))))
(define compose-patterns
(letrec ((match-nothing
(lambda (e failure)
(failure)))
(loop
(lambda (s)
(if (null? s)
match-nothing
(let ((match-rest
(loop (cdr s)))
(match-first (car s)))
(lambda (e failure)
(match-first e
(lambda ()
(match-rest e failure)))))))))
(lambda patterns
(loop patterns))))
;;; end of input