File: pattern.rkt

package info (click to toggle)
racket 7.9%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 178,684 kB
  • sloc: ansic: 282,112; lisp: 234,887; pascal: 70,954; sh: 27,112; asm: 16,268; makefile: 4,613; cpp: 2,715; ada: 1,681; javascript: 1,244; cs: 879; exp: 499; csh: 422; python: 274; xml: 106; perl: 104
file content (96 lines) | stat: -rw-r--r-- 2,688 bytes parent folder | download | duplicates (11)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#lang racket/base
(require racket/list
         racket/contract)

; A dispatch pattern is either
; - a string
; - a bidi match expander
; - ...

(define (...? stx)
  (eq? '... (syntax->datum stx)))

(define (string-syntax? stx)
  (string? (syntax->datum stx)))

(define (dispatch-pattern? stx)
  (define (dispatch/no-...? stx)
    (syntax-case stx ()
      [() #t]
      [((bidi arg ...) . rest-stx)
       (dispatch/...? #'rest-stx)]
      [(string . rest-stx)
       (string-syntax? #'string)
       (dispatch/no-...? #'rest-stx)]))
  (define (dispatch/...? stx)
    (syntax-case stx ()
      [() #t]
      [((bidi arg ...) . rest-stx)
       (dispatch/...? #'rest-stx)]
      [(string . rest-stx)
       (string-syntax? #'string)
       (dispatch/no-...? #'rest-stx)]
      [((... ...) . rest-stx)
       (dispatch/no-...? #'rest-stx)]))    
  (dispatch/no-...? stx))

(define (dispatch-pattern/ids? stx)
  (define (dispatch/no-...? stx)
    (syntax-case stx ()
      [() #t]
      [((bidi arg ... id) . rest-stx)
       (identifier? #'id)
       (dispatch/...? #'rest-stx)]
      [(string . rest-stx)
       (string-syntax? #'string)
       (dispatch/no-...? #'rest-stx)]))
  (define (dispatch/...? stx)
    (syntax-case stx ()
      [() #t]
      [((bidi arg ... id) . rest-stx)
       (identifier? #'id)
       (dispatch/...? #'rest-stx)]
      [(string . rest-stx)
       (string-syntax? #'string)
       (dispatch/no-...? #'rest-stx)]
      [((... ...) . rest-stx)
       (dispatch/no-...? #'rest-stx)]))    
  (dispatch/no-...? stx))

(define (dispatch-pattern-not-... stx)
  (filter (compose not ...?) 
          (syntax->list stx)))

(define (dispatch-pattern-next-...? stx)
  (let loop ([l (syntax->list stx)])
    (cond
      [(empty? l)
       empty]
      [(empty? (rest l))
       (list #f)]
      [(...? (second l))
       (list* #t (loop (rest (rest l))))]
      [else
       (list* #f (loop (rest l)))])))

(define (dispatch-pattern->dispatch-pattern/ids pps)
  (map (lambda (pp ppi)
         (cond
           [(string-syntax? pp)
            pp]
           [(...? pp)
            pp]
           [else
            (with-syntax ([(bidi-id arg ...) pp]
                          [id ppi])
              (syntax/loc pp (bidi-id arg ... id)))]))
       (syntax->list pps)
       (generate-temporaries pps)))

(provide/contract
 [string-syntax? (syntax? . -> . boolean?)]
 [dispatch-pattern-next-...? (syntax? . -> . (listof boolean?))]
 [dispatch-pattern-not-... (syntax? . -> . (listof syntax?))]
 [dispatch-pattern->dispatch-pattern/ids (syntax? . -> . (listof syntax?))]
 [dispatch-pattern? (syntax? . -> . boolean?)]
 [dispatch-pattern/ids? (syntax? . -> . boolean?)])