1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2;; Pattern Matching Syntactic Extensions for Scheme
3;;
4(define match:version "Version 1.18, July 17, 1995")
5;;
6;; Report bugs to wright@research.nj.nec.com.  The most recent version of
7;; this software can be obtained by anonymous FTP from ftp.nj.nec.com
8;; in file pub/wright/match.tar.Z.  Be sure to set "type binary" when
9;; transferring this file.
10;;
11;; Written by Andrew K. Wright, 1993 (wright@research.nj.nec.com).
12;; Adapted from code originally written by Bruce F. Duba, 1991.
13;; This package also includes a modified version of Kent Dybvig's
14;; define-structure (see Dybvig, R.K., The Scheme Programming Language,
15;; Prentice-Hall, NJ, 1987).
16;;
17;; This software is in the public domain.  Feel free to copy,
18;; distribute, and modify this software as desired.  No warranties
19;; nor guarantees of any kind apply.  Please return any improvements
20;; or bug fixes to wright@research.nj.nec.com so that they may be included
21;; in future releases.
22;;
23;; This macro package extends Scheme with several new expression forms.
24;; Following is a brief summary of the new forms.  See the associated
25;; LaTeX documentation for a full description of their functionality.
26;;
27;;
28;;         match expressions:
29;;
30;; exp ::= ...
31;;       | (match exp clause ...)
32;;       | (match-lambda clause ...)
33;;       | (match-lambda* clause ...)
34;;       | (match-let ((pat exp) ...) body)
35;;       | (match-let* ((pat exp) ...) body)
36;;       | (match-letrec ((pat exp) ...) body)
37;;       | (match-define pat exp)
38;;
39;; clause ::= (pat body) | (pat => exp)
40;;
41;;         patterns:                       matches:
42;;
43;; pat ::= identifier                      anything, and binds identifier
44;;       | _                               anything
45;;       | ()                              the empty list
46;;       | #t                              #t
47;;       | #f                              #f
48;;       | string                          a string
49;;       | number                          a number
50;;       | character                       a character
51;;       | 'sexp                           an s-expression
52;;       | 'symbol                         a symbol (special case of s-expr)
53;;       | (pat_1 ... pat_n)               list of n elements
54;;       | (pat_1 ... pat_n . pat_{n+1})   list of n or more
55;;       | (pat_1 ... pat_n pat_n+1 ooo)   list of n or more, each element
56;;                                           of remainder must match pat_n+1
57;;       | #(pat_1 ... pat_n)              vector of n elements
58;;       | #(pat_1 ... pat_n pat_n+1 ooo)  vector of n or more, each element
59;;                                           of remainder must match pat_n+1
60;;       | #&pat                           box
61;;       | ($ struct-name pat_1 ... pat_n) a structure
62;;       | (= field pat)                   a field of a structure
63;;       | (and pat_1 ... pat_n)           if all of pat_1 thru pat_n match
64;;       | (or pat_1 ... pat_n)            if any of pat_1 thru pat_n match
65;;       | (not pat_1 ... pat_n)           if all pat_1 thru pat_n don't match
66;;       | (? predicate pat_1 ... pat_n)   if predicate true and all of
67;;                                           pat_1 thru pat_n match
68;;       | (set! identifier)               anything, and binds setter
69;;       | (get! identifier)               anything, and binds getter
70;;       | `qp                             a quasi-pattern
71;;
72;; ooo ::= ...                             zero or more
73;;       | ___                             zero or more
74;;       | ..k                             k or more
75;;       | __k                             k or more
76;;
77;;         quasi-patterns:                 matches:
78;;
79;; qp  ::= ()                              the empty list
80;;       | #t                              #t
81;;       | #f                              #f
82;;       | string                          a string
83;;       | number                          a number
84;;       | character                       a character
85;;       | identifier                      a symbol
86;;       | (qp_1 ... qp_n)                 list of n elements
87;;       | (qp_1 ... qp_n . qp_{n+1})      list of n or more
88;;       | (qp_1 ... qp_n qp_n+1 ooo)      list of n or more, each element
89;;                                           of remainder must match qp_n+1
90;;       | #(qp_1 ... qp_n)                vector of n elements
91;;       | #(qp_1 ... qp_n qp_n+1 ooo)     vector of n or more, each element
92;;                                           of remainder must match qp_n+1
93;;       | #&qp                            box
94;;       | ,pat                            a pattern
95;;       | ,@pat                           a pattern
96;;
97;; The names (quote, quasiquote, unquote, unquote-splicing, ?, _, $,
98;; and, or, not, set!, get!, ..., ___) cannot be used as pattern variables.
99;;
100;;
101;;         structure expressions:
102;;
103;; exp ::= ...
104;;       | (define-structure (id_0 id_1 ... id_n))
105;;       | (define-structure (id_0 id_1 ... id_n)
106;;                           ((id_{n+1} exp_1) ... (id_{n+m} exp_m)))
107;;       | (define-const-structure (id_0 arg_1 ... arg_n))
108;;       | (define-const-structure (id_0 arg_1 ... arg_n)
109;;                                 ((arg_{n+1} exp_1) ... (arg_{n+m} exp_m)))
110;;
111;; arg ::= id | (! id) | (@ id)
112;;
113;;
114;; match:error-control controls what code is generated for failed matches.
115;; Possible values:
116;;  'unspecified - do nothing, ie., evaluate (cond [#f #f])
117;;  'fail - call match:error, or die at car or cdr
118;;  'error - call match:error with the unmatched value
119;;  'match - call match:error with the unmatched value _and_
120;;             the quoted match expression
121;; match:error-control is set by calling match:set-error-control with
122;; the new value.
123;;
124;; match:error is called for a failed match.
125;; match:error is set by calling match:set-error with the new value.
126;;
127;; match:structure-control controls the uniqueness of structures
128;; (does not exist for Scheme 48 version).
129;; Possible values:
130;;  'vector - (default) structures are vectors with a symbol in position 0
131;;  'disjoint - structures are fully disjoint from all other values
132;; match:structure-control is set by calling match:set-structure-control
133;; with the new value.
134;;
135;; match:runtime-structures controls whether local structure declarations
136;; generate new structures each time they are reached
137;; (does not exist for Scheme 48 version).
138;; Possible values:
139;;  #t - (default) each runtime occurrence generates a new structure
140;;  #f - each lexical occurrence generates a new structure
141;;
142;; End of user visible/modifiable stuff.
143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
144
145(define match:error
146  (lambda (val . args)
147    (for-each print args)
148    (error "no matching clause for " val)))
149(define match:andmap
150  (lambda (f l)
151    (if (null? l)
152        (and)
153        (and (f (car l)) (match:andmap f (cdr l))))))
154(define match:syntax-err
155  (lambda (obj msg) (error msg obj)))
156(define match:disjoint-structure-tags '())
157(define match:make-structure-tag
158  (lambda (name)
159    (if (or (eq? match:structure-control 'disjoint)
160            match:runtime-structures)
161        (let ((tag (gensym)))
162          (set! match:disjoint-structure-tags
163            (cons tag match:disjoint-structure-tags))
164          tag)
165        (string->symbol
166          (string-append "<" (symbol->string name) ">")))))
167(define match:structure?
168  (lambda (tag) (memq tag match:disjoint-structure-tags)))
169(define match:structure-control 'vector)
170(define match:set-structure-control
171  (lambda (v) (set! match:structure-control v)))
172(define match:set-error (lambda (v) (set! match:error v)))
173(define match:error-control 'error)
174(define match:set-error-control
175  (lambda (v) (set! match:error-control v)))
176(define match:disjoint-predicates
177  (cons 'null
178        '(pair?
179           symbol?
180           boolean?
181           number?
182           string?
183           char?
184           procedure?
185           vector?)))
186(define match:vector-structures '())
187(define match:expanders
188  (letrec ((genmatch (lambda (x clauses match-expr)
189                       (let* ((length>= (gensym))
190                              (eb-errf (error-maker match-expr))
191                              (blist (car eb-errf))
192                              (plist (map (lambda (c)
193                                            (let* ((x (bound
194                                                        (validate-pattern
195                                                          (car c))))
196                                                   (p (car x))
197                                                   (bv (cadr x))
198                                                   (bindings (caddr x))
199                                                   (code (gensym))
200                                                   (fail (and (pair?
201                                                                (cdr c))
202                                                              (pair?
203                                                                (cadr c))
204                                                              (eq? (caadr
205                                                                     c)
206                                                                   '=>)
207                                                              (symbol?
208                                                                (cadadr c))
209                                                              (pair?
210                                                                (cdadr c))
211                                                              (null?
212                                                                (cddadr c))
213                                                              (pair?
214                                                                (cddr c))
215                                                              (cadadr c)))
216                                                   (bv2 (if fail
217                                                            (cons fail bv)
218                                                            bv))
219                                                   (body (if fail
220                                                             (cddr c)
221                                                             (cdr c))))
222                                              (set! blist
223                                                (cons `(,code
224                                                         (lambda ,bv2
225                                                           ,@body))
226                                                      (append
227                                                        bindings
228                                                        blist)))
229                                              (list p
230                                                    code
231                                                    bv
232                                                    (and fail (gensym))
233                                                    #f)))
234                                          clauses))
235                              (code (gen x
236                                         '()
237                                         plist
238                                         (cdr eb-errf)
239                                         length>=
240                                         (gensym))))
241                         (unreachable plist match-expr)
242                         (inline-let
243                           `(let ((,length>= (lambda (n)
244                                               (lambda (l)
245                                                 (>= (length l) n))))
246                                  ,@blist)
247                              ,code)))))
248           (genletrec (lambda (pat exp body match-expr)
249                        (let* ((length>= (gensym))
250                               (eb-errf (error-maker match-expr))
251                               (x (bound (validate-pattern pat)))
252                               (p (car x))
253                               (bv (cadr x))
254                               (bindings (caddr x))
255                               (code (gensym))
256                               (plist (list (list p code bv #f #f)))
257                               (x (gensym))
258                               (m (gen x
259                                       '()
260                                       plist
261                                       (cdr eb-errf)
262                                       length>=
263                                       (gensym)))
264                               (gs (map (lambda (_) (gensym)) bv)))
265                          (unreachable plist match-expr)
266                          `(letrec ((,length>= (lambda (n)
267                                                 (lambda (l)
268                                                   (>= (length l) n))))
269                                    ,@(map (lambda (v) `(,v #f)) bv)
270                                    (,x ,exp)
271                                    (,code (lambda ,gs
272                                             ,@(map (lambda (v g)
273                                                      `(set! ,v ,g))
274                                                    bv
275                                                    gs)
276                                             ,@body))
277                                    ,@bindings
278                                    ,@(car eb-errf))
279                             ,m))))
280           (gendefine (lambda (pat exp match-expr)
281                        (let* ((length>= (gensym))
282                               (eb-errf (error-maker match-expr))
283                               (x (bound (validate-pattern pat)))
284                               (p (car x))
285                               (bv (cadr x))
286                               (bindings (caddr x))
287                               (code (gensym))
288                               (plist (list (list p code bv #f #f)))
289                               (x (gensym))
290                               (m (gen x
291                                       '()
292                                       plist
293                                       (cdr eb-errf)
294                                       length>=
295                                       (gensym)))
296                               (gs (map (lambda (_) (gensym)) bv)))
297                          (unreachable plist match-expr)
298                          `(begin ,@(map (lambda (v) `(define ,v #f)) bv)
299                                  ,(inline-let
300                                     `(let ((,length>= (lambda (n)
301                                                         (lambda (l)
302                                                           (>= (length l)
303                                                               n))))
304                                            (,x ,exp)
305                                            (,code (lambda ,gs
306                                                     ,@(map (lambda (v g)
307                                                              `(set! ,v
308                                                                 ,g))
309                                                            bv
310                                                            gs)
311                                                     (cond (#f #f))))
312                                            ,@bindings
313                                            ,@(car eb-errf))
314                                        ,m))))))
315           (pattern-var? (lambda (x)
316                           (and (symbol? x)
317                                (not (dot-dot-k? x))
318                                (not (memq x
319                                           '(quasiquote
320                                              quote
321                                              unquote
322                                              unquote-splicing
323                                              ?
324                                              _
325                                              $
326                                              =
327                                              and
328                                              or
329                                              not
330                                              set!
331                                              get!
332                                              ...
333                                              ___))))))
334           (dot-dot-k? (lambda (s)
335                         (and (symbol? s)
336                              (if (memq s '(... ___))
337                                  0
338                                  (let* ((s (symbol->string s))
339                                         (n (string-length s)))
340                                    (and (<= 3 n)
341                                         (memq (string-ref s 0) '(#\. #\_))
342                                         (memq (string-ref s 1) '(#\. #\_))
343                                         (match:andmap
344                                           char-numeric?
345                                           (string->list
346                                             (substring s 2 n)))
347                                         (string->number
348                                           (substring s 2 n))))))))
349           (error-maker (lambda (match-expr)
350                          (cond
351                            ((eq? match:error-control 'unspecified) (cons '()
352                                                                          (lambda (x)
353                                                                            `(cond
354                                                                               (#f #f)))))
355                            ((memq match:error-control '(error fail)) (cons '()
356                                                                            (lambda (x)
357                                                                              `(match:error
358                                                                                 ,x))))
359                            ((eq? match:error-control 'match) (let ((errf (gensym))
360                                                                    (arg (gensym)))
361                                                                (cons `((,errf
362                                                                          (lambda (,arg)
363                                                                            (match:error
364                                                                              ,arg
365                                                                              ',match-expr))))
366                                                                      (lambda (x)
367                                                                        `(,errf
368                                                                           ,x)))))
369                            (else (match:syntax-err
370                                    '(unspecified error fail match)
371                                    "invalid value for match:error-control, legal values are")))))
372           (unreachable (lambda (plist match-expr)
373                          (for-each
374                            (lambda (x)
375                              (if (not (car (cddddr x)))
376                                  (begin (display
377                                           "Warning: unreachable pattern ")
378                                         (display (car x))
379                                         (display " in ")
380                                         (display match-expr)
381                                         (newline))))
382                            plist)))
383           (validate-pattern (lambda (pattern)
384                               (letrec ((simple? (lambda (x)
385                                                   (or (string? x)
386                                                       (boolean? x)
387                                                       (char? x)
388                                                       (number? x)
389                                                       (null? x))))
390                                        (ordinary (lambda (p)
391                                                    (let ((g88 (lambda (x
392                                                                        y)
393                                                                 (cons (ordinary
394                                                                         x)
395                                                                       (ordinary
396                                                                         y)))))
397                                                      (if (simple? p)
398                                                          ((lambda (p) p)
399                                                           p)
400                                                          (if (equal? p '_)
401                                                              ((lambda ()
402                                                                 '_))
403                                                              (if (pattern-var?
404                                                                    p)
405                                                                  ((lambda (p)
406                                                                     p)
407                                                                   p)
408                                                                  (if (pair?
409                                                                        p)
410                                                                      (if (equal?
411                                                                            (car p)
412                                                                            'quasiquote)
413                                                                          (if (and (pair?
414                                                                                     (cdr p))
415                                                                                   (null?
416                                                                                     (cddr p)))
417                                                                              ((lambda (p)
418                                                                                 (quasi
419                                                                                   p))
420                                                                               (cadr p))
421                                                                              (g88 (car p)
422                                                                                   (cdr p)))
423                                                                          (if (equal?
424                                                                                (car p)
425                                                                                'quote)
426                                                                              (if (and (pair?
427                                                                                         (cdr p))
428                                                                                       (null?
429                                                                                         (cddr p)))
430                                                                                  ((lambda (p)
431                                                                                     p)
432                                                                                   p)
433                                                                                  (g88 (car p)
434                                                                                       (cdr p)))
435                                                                              (if (equal?
436                                                                                    (car p)
437                                                                                    '?)
438                                                                                  (if (and (pair?
439                                                                                             (cdr p))
440                                                                                           (list?
441                                                                                             (cddr p)))
442                                                                                      ((lambda (pred
443                                                                                                ps)
444                                                                                         `(? ,pred
445                                                                                             ,@(map ordinary
446                                                                                                    ps)))
447                                                                                       (cadr p)
448                                                                                       (cddr p))
449                                                                                      (g88 (car p)
450                                                                                           (cdr p)))
451                                                                                  (if (equal?
452                                                                                        (car p)
453                                                                                        '=)
454                                                                                      (if (and (pair?
455                                                                                                 (cdr p))
456                                                                                               (pair?
457                                                                                                 (cddr p))
458                                                                                               (null?
459                                                                                                 (cdddr
460                                                                                                   p)))
461                                                                                          ((lambda (sel
462                                                                                                    p)
463                                                                                             `(= ,sel
464                                                                                                 ,(ordinary
465                                                                                                    p)))
466                                                                                           (cadr p)
467                                                                                           (caddr
468                                                                                             p))
469                                                                                          (g88 (car p)
470                                                                                               (cdr p)))
471                                                                                      (if (equal?
472                                                                                            (car p)
473                                                                                            'and)
474                                                                                          (if (and (list?
475                                                                                                     (cdr p))
476                                                                                                   (pair?
477                                                                                                     (cdr p)))
478                                                                                              ((lambda (ps)
479                                                                                                 `(and ,@(map ordinary
480                                                                                                              ps)))
481                                                                                               (cdr p))
482                                                                                              (g88 (car p)
483                                                                                                   (cdr p)))
484                                                                                          (if (equal?
485                                                                                                (car p)
486                                                                                                'or)
487                                                                                              (if (and (list?
488                                                                                                         (cdr p))
489                                                                                                       (pair?
490                                                                                                         (cdr p)))
491                                                                                                  ((lambda (ps)
492                                                                                                     `(or ,@(map ordinary
493                                                                                                                 ps)))
494                                                                                                   (cdr p))
495                                                                                                  (g88 (car p)
496                                                                                                       (cdr p)))
497                                                                                              (if (equal?
498                                                                                                    (car p)
499                                                                                                    'not)
500                                                                                                  (if (and (list?
501                                                                                                             (cdr p))
502                                                                                                           (pair?
503                                                                                                             (cdr p)))
504                                                                                                      ((lambda (ps)
505                                                                                                         `(not ,@(map ordinary
506                                                                                                                      ps)))
507                                                                                                       (cdr p))
508                                                                                                      (g88 (car p)
509                                                                                                           (cdr p)))
510                                                                                                  (if (equal?
511                                                                                                        (car p)
512                                                                                                        '$)
513                                                                                                      (if (and (pair?
514                                                                                                                 (cdr p))
515                                                                                                               (symbol?
516                                                                                                                 (cadr p))
517                                                                                                               (list?
518                                                                                                                 (cddr p)))
519                                                                                                          ((lambda (r
520                                                                                                                    ps)
521                                                                                                             `($ ,r
522                                                                                                                 ,@(map ordinary
523                                                                                                                        ps)))
524                                                                                                           (cadr p)
525                                                                                                           (cddr p))
526                                                                                                          (g88 (car p)
527                                                                                                               (cdr p)))
528                                                                                                      (if (equal?
529                                                                                                            (car p)
530                                                                                                            'set!)
531                                                                                                          (if (and (pair?
532                                                                                                                     (cdr p))
533                                                                                                                   (pattern-var?
534                                                                                                                     (cadr p))
535                                                                                                                   (null?
536                                                                                                                     (cddr p)))
537                                                                                                              ((lambda (p)
538                                                                                                                 p)
539                                                                                                               p)
540                                                                                                              (g88 (car p)
541                                                                                                                   (cdr p)))
542                                                                                                          (if (equal?
543                                                                                                                (car p)
544                                                                                                                'get!)
545                                                                                                              (if (and (pair?
546                                                                                                                         (cdr p))
547                                                                                                                       (pattern-var?
548                                                                                                                         (cadr p))
549                                                                                                                       (null?
550                                                                                                                         (cddr p)))
551                                                                                                                  ((lambda (p)
552                                                                                                                     p)
553                                                                                                                   p)
554                                                                                                                  (g88 (car p)
555                                                                                                                       (cdr p)))
556                                                                                                              (if (equal?
557                                                                                                                    (car p)
558                                                                                                                    'unquote)
559                                                                                                                  (g88 (car p)
560                                                                                                                       (cdr p))
561                                                                                                                  (if (equal?
562                                                                                                                        (car p)
563                                                                                                                        'unquote-splicing)
564                                                                                                                      (g88 (car p)
565                                                                                                                           (cdr p))
566                                                                                                                      (if (and (pair?
567                                                                                                                                 (cdr p))
568                                                                                                                               (dot-dot-k?
569                                                                                                                                 (cadr p))
570                                                                                                                               (null?
571                                                                                                                                 (cddr p)))
572                                                                                                                          ((lambda (p
573                                                                                                                                    ddk)
574                                                                                                                             `(,(ordinary
575                                                                                                                                  p)
576                                                                                                                                ,ddk))
577                                                                                                                           (car p)
578                                                                                                                           (cadr p))
579                                                                                                                          (g88 (car p)
580                                                                                                                               (cdr p)))))))))))))))
581                                                                      (if (vector?
582                                                                            p)
583                                                                          ((lambda (p)
584                                                                             (let* ((pl (vector->list
585                                                                                          p))
586                                                                                    (rpl (reverse
587                                                                                           pl)))
588                                                                               (apply
589                                                                                 vector
590                                                                                 (if (and (not (null?
591                                                                                                 rpl))
592                                                                                          (dot-dot-k?
593                                                                                            (car rpl)))
594                                                                                     (reverse
595                                                                                       (cons (car rpl)
596                                                                                             (map ordinary
597                                                                                                  (cdr rpl))))
598                                                                                     (map ordinary
599                                                                                          pl)))))
600                                                                           p)
601                                                                          ((lambda ()
602                                                                             (match:syntax-err
603                                                                               pattern
604                                                                               "syntax error in pattern")))))))))))
605                                        (quasi (lambda (p)
606                                                 (let ((g109 (lambda (x y)
607                                                               (cons (quasi
608                                                                       x)
609                                                                     (quasi
610                                                                       y)))))
611                                                   (if (simple? p)
612                                                       ((lambda (p) p) p)
613                                                       (if (symbol? p)
614                                                           ((lambda (p)
615                                                              `',p)
616                                                            p)
617                                                           (if (pair? p)
618                                                               (if (equal?
619                                                                     (car p)
620                                                                     'unquote)
621                                                                   (if (and (pair?
622                                                                              (cdr p))
623                                                                            (null?
624                                                                              (cddr p)))
625                                                                       ((lambda (p)
626                                                                          (ordinary
627                                                                            p))
628                                                                        (cadr p))
629                                                                       (g109 (car p)
630                                                                             (cdr p)))
631                                                                   (if (and (pair?
632                                                                              (car p))
633                                                                            (equal?
634                                                                              (caar p)
635                                                                              'unquote-splicing)
636                                                                            (pair?
637                                                                              (cdar p))
638                                                                            (null?
639                                                                              (cddar
640                                                                                p)))
641                                                                       (if (null?
642                                                                             (cdr p))
643                                                                           ((lambda (p)
644                                                                              (ordinary
645                                                                                p))
646                                                                            (cadar
647                                                                              p))
648                                                                           ((lambda (p
649                                                                                     y)
650                                                                              (append
651                                                                                (ordlist
652                                                                                  p)
653                                                                                (quasi
654                                                                                  y)))
655                                                                            (cadar
656                                                                              p)
657                                                                            (cdr p)))
658                                                                       (if (and (pair?
659                                                                                  (cdr p))
660                                                                                (dot-dot-k?
661                                                                                  (cadr p))
662                                                                                (null?
663                                                                                  (cddr p)))
664                                                                           ((lambda (p
665                                                                                     ddk)
666                                                                              `(,(quasi
667                                                                                   p)
668                                                                                 ,ddk))
669                                                                            (car p)
670                                                                            (cadr p))
671                                                                           (g109 (car p)
672                                                                                 (cdr p)))))
673                                                               (if (vector?
674                                                                     p)
675                                                                   ((lambda (p)
676                                                                      (let* ((pl (vector->list
677                                                                                   p))
678                                                                             (rpl (reverse
679                                                                                    pl)))
680                                                                        (apply
681                                                                          vector
682                                                                          (if (dot-dot-k?
683                                                                                (car rpl))
684                                                                              (reverse
685                                                                                (cons (car rpl)
686                                                                                      (map quasi
687                                                                                           (cdr rpl))))
688                                                                              (map ordinary
689                                                                                   pl)))))
690                                                                    p)
691                                                                   ((lambda ()
692                                                                      (match:syntax-err
693                                                                        pattern
694                                                                        "syntax error in pattern"))))))))))
695                                        (ordlist (lambda (p)
696                                                   (cond
697                                                     ((null? p) '())
698                                                     ((pair? p) (cons (ordinary
699                                                                        (car p))
700                                                                      (ordlist
701                                                                        (cdr p))))
702                                                     (else (match:syntax-err
703                                                             pattern
704                                                             "invalid use of unquote-splicing in pattern"))))))
705                                 (ordinary pattern))))
706           (bound (lambda (pattern)
707                    (letrec ((pred-bodies '())
708                             (bound (lambda (p a k)
709                                      (cond
710                                        ((eq? '_ p) (k p a))
711                                        ((symbol? p) (if (memq p a)
712                                                         (match:syntax-err
713                                                           pattern
714                                                           "duplicate variable in pattern"))
715                                         (k p (cons p a)))
716                                        ((and (pair? p)
717                                              (eq? 'quote (car p))) (k p a))
718                                        ((and (pair? p) (eq? '? (car p))) (cond
719                                                                            ((not (null?
720                                                                                    (cddr p))) (bound
721                                                                                                 `(and (? ,(cadr p))
722                                                                                                       ,@(cddr p))
723                                                                                                 a
724                                                                                                 k))
725                                                                            ((or (not (symbol?
726                                                                                        (cadr p)))
727                                                                                 (memq (cadr p)
728                                                                                       a)) (let ((g (gensym)))
729                                                                                             (set! pred-bodies
730                                                                                               (cons `(,g ,(cadr p))
731                                                                                                     pred-bodies))
732                                                                                             (k `(? ,g)
733                                                                                                a)))
734                                                                            (else (k p
735                                                                                     a))))
736                                        ((and (pair? p) (eq? '= (car p))) (cond
737                                                                            ((or (not (symbol?
738                                                                                        (cadr p)))
739                                                                                 (memq (cadr p)
740                                                                                       a)) (let ((g (gensym)))
741                                                                                             (set! pred-bodies
742                                                                                               (cons `(,g ,(cadr p))
743                                                                                                     pred-bodies))
744                                                                                             (bound
745                                                                                               `(= ,g
746                                                                                                   ,(caddr
747                                                                                                      p))
748                                                                                               a
749                                                                                               k)))
750                                                                            (else (bound
751                                                                                    (caddr
752                                                                                      p)
753                                                                                    a
754                                                                                    (lambda (p2
755                                                                                             a)
756                                                                                      (k `(= ,(cadr p)
757                                                                                             ,p2)
758                                                                                         a))))))
759                                        ((and (pair? p) (eq? 'and (car p))) (bound*
760                                                                              (cdr p)
761                                                                              a
762                                                                              (lambda (p
763                                                                                       a)
764                                                                                (k `(and ,@p)
765                                                                                   a))))
766                                        ((and (pair? p) (eq? 'or (car p))) (bound
767                                                                             (cadr p)
768                                                                             a
769                                                                             (lambda (first-p
770                                                                                      first-a)
771                                                                               (let or* ((plist (cddr p))
772                                                                                         (k (lambda (plist)
773                                                                                              (k `(or ,first-p
774                                                                                                      ,@plist)
775                                                                                                 first-a))))
776                                                                                 (if (null?
777                                                                                       plist)
778                                                                                     (k plist)
779                                                                                     (bound
780                                                                                       (car plist)
781                                                                                       a
782                                                                                       (lambda (car-p
783                                                                                                car-a)
784                                                                                         (if (not (permutation
785                                                                                                    car-a
786                                                                                                    first-a))
787                                                                                             (match:syntax-err
788                                                                                               pattern
789                                                                                               "variables of or-pattern differ in"))
790                                                                                         (or* (cdr plist)
791                                                                                              (lambda (cdr-p)
792                                                                                                (k (cons car-p
793                                                                                                         cdr-p)))))))))))
794                                        ((and (pair? p) (eq? 'not (car p))) (cond
795                                                                              ((not (null?
796                                                                                      (cddr p))) (bound
797                                                                                                   `(not (or ,@(cdr p)))
798                                                                                                   a
799                                                                                                   k))
800                                                                              (else (bound
801                                                                                      (cadr p)
802                                                                                      a
803                                                                                      (lambda (p2
804                                                                                               a2)
805                                                                                        (if (not (permutation
806                                                                                                   a
807                                                                                                   a2))
808                                                                                            (match:syntax-err
809                                                                                              p
810                                                                                              "no variables allowed in"))
811                                                                                        (k `(not ,p2)
812                                                                                           a))))))
813                                        ((and (pair? p)
814                                              (pair? (cdr p))
815                                              (dot-dot-k? (cadr p))) (bound
816                                                                       (car p)
817                                                                       a
818                                                                       (lambda (q
819                                                                                b)
820                                                                         (let ((bvars (find-prefix
821                                                                                        b
822                                                                                        a)))
823                                                                           (k `(,q ,(cadr p)
824                                                                                   ,bvars
825                                                                                   ,(gensym)
826                                                                                   ,(gensym)
827                                                                                   ,(map (lambda (_)
828                                                                                           (gensym))
829                                                                                         bvars))
830                                                                              b)))))
831                                        ((and (pair? p) (eq? '$ (car p))) (bound*
832                                                                            (cddr p)
833                                                                            a
834                                                                            (lambda (p1
835                                                                                     a)
836                                                                              (k `($ ,(cadr p)
837                                                                                     ,@p1)
838                                                                                 a))))
839                                        ((and (pair? p)
840                                              (eq? 'set! (car p))) (if (memq (cadr p)
841                                                                             a)
842                                                                       (k p
843                                                                          a)
844                                                                       (k p
845                                                                          (cons (cadr p)
846                                                                                a))))
847                                        ((and (pair? p)
848                                              (eq? 'get! (car p))) (if (memq (cadr p)
849                                                                             a)
850                                                                       (k p
851                                                                          a)
852                                                                       (k p
853                                                                          (cons (cadr p)
854                                                                                a))))
855                                        ((pair? p) (bound
856                                                     (car p)
857                                                     a
858                                                     (lambda (car-p a)
859                                                       (bound
860                                                         (cdr p)
861                                                         a
862                                                         (lambda (cdr-p a)
863                                                           (k (cons car-p
864                                                                    cdr-p)
865                                                              a))))))
866                                        ((vector? p) (boundv
867                                                       (vector->list p)
868                                                       a
869                                                       (lambda (pl a)
870                                                         (k (list->vector
871                                                              pl)
872                                                            a))))
873                                        (else (k p a)))))
874                             (boundv (lambda (plist a k)
875                                       (let ((g115 (lambda () (k plist a))))
876                                         (if (pair? plist)
877                                             (if (and (pair? (cdr plist))
878                                                      (dot-dot-k?
879                                                        (cadr plist))
880                                                      (null? (cddr plist)))
881                                                 ((lambda ()
882                                                    (bound plist a k)))
883                                                 (if (null? plist)
884                                                     (g115)
885                                                     ((lambda (x y)
886                                                        (bound
887                                                          x
888                                                          a
889                                                          (lambda (car-p a)
890                                                            (boundv
891                                                              y
892                                                              a
893                                                              (lambda (cdr-p
894                                                                       a)
895                                                                (k (cons car-p
896                                                                         cdr-p)
897                                                                   a))))))
898                                                      (car plist)
899                                                      (cdr plist))))
900                                             (if (null? plist)
901                                                 (g115)
902                                                 (match:error plist))))))
903                             (bound* (lambda (plist a k)
904                                       (if (null? plist)
905                                           (k plist a)
906                                           (bound
907                                             (car plist)
908                                             a
909                                             (lambda (car-p a)
910                                               (bound*
911                                                 (cdr plist)
912                                                 a
913                                                 (lambda (cdr-p a)
914                                                   (k (cons car-p cdr-p)
915                                                      a))))))))
916                             (find-prefix (lambda (b a)
917                                            (if (eq? b a)
918                                                '()
919                                                (cons (car b)
920                                                      (find-prefix
921                                                        (cdr b)
922                                                        a)))))
923                             (permutation (lambda (p1 p2)
924                                            (and (= (length p1)
925                                                    (length p2))
926                                                 (match:andmap
927                                                   (lambda (x1)
928                                                     (memq x1 p2))
929                                                   p1)))))
930                      (bound
931                        pattern
932                        '()
933                        (lambda (p a) (list p (reverse a) pred-bodies))))))
934           (inline-let (lambda (let-exp)
935                         (letrec ((occ (lambda (x e)
936                                         (let loop ((e e))
937                                           (cond
938                                             ((pair? e) (+ (loop (car e))
939                                                           (loop (cdr e))))
940                                             ((eq? x e) 1)
941                                             (else 0)))))
942                                  (subst (lambda (e old new)
943                                           (let loop ((e e))
944                                             (cond
945                                               ((pair? e) (cons (loop (car e))
946                                                                (loop (cdr e))))
947                                               ((eq? old e) new)
948                                               (else e)))))
949                                  (const? (lambda (sexp)
950                                            (or (symbol? sexp)
951                                                (boolean? sexp)
952                                                (string? sexp)
953                                                (char? sexp)
954                                                (number? sexp)
955                                                (null? sexp)
956                                                (and (pair? sexp)
957                                                     (eq? (car sexp)
958                                                          'quote)
959                                                     (pair? (cdr sexp))
960                                                     (symbol? (cadr sexp))
961                                                     (null? (cddr sexp))))))
962                                  (isval? (lambda (sexp)
963                                            (or (const? sexp)
964                                                (and (pair? sexp)
965                                                     (memq (car sexp)
966                                                           '(lambda quote
967                                                              match-lambda
968                                                              match-lambda*))))))
969                                  (small? (lambda (sexp)
970                                            (or (const? sexp)
971                                                (and (pair? sexp)
972                                                     (eq? (car sexp)
973                                                          'lambda)
974                                                     (pair? (cdr sexp))
975                                                     (pair? (cddr sexp))
976                                                     (const? (caddr sexp))
977                                                     (null?
978                                                       (cdddr sexp)))))))
979                           (let loop ((b (cadr let-exp))
980                                      (new-b '())
981                                      (e (caddr let-exp)))
982                             (cond
983                               ((null? b) (if (null? new-b)
984                                              e
985                                              `(let ,(reverse new-b) ,e)))
986                               ((isval? (cadr (car b))) (let* ((x (caar b))
987                                                               (n (occ x e)))
988                                                          (cond
989                                                            ((= 0 n) (loop (cdr b)
990                                                                           new-b
991                                                                           e))
992                                                            ((or (= 1 n)
993                                                                 (small?
994                                                                   (cadr (car b)))) (loop (cdr b)
995                                                                                          new-b
996                                                                                          (subst
997                                                                                            e
998                                                                                            x
999                                                                                            (cadr (car b)))))
1000                                                            (else (loop (cdr b)
1001                                                                        (cons (car b)
1002                                                                              new-b)
1003                                                                        e)))))
1004                               (else (loop (cdr b) (cons (car b) new-b) e)))))))
1005           (gen (lambda (x sf plist erract length>= eta)
1006                  (if (null? plist)
1007                      (erract x)
1008                      (let* ((v '())
1009                             (val (lambda (x) (cdr (assq x v))))
1010                             (fail (lambda (sf)
1011                                     (gen x
1012                                          sf
1013                                          (cdr plist)
1014                                          erract
1015                                          length>=
1016                                          eta)))
1017                             (success (lambda (sf)
1018                                        (set-car! (cddddr (car plist)) #t)
1019                                        (let* ((code (cadr (car plist)))
1020                                               (bv (caddr (car plist)))
1021                                               (fail-sym (cadddr
1022                                                           (car plist))))
1023                                          (if fail-sym
1024                                              (let ((ap `(,code
1025                                                           ,fail-sym
1026                                                           ,@(map val bv))))
1027                                                `(call-with-current-continuation
1028                                                   (lambda (,fail-sym)
1029                                                     (let ((,fail-sym (lambda ()
1030                                                                        (,fail-sym
1031                                                                          ,(fail sf)))))
1032                                                       ,ap))))
1033                                              `(,code ,@(map val bv)))))))
1034                        (let next ((p (caar plist))
1035                                   (e x)
1036                                   (sf sf)
1037                                   (kf fail)
1038                                   (ks success))
1039                          (cond
1040                            ((eq? '_ p) (ks sf))
1041                            ((symbol? p) (set! v (cons (cons p e) v))
1042                             (ks sf))
1043                            ((null? p) (emit `(null? ,e) sf kf ks))
1044                            ((equal? p ''()) (emit `(null? ,e) sf kf ks))
1045                            ((string? p) (emit `(equal? ,e ,p) sf kf ks))
1046                            ((boolean? p) (emit `(equal? ,e ,p) sf kf ks))
1047                            ((char? p) (emit `(equal? ,e ,p) sf kf ks))
1048                            ((number? p) (emit `(equal? ,e ,p) sf kf ks))
1049                            ((and (pair? p) (eq? 'quote (car p))) (emit `(equal?
1050                                                                           ,e
1051                                                                           ,p)
1052                                                                        sf
1053                                                                        kf
1054                                                                        ks))
1055                            ((and (pair? p) (eq? '? (car p))) (let ((tst `(,(cadr p)
1056                                                                            ,e)))
1057                                                                (emit tst
1058                                                                      sf
1059                                                                      kf
1060                                                                      ks)))
1061                            ((and (pair? p) (eq? '= (car p))) (next (caddr
1062                                                                      p)
1063                                                                    `(,(cadr p)
1064                                                                       ,e)
1065                                                                    sf
1066                                                                    kf
1067                                                                    ks))
1068                            ((and (pair? p) (eq? 'and (car p))) (let loop ((p (cdr p))
1069                                                                           (sf sf))
1070                                                                  (if (null?
1071                                                                        p)
1072                                                                      (ks sf)
1073                                                                      (next (car p)
1074                                                                            e
1075                                                                            sf
1076                                                                            kf
1077                                                                            (lambda (sf)
1078                                                                              (loop (cdr p)
1079                                                                                    sf))))))
1080                            ((and (pair? p) (eq? 'or (car p))) (let ((or-v v))
1081                                                                 (let loop ((p (cdr p))
1082                                                                            (sf sf))
1083                                                                   (if (null?
1084                                                                         p)
1085                                                                       (kf sf)
1086                                                                       (begin (set! v
1087                                                                                or-v)
1088                                                                              (next (car p)
1089                                                                                    e
1090                                                                                    sf
1091                                                                                    (lambda (sf)
1092                                                                                      (loop (cdr p)
1093                                                                                            sf))
1094                                                                                    ks))))))
1095                            ((and (pair? p) (eq? 'not (car p))) (next (cadr p)
1096                                                                      e
1097                                                                      sf
1098                                                                      ks
1099                                                                      kf))
1100                            ((and (pair? p) (eq? '$ (car p))) (let* ((tag (cadr p))
1101                                                                     (fields (cdr p))
1102                                                                     (rlen (length
1103                                                                             fields))
1104                                                                     (tst `(,(symbol-append
1105                                                                               tag
1106                                                                               '?)
1107                                                                             ,e)))
1108                                                                (emit tst
1109                                                                      sf
1110                                                                      kf
1111                                                                      (let rloop ((n 1))
1112                                                                        (lambda (sf)
1113                                                                          (if (= n
1114                                                                                 rlen)
1115                                                                              (ks sf)
1116                                                                              (next (list-ref
1117                                                                                      fields
1118                                                                                      n)
1119                                                                                    `(,(symbol-append
1120                                                                                         tag
1121                                                                                         '-
1122                                                                                         n)
1123                                                                                       ,e)
1124                                                                                    sf
1125                                                                                    kf
1126                                                                                    (rloop
1127                                                                                      (+ 1
1128                                                                                         n)))))))))
1129                            ((and (pair? p) (eq? 'set! (car p))) (set! v
1130                                                                   (cons (cons (cadr p)
1131                                                                               (setter
1132                                                                                 e
1133                                                                                 p))
1134                                                                         v))
1135                             (ks sf))
1136                            ((and (pair? p) (eq? 'get! (car p))) (set! v
1137                                                                   (cons (cons (cadr p)
1138                                                                               (getter
1139                                                                                 e
1140                                                                                 p))
1141                                                                         v))
1142                             (ks sf))
1143                            ((and (pair? p)
1144                                  (pair? (cdr p))
1145                                  (dot-dot-k? (cadr p))) (emit `(list? ,e)
1146                                                               sf
1147                                                               kf
1148                                                               (lambda (sf)
1149                                                                 (let* ((k (dot-dot-k?
1150                                                                             (cadr p)))
1151                                                                        (ks (lambda (sf)
1152                                                                              (let ((bound (list-ref
1153                                                                                             p
1154                                                                                             2)))
1155                                                                                (cond
1156                                                                                  ((eq? (car p)
1157                                                                                        '_) (ks sf))
1158                                                                                  ((null?
1159                                                                                     bound) (let* ((ptst (next (car p)
1160                                                                                                               eta
1161                                                                                                               sf
1162                                                                                                               (lambda (sf)
1163                                                                                                                 #f)
1164                                                                                                               (lambda (sf)
1165                                                                                                                 #t)))
1166                                                                                                   (tst (if (and (pair?
1167                                                                                                                   ptst)
1168                                                                                                                 (symbol?
1169                                                                                                                   (car ptst))
1170                                                                                                                 (pair?
1171                                                                                                                   (cdr ptst))
1172                                                                                                                 (eq? eta
1173                                                                                                                      (cadr ptst))
1174                                                                                                                 (null?
1175                                                                                                                   (cddr ptst)))
1176                                                                                                            (car ptst)
1177                                                                                                            `(lambda (,eta)
1178                                                                                                               ,ptst))))
1179                                                                                              (assm `(match:andmap
1180                                                                                                       ,tst
1181                                                                                                       ,e)
1182                                                                                                    (kf sf)
1183                                                                                                    (ks sf))))
1184                                                                                  ((and (symbol?
1185                                                                                          (car p))
1186                                                                                        (equal?
1187                                                                                          (list (car p))
1188                                                                                          bound)) (next (car p)
1189                                                                                                        e
1190                                                                                                        sf
1191                                                                                                        kf
1192                                                                                                        ks))
1193                                                                                  (else (let* ((gloop (list-ref
1194                                                                                                        p
1195                                                                                                        3))
1196                                                                                               (ge (list-ref
1197                                                                                                     p
1198                                                                                                     4))
1199                                                                                               (fresh (list-ref
1200                                                                                                        p
1201                                                                                                        5))
1202                                                                                               (p1 (next (car p)
1203                                                                                                         `(car ,ge)
1204                                                                                                         sf
1205                                                                                                         kf
1206                                                                                                         (lambda (sf)
1207                                                                                                           `(,gloop
1208                                                                                                              (cdr ,ge)
1209                                                                                                              ,@(map (lambda (b
1210                                                                                                                              f)
1211                                                                                                                       `(cons ,(val b)
1212                                                                                                                              ,f))
1213                                                                                                                     bound
1214                                                                                                                     fresh))))))
1215                                                                                          (set! v
1216                                                                                            (append
1217                                                                                              (map cons
1218                                                                                                   bound
1219                                                                                                   (map (lambda (x)
1220                                                                                                          `(reverse
1221                                                                                                             ,x))
1222                                                                                                        fresh))
1223                                                                                              v))
1224                                                                                          `(let ,gloop
1225                                                                                             ((,ge ,e)
1226                                                                                              ,@(map (lambda (x)
1227                                                                                                       `(,x '()))
1228                                                                                                     fresh))
1229                                                                                             (if (null?
1230                                                                                                   ,ge)
1231                                                                                                 ,(ks sf)
1232                                                                                                 ,p1)))))))))
1233                                                                   (case k
1234                                                                     ((0) (ks sf))
1235                                                                     ((1) (emit `(pair?
1236                                                                                   ,e)
1237                                                                                sf
1238                                                                                kf
1239                                                                                ks))
1240                                                                     (else (emit `((,length>=
1241                                                                                     ,k)
1242                                                                                   ,e)
1243                                                                                 sf
1244                                                                                 kf
1245                                                                                 ks)))))))
1246                            ((pair? p) (emit `(pair? ,e)
1247                                             sf
1248                                             kf
1249                                             (lambda (sf)
1250                                               (next (car p)
1251                                                     (add-a e)
1252                                                     sf
1253                                                     kf
1254                                                     (lambda (sf)
1255                                                       (next (cdr p)
1256                                                             (add-d e)
1257                                                             sf
1258                                                             kf
1259                                                             ks))))))
1260                            ((and (vector? p)
1261                                  (>= (vector-length p) 6)
1262                                  (dot-dot-k?
1263                                    (vector-ref
1264                                      p
1265                                      (- (vector-length p) 5)))) (let* ((vlen (- (vector-length
1266                                                                                   p)
1267                                                                                 6))
1268                                                                        (k (dot-dot-k?
1269                                                                             (vector-ref
1270                                                                               p
1271                                                                               (+ vlen
1272                                                                                  1))))
1273                                                                        (minlen (+ vlen
1274                                                                                   k))
1275                                                                        (bound (vector-ref
1276                                                                                 p
1277                                                                                 (+ vlen
1278                                                                                    2))))
1279                                                                   (emit `(vector?
1280                                                                            ,e)
1281                                                                         sf
1282                                                                         kf
1283                                                                         (lambda (sf)
1284                                                                           (assm `(>= (vector-length
1285                                                                                        ,e)
1286                                                                                      ,minlen)
1287                                                                                 (kf sf)
1288                                                                                 ((let vloop ((n 0))
1289                                                                                    (lambda (sf)
1290                                                                                      (cond
1291                                                                                        ((not (= n
1292                                                                                                 vlen)) (next (vector-ref
1293                                                                                                                p
1294                                                                                                                n)
1295                                                                                                              `(vector-ref
1296                                                                                                                 ,e
1297                                                                                                                 ,n)
1298                                                                                                              sf
1299                                                                                                              kf
1300                                                                                                              (vloop
1301                                                                                                                (+ 1
1302                                                                                                                   n))))
1303                                                                                        ((eq? (vector-ref
1304                                                                                                p
1305                                                                                                vlen)
1306                                                                                              '_) (ks sf))
1307                                                                                        (else (let* ((gloop (vector-ref
1308                                                                                                              p
1309                                                                                                              (+ vlen
1310                                                                                                                 3)))
1311                                                                                                     (ind (vector-ref
1312                                                                                                            p
1313                                                                                                            (+ vlen
1314                                                                                                               4)))
1315                                                                                                     (fresh (vector-ref
1316                                                                                                              p
1317                                                                                                              (+ vlen
1318                                                                                                                 5)))
1319                                                                                                     (p1 (next (vector-ref
1320                                                                                                                 p
1321                                                                                                                 vlen)
1322                                                                                                               `(vector-ref
1323                                                                                                                  ,e
1324                                                                                                                  ,ind)
1325                                                                                                               sf
1326                                                                                                               kf
1327                                                                                                               (lambda (sf)
1328                                                                                                                 `(,gloop
1329                                                                                                                    (- ,ind
1330                                                                                                                       1)
1331                                                                                                                    ,@(map (lambda (b
1332                                                                                                                                    f)
1333                                                                                                                             `(cons ,(val b)
1334                                                                                                                                    ,f))
1335                                                                                                                           bound
1336                                                                                                                           fresh))))))
1337                                                                                                (set! v
1338                                                                                                  (append
1339                                                                                                    (map cons
1340                                                                                                         bound
1341                                                                                                         fresh)
1342                                                                                                    v))
1343                                                                                                `(let ,gloop
1344                                                                                                   ((,ind (- (vector-length
1345                                                                                                               ,e)
1346                                                                                                             1))
1347                                                                                                    ,@(map (lambda (x)
1348                                                                                                             `(,x '()))
1349                                                                                                           fresh))
1350                                                                                                   (if (> ,minlen
1351                                                                                                          ,ind)
1352                                                                                                       ,(ks sf)
1353                                                                                                       ,p1)))))))
1354                                                                                  sf))))))
1355                            ((vector? p) (let ((vlen (vector-length p)))
1356                                           (emit `(vector? ,e)
1357                                                 sf
1358                                                 kf
1359                                                 (lambda (sf)
1360                                                   (emit `(equal?
1361                                                            (vector-length
1362                                                              ,e)
1363                                                            ,vlen)
1364                                                         sf
1365                                                         kf
1366                                                         (let vloop ((n 0))
1367                                                           (lambda (sf)
1368                                                             (if (= n vlen)
1369                                                                 (ks sf)
1370                                                                 (next (vector-ref
1371                                                                         p
1372                                                                         n)
1373                                                                       `(vector-ref
1374                                                                          ,e
1375                                                                          ,n)
1376                                                                       sf
1377                                                                       kf
1378                                                                       (vloop
1379                                                                         (+ 1
1380                                                                            n)))))))))))
1381                            (else (display
1382                                    "FATAL ERROR IN PATTERN MATCHER")
1383                             (newline)
1384                             (error #f "THIS NEVER HAPPENS"))))))))
1385           (emit (lambda (tst sf kf ks)
1386                   (cond
1387                     ((in tst sf) (ks sf))
1388                     ((in `(not ,tst) sf) (kf sf))
1389                     (else (let* ((e (cadr tst))
1390                                  (implied (cond
1391                                             ((eq? (car tst) 'equal?) (let ((p (caddr
1392                                                                                 tst)))
1393                                                                        (cond
1394                                                                          ((string?
1395                                                                             p) `((string?
1396                                                                                    ,e)))
1397                                                                          ((boolean?
1398                                                                             p) `((boolean?
1399                                                                                    ,e)))
1400                                                                          ((char?
1401                                                                             p) `((char?
1402                                                                                    ,e)))
1403                                                                          ((number?
1404                                                                             p) `((number?
1405                                                                                    ,e)))
1406                                                                          ((and (pair?
1407                                                                                  p)
1408                                                                                (eq? 'quote
1409                                                                                     (car p))) `((symbol?
1410                                                                                                   ,e)))
1411                                                                          (else '()))))
1412                                             ((eq? (car tst) 'null?) `((list?
1413                                                                         ,e)))
1414                                             ((vec-structure? tst) `((vector?
1415                                                                       ,e)))
1416                                             (else '())))
1417                                  (not-imp (case (car tst)
1418                                             ((list?) `((not (null? ,e))))
1419                                             (else '())))
1420                                  (s (ks (cons tst (append implied sf))))
1421                                  (k (kf (cons `(not ,tst)
1422                                               (append not-imp sf)))))
1423                             (assm tst k s))))))
1424           (assm (lambda (tst f s)
1425                   (cond
1426                     ((equal? s f) s)
1427                     ((and (eq? s #t) (eq? f #f)) tst)
1428                     ((and (eq? (car tst) 'pair?)
1429                           (memq match:error-control '(unspecified fail))
1430                           (memq (car f) '(cond match:error))
1431                           (guarantees s (cadr tst))) s)
1432                     ((and (pair? s)
1433                           (eq? (car s) 'if)
1434                           (equal? (cadddr s) f)) (if (eq? (car (cadr s))
1435                                                           'and)
1436                                                      `(if (and ,tst
1437                                                                ,@(cdr (cadr s)))
1438                                                           ,(caddr s)
1439                                                           ,f)
1440                                                      `(if (and ,tst
1441                                                                ,(cadr s))
1442                                                           ,(caddr s)
1443                                                           ,f)))
1444                     ((and (pair? s)
1445                           (equal? (car s) 'call-with-current-continuation)
1446                           (pair? (cdr s))
1447                           (pair? (cadr s))
1448                           (equal? (caadr s) 'lambda)
1449                           (pair? (cdadr s))
1450                           (pair? (cadadr s))
1451                           (null? (cdr (cadadr s)))
1452                           (pair? (cddadr s))
1453                           (pair? (car (cddadr s)))
1454                           (equal? (caar (cddadr s)) 'let)
1455                           (pair? (cdar (cddadr s)))
1456                           (pair? (cadar (cddadr s)))
1457                           (pair? (caadar (cddadr s)))
1458                           (pair? (cdr (caadar (cddadr s))))
1459                           (pair? (cadr (caadar (cddadr s))))
1460                           (equal? (caadr (caadar (cddadr s))) 'lambda)
1461                           (pair? (cdadr (caadar (cddadr s))))
1462                           (null? (cadadr (caadar (cddadr s))))
1463                           (pair? (cddadr (caadar (cddadr s))))
1464                           (pair? (car (cddadr (caadar (cddadr s)))))
1465                           (pair? (cdar (cddadr (caadar (cddadr s)))))
1466                           (null? (cddar (cddadr (caadar (cddadr s)))))
1467                           (null? (cdr (cddadr (caadar (cddadr s)))))
1468                           (null? (cddr (caadar (cddadr s))))
1469                           (null? (cdadar (cddadr s)))
1470                           (pair? (cddar (cddadr s)))
1471                           (null? (cdddar (cddadr s)))
1472                           (null? (cdr (cddadr s)))
1473                           (null? (cddr s))
1474                           (equal? f (cadar (cddadr (caadar (cddadr s)))))) (let ((k (car (cadadr
1475                                                                                            s)))
1476                                                                                  (fail (car (caadar
1477                                                                                               (cddadr
1478                                                                                                 s))))
1479                                                                                  (s2 (caddar
1480                                                                                        (cddadr
1481                                                                                          s))))
1482                                                                              `(call-with-current-continuation
1483                                                                                 (lambda (,k)
1484                                                                                   (let ((,fail (lambda ()
1485                                                                                                  (,k ,f))))
1486                                                                                     ,(assm tst
1487                                                                                            `(,fail)
1488                                                                                            s2))))))
1489                     ((and #f
1490                           (pair? s)
1491                           (equal? (car s) 'let)
1492                           (pair? (cdr s))
1493                           (pair? (cadr s))
1494                           (pair? (caadr s))
1495                           (pair? (cdaadr s))
1496                           (pair? (car (cdaadr s)))
1497                           (equal? (caar (cdaadr s)) 'lambda)
1498                           (pair? (cdar (cdaadr s)))
1499                           (null? (cadar (cdaadr s)))
1500                           (pair? (cddar (cdaadr s)))
1501                           (null? (cdddar (cdaadr s)))
1502                           (null? (cdr (cdaadr s)))
1503                           (null? (cdadr s))
1504                           (pair? (cddr s))
1505                           (null? (cdddr s))
1506                           (equal? (caddar (cdaadr s)) f)) (let ((fail (caaadr
1507                                                                         s))
1508                                                                 (s2 (caddr
1509                                                                       s)))
1510                                                             `(let ((,fail (lambda ()
1511                                                                             ,f)))
1512                                                                ,(assm tst
1513                                                                       `(,fail)
1514                                                                       s2))))
1515                     (else `(if ,tst ,s ,f)))))
1516           (guarantees (lambda (code x)
1517                         (let ((a (add-a x)) (d (add-d x)))
1518                           (let loop ((code code))
1519                             (cond
1520                               ((not (pair? code)) #f)
1521                               ((memq (car code) '(cond match:error)) #t)
1522                               ((or (equal? code a) (equal? code d)) #t)
1523                               ((eq? (car code) 'if) (or (loop (cadr code))
1524                                                         (and (loop (caddr
1525                                                                      code))
1526                                                              (loop (cadddr
1527                                                                      code)))))
1528                               ((eq? (car code) 'lambda) #f)
1529                               ((and (eq? (car code) 'let)
1530                                     (symbol? (cadr code))) #f)
1531                               (else (or (loop (car code))
1532                                         (loop (cdr code)))))))))
1533           (in (lambda (e l)
1534                 (or (member e l)
1535                     (and (eq? (car e) 'list?)
1536                          (or (member `(null? ,(cadr e)) l)
1537                              (member `(pair? ,(cadr e)) l)))
1538                     (and (eq? (car e) 'not)
1539                          (let* ((srch (cadr e))
1540                                 (const-class (equal-test? srch)))
1541                            (cond
1542                              (const-class (let mem ((l l))
1543                                             (if (null? l)
1544                                                 #f
1545                                                 (let ((x (car l)))
1546                                                   (or (and (equal?
1547                                                              (cadr x)
1548                                                              (cadr srch))
1549                                                            (disjoint? x)
1550                                                            (not (equal?
1551                                                                   const-class
1552                                                                   (car x))))
1553                                                       (equal?
1554                                                         x
1555                                                         `(not (,const-class
1556                                                                 ,(cadr srch))))
1557                                                       (and (equal?
1558                                                              (cadr x)
1559                                                              (cadr srch))
1560                                                            (equal-test? x)
1561                                                            (not (equal?
1562                                                                   (caddr
1563                                                                     srch)
1564                                                                   (caddr
1565                                                                     x))))
1566                                                       (mem (cdr l)))))))
1567                              ((disjoint? srch) (let mem ((l l))
1568                                                  (if (null? l)
1569                                                      #f
1570                                                      (let ((x (car l)))
1571                                                        (or (and (equal?
1572                                                                   (cadr x)
1573                                                                   (cadr srch))
1574                                                                 (disjoint?
1575                                                                   x)
1576                                                                 (not (equal?
1577                                                                        (car x)
1578                                                                        (car srch))))
1579                                                            (mem (cdr l)))))))
1580                              ((eq? (car srch) 'list?) (let mem ((l l))
1581                                                         (if (null? l)
1582                                                             #f
1583                                                             (let ((x (car l)))
1584                                                               (or (and (equal?
1585                                                                          (cadr x)
1586                                                                          (cadr srch))
1587                                                                        (disjoint?
1588                                                                          x)
1589                                                                        (not (memq (car x)
1590                                                                                   '(list?
1591                                                                                      pair?
1592                                                                                      null?))))
1593                                                                   (mem (cdr l)))))))
1594                              ((vec-structure? srch) (let mem ((l l))
1595                                                       (if (null? l)
1596                                                           #f
1597                                                           (let ((x (car l)))
1598                                                             (or (and (equal?
1599                                                                        (cadr x)
1600                                                                        (cadr srch))
1601                                                                      (or (disjoint?
1602                                                                            x)
1603                                                                          (vec-structure?
1604                                                                            x))
1605                                                                      (not (equal?
1606                                                                             (car x)
1607                                                                             'vector?))
1608                                                                      (not (equal?
1609                                                                             (car x)
1610                                                                             (car srch))))
1611                                                                 (equal?
1612                                                                   x
1613                                                                   `(not (vector?
1614                                                                           ,(cadr srch))))
1615                                                                 (mem (cdr l)))))))
1616                              (else #f)))))))
1617           (equal-test? (lambda (tst)
1618                          (and (eq? (car tst) 'equal?)
1619                               (let ((p (caddr tst)))
1620                                 (cond
1621                                   ((string? p) 'string?)
1622                                   ((boolean? p) 'boolean?)
1623                                   ((char? p) 'char?)
1624                                   ((number? p) 'number?)
1625                                   ((and (pair? p)
1626                                         (pair? (cdr p))
1627                                         (null? (cddr p))
1628                                         (eq? 'quote (car p))
1629                                         (symbol? (cadr p))) 'symbol?)
1630                                   (else #f))))))
1631           (disjoint? (lambda (tst)
1632                        (memq (car tst) match:disjoint-predicates)))
1633           (vec-structure? (lambda (tst)
1634                             (memq (car tst) match:vector-structures)))
1635           (add-a (lambda (a)
1636                    (let ((new (and (pair? a) (assq (car a) c---rs))))
1637                      (if new (cons (cadr new) (cdr a)) `(car ,a)))))
1638           (add-d (lambda (a)
1639                    (let ((new (and (pair? a) (assq (car a) c---rs))))
1640                      (if new (cons (cddr new) (cdr a)) `(cdr ,a)))))
1641           (c---rs '((car caar . cdar)
1642                     (cdr cadr . cddr)
1643                     (caar caaar . cdaar)
1644                     (cadr caadr . cdadr)
1645                     (cdar cadar . cddar)
1646                     (cddr caddr . cdddr)
1647                     (caaar caaaar . cdaaar)
1648                     (caadr caaadr . cdaadr)
1649                     (cadar caadar . cdadar)
1650                     (caddr caaddr . cdaddr)
1651                     (cdaar cadaar . cddaar)
1652                     (cdadr cadadr . cddadr)
1653                     (cddar caddar . cdddar)
1654                     (cdddr cadddr . cddddr)))
1655           (setter (lambda (e p)
1656                     (let ((mk-setter (lambda (s)
1657                                        (symbol-append 'set- s '!))))
1658                       (cond
1659                         ((not (pair? e)) (match:syntax-err
1660                                            p
1661                                            "unnested set! pattern"))
1662                         ((eq? (car e) 'vector-ref) `(let ((x ,(cadr e)))
1663                                                       (lambda (y)
1664                                                         (vector-set!
1665                                                           x
1666                                                           ,(caddr e)
1667                                                           y))))
1668                         ((eq? (car e) 'unbox) `(let ((x ,(cadr e)))
1669                                                  (lambda (y)
1670                                                    (set-box! x y))))
1671                         ((eq? (car e) 'car) `(let ((x ,(cadr e)))
1672                                                (lambda (y)
1673                                                  (set-car! x y))))
1674                         ((eq? (car e) 'cdr) `(let ((x ,(cadr e)))
1675                                                (lambda (y)
1676                                                  (set-cdr! x y))))
1677                         ((let ((a (assq (car e) get-c---rs)))
1678                            (and a
1679                                 `(let ((x (,(cadr a) ,(cadr e))))
1680                                    (lambda (y)
1681                                      (,(mk-setter (cddr a)) x y))))))
1682                         (else `(let ((x ,(cadr e)))
1683                                  (lambda (y) (,(mk-setter (car e)) x y))))))))
1684           (getter (lambda (e p)
1685                     (cond
1686                       ((not (pair? e)) (match:syntax-err
1687                                          p
1688                                          "unnested get! pattern"))
1689                       ((eq? (car e) 'vector-ref) `(let ((x ,(cadr e)))
1690                                                     (lambda ()
1691                                                       (vector-ref
1692                                                         x
1693                                                         ,(caddr e)))))
1694                       ((eq? (car e) 'unbox) `(let ((x ,(cadr e)))
1695                                                (lambda () (unbox x))))
1696                       ((eq? (car e) 'car) `(let ((x ,(cadr e)))
1697                                              (lambda () (car x))))
1698                       ((eq? (car e) 'cdr) `(let ((x ,(cadr e)))
1699                                              (lambda () (cdr x))))
1700                       ((let ((a (assq (car e) get-c---rs)))
1701                          (and a
1702                               `(let ((x (,(cadr a) ,(cadr e))))
1703                                  (lambda () (,(cddr a) x))))))
1704                       (else `(let ((x ,(cadr e)))
1705                                (lambda () (,(car e) x)))))))
1706           (get-c---rs '((caar car . car)
1707                         (cadr cdr . car)
1708                         (cdar car . cdr)
1709                         (cddr cdr . cdr)
1710                         (caaar caar . car)
1711                         (caadr cadr . car)
1712                         (cadar cdar . car)
1713                         (caddr cddr . car)
1714                         (cdaar caar . cdr)
1715                         (cdadr cadr . cdr)
1716                         (cddar cdar . cdr)
1717                         (cdddr cddr . cdr)
1718                         (caaaar caaar . car)
1719                         (caaadr caadr . car)
1720                         (caadar cadar . car)
1721                         (caaddr caddr . car)
1722                         (cadaar cdaar . car)
1723                         (cadadr cdadr . car)
1724                         (caddar cddar . car)
1725                         (cadddr cdddr . car)
1726                         (cdaaar caaar . cdr)
1727                         (cdaadr caadr . cdr)
1728                         (cdadar cadar . cdr)
1729                         (cdaddr caddr . cdr)
1730                         (cddaar cdaar . cdr)
1731                         (cddadr cdadr . cdr)
1732                         (cdddar cddar . cdr)
1733                         (cddddr cdddr . cdr)))
1734           (symbol-append (lambda l
1735                            (string->symbol
1736                              (apply
1737                                string-append
1738                                (map (lambda (x)
1739                                       (cond
1740                                         ((symbol? x) (symbol->string x))
1741                                         ((number? x) (number->string x))
1742                                         (else x)))
1743                                     l)))))
1744           (rac (lambda (l) (if (null? (cdr l)) (car l) (rac (cdr l)))))
1745           (rdc (lambda (l)
1746                  (if (null? (cdr l)) '() (cons (car l) (rdc (cdr l)))))))
1747    (list genmatch genletrec gendefine pattern-var?)))
1748(define-macro (match . args)
1749  (cond
1750    ((and (list? args)
1751          (<= 1 (length args))
1752          (match:andmap
1753            (lambda (y) (and (list? y) (<= 2 (length y))))
1754            (cdr args))) (let* ((exp (car args))
1755                                (clauses (cdr args))
1756                                (e (if (symbol? exp) exp (gensym))))
1757                           (if (symbol? exp)
1758                               ((car match:expanders)
1759                                e
1760                                clauses
1761                                `(match ,@args))
1762                               `(let ((,e ,exp))
1763                                  ,((car match:expanders)
1764                                    e
1765                                    clauses
1766                                    `(match ,@args))))))
1767    (else (match:syntax-err `(match ,@args) "syntax error in"))))
1768(define-macro (match-lambda . args)
1769  (if (and (list? args)
1770           (match:andmap
1771             (lambda (g126)
1772               (if (and (pair? g126) (list? (cdr g126)))
1773                   (pair? (cdr g126))
1774                   #f))
1775             args))
1776      ((lambda ()
1777         (let ((e (gensym))) `(lambda (,e) (match ,e ,@args)))))
1778      ((lambda ()
1779         (match:syntax-err
1780           `(match-lambda ,@args)
1781           "syntax error in")))))
1782(define-macro (match-lambda* . args)
1783  (if (and (list? args)
1784           (match:andmap
1785             (lambda (g134)
1786               (if (and (pair? g134) (list? (cdr g134)))
1787                   (pair? (cdr g134))
1788                   #f))
1789             args))
1790      ((lambda ()
1791         (let ((e (gensym))) `(lambda ,e (match ,e ,@args)))))
1792      ((lambda ()
1793         (match:syntax-err
1794           `(match-lambda* ,@args)
1795           "syntax error in")))))
1796(define-macro (match-let . args)
1797  (let ((g158 (lambda (pat exp body)
1798                `(match ,exp (,pat ,@body))))
1799        (g154 (lambda (pat exp body)
1800                (let ((g (map (lambda (x) (gensym)) pat))
1801                      (vpattern (list->vector pat)))
1802                  `(let ,(map list g exp)
1803                     (match (vector ,@g) (,vpattern ,@body))))))
1804        (g146 (lambda ()
1805                (match:syntax-err `(match-let ,@args) "syntax error in")))
1806        (g145 (lambda (p1 e1 p2 e2 body)
1807                (let ((g1 (gensym)) (g2 (gensym)))
1808                  `(let ((,g1 ,e1) (,g2 ,e2))
1809                     (match (cons ,g1 ,g2) ((,p1 . ,p2) ,@body))))))
1810        (g136 (cadddr match:expanders)))
1811    (if (pair? args)
1812        (if (symbol? (car args))
1813            (if (and (pair? (cdr args)) (list? (cadr args)))
1814                (let g161 ((g162 (cadr args)) (g160 '()) (g159 '()))
1815                  (if (null? g162)
1816                      (if (and (list? (cddr args)) (pair? (cddr args)))
1817                          ((lambda (name pat exp body)
1818                             (if (match:andmap
1819                                   (cadddr match:expanders)
1820                                   pat)
1821                                 `(let ,@args)
1822                                 `(letrec ((,name (match-lambda*
1823                                                    (,pat ,@body))))
1824                                    (,name ,@exp))))
1825                           (car args)
1826                           (reverse g159)
1827                           (reverse g160)
1828                           (cddr args))
1829                          (g146))
1830                      (if (and (pair? (car g162))
1831                               (pair? (cdar g162))
1832                               (null? (cddar g162)))
1833                          (g161 (cdr g162)
1834                                (cons (cadar g162) g160)
1835                                (cons (caar g162) g159))
1836                          (g146))))
1837                (g146))
1838            (if (list? (car args))
1839                (if (match:andmap
1840                      (lambda (g167)
1841                        (if (and (pair? g167)
1842                                 (g136 (car g167))
1843                                 (pair? (cdr g167)))
1844                            (null? (cddr g167))
1845                            #f))
1846                      (car args))
1847                    (if (and (list? (cdr args)) (pair? (cdr args)))
1848                        ((lambda () `(let ,@args)))
1849                        (let g149 ((g150 (car args)) (g148 '()) (g147 '()))
1850                          (if (null? g150)
1851                              (g146)
1852                              (if (and (pair? (car g150))
1853                                       (pair? (cdar g150))
1854                                       (null? (cddar g150)))
1855                                  (g149 (cdr g150)
1856                                        (cons (cadar g150) g148)
1857                                        (cons (caar g150) g147))
1858                                  (g146)))))
1859                    (if (and (pair? (car args))
1860                             (pair? (caar args))
1861                             (pair? (cdaar args))
1862                             (null? (cddaar args)))
1863                        (if (null? (cdar args))
1864                            (if (and (list? (cdr args)) (pair? (cdr args)))
1865                                (g158 (caaar args)
1866                                      (cadaar args)
1867                                      (cdr args))
1868                                (let g149 ((g150 (car args))
1869                                           (g148 '())
1870                                           (g147 '()))
1871                                  (if (null? g150)
1872                                      (g146)
1873                                      (if (and (pair? (car g150))
1874                                               (pair? (cdar g150))
1875                                               (null? (cddar g150)))
1876                                          (g149 (cdr g150)
1877                                                (cons (cadar g150) g148)
1878                                                (cons (caar g150) g147))
1879                                          (g146)))))
1880                            (if (and (pair? (cdar args))
1881                                     (pair? (cadar args))
1882                                     (pair? (cdadar args))
1883                                     (null? (cdr (cdadar args)))
1884                                     (null? (cddar args)))
1885                                (if (and (list? (cdr args))
1886                                         (pair? (cdr args)))
1887                                    (g145 (caaar args)
1888                                          (cadaar args)
1889                                          (caadar args)
1890                                          (car (cdadar args))
1891                                          (cdr args))
1892                                    (let g149 ((g150 (car args))
1893                                               (g148 '())
1894                                               (g147 '()))
1895                                      (if (null? g150)
1896                                          (g146)
1897                                          (if (and (pair? (car g150))
1898                                                   (pair? (cdar g150))
1899                                                   (null? (cddar g150)))
1900                                              (g149 (cdr g150)
1901                                                    (cons (cadar g150)
1902                                                          g148)
1903                                                    (cons (caar g150)
1904                                                          g147))
1905                                              (g146)))))
1906                                (let g149 ((g150 (car args))
1907                                           (g148 '())
1908                                           (g147 '()))
1909                                  (if (null? g150)
1910                                      (if (and (list? (cdr args))
1911                                               (pair? (cdr args)))
1912                                          (g154 (reverse g147)
1913                                                (reverse g148)
1914                                                (cdr args))
1915                                          (g146))
1916                                      (if (and (pair? (car g150))
1917                                               (pair? (cdar g150))
1918                                               (null? (cddar g150)))
1919                                          (g149 (cdr g150)
1920                                                (cons (cadar g150) g148)
1921                                                (cons (caar g150) g147))
1922                                          (g146))))))
1923                        (let g149 ((g150 (car args)) (g148 '()) (g147 '()))
1924                          (if (null? g150)
1925                              (if (and (list? (cdr args))
1926                                       (pair? (cdr args)))
1927                                  (g154 (reverse g147)
1928                                        (reverse g148)
1929                                        (cdr args))
1930                                  (g146))
1931                              (if (and (pair? (car g150))
1932                                       (pair? (cdar g150))
1933                                       (null? (cddar g150)))
1934                                  (g149 (cdr g150)
1935                                        (cons (cadar g150) g148)
1936                                        (cons (caar g150) g147))
1937                                  (g146))))))
1938                (if (pair? (car args))
1939                    (if (and (pair? (caar args))
1940                             (pair? (cdaar args))
1941                             (null? (cddaar args)))
1942                        (if (null? (cdar args))
1943                            (if (and (list? (cdr args)) (pair? (cdr args)))
1944                                (g158 (caaar args)
1945                                      (cadaar args)
1946                                      (cdr args))
1947                                (let g149 ((g150 (car args))
1948                                           (g148 '())
1949                                           (g147 '()))
1950                                  (if (null? g150)
1951                                      (g146)
1952                                      (if (and (pair? (car g150))
1953                                               (pair? (cdar g150))
1954                                               (null? (cddar g150)))
1955                                          (g149 (cdr g150)
1956                                                (cons (cadar g150) g148)
1957                                                (cons (caar g150) g147))
1958                                          (g146)))))
1959                            (if (and (pair? (cdar args))
1960                                     (pair? (cadar args))
1961                                     (pair? (cdadar args))
1962                                     (null? (cdr (cdadar args)))
1963                                     (null? (cddar args)))
1964                                (if (and (list? (cdr args))
1965                                         (pair? (cdr args)))
1966                                    (g145 (caaar args)
1967                                          (cadaar args)
1968                                          (caadar args)
1969                                          (car (cdadar args))
1970                                          (cdr args))
1971                                    (let g149 ((g150 (car args))
1972                                               (g148 '())
1973                                               (g147 '()))
1974                                      (if (null? g150)
1975                                          (g146)
1976                                          (if (and (pair? (car g150))
1977                                                   (pair? (cdar g150))
1978                                                   (null? (cddar g150)))
1979                                              (g149 (cdr g150)
1980                                                    (cons (cadar g150)
1981                                                          g148)
1982                                                    (cons (caar g150)
1983                                                          g147))
1984                                              (g146)))))
1985                                (let g149 ((g150 (car args))
1986                                           (g148 '())
1987                                           (g147 '()))
1988                                  (if (null? g150)
1989                                      (if (and (list? (cdr args))
1990                                               (pair? (cdr args)))
1991                                          (g154 (reverse g147)
1992                                                (reverse g148)
1993                                                (cdr args))
1994                                          (g146))
1995                                      (if (and (pair? (car g150))
1996                                               (pair? (cdar g150))
1997                                               (null? (cddar g150)))
1998                                          (g149 (cdr g150)
1999                                                (cons (cadar g150) g148)
2000                                                (cons (caar g150) g147))
2001                                          (g146))))))
2002                        (let g149 ((g150 (car args)) (g148 '()) (g147 '()))
2003                          (if (null? g150)
2004                              (if (and (list? (cdr args))
2005                                       (pair? (cdr args)))
2006                                  (g154 (reverse g147)
2007                                        (reverse g148)
2008                                        (cdr args))
2009                                  (g146))
2010                              (if (and (pair? (car g150))
2011                                       (pair? (cdar g150))
2012                                       (null? (cddar g150)))
2013                                  (g149 (cdr g150)
2014                                        (cons (cadar g150) g148)
2015                                        (cons (caar g150) g147))
2016                                  (g146)))))
2017                    (g146))))
2018        (g146))))
2019(define-macro (match-let* . args)
2020  (let ((g176 (lambda ()
2021                (match:syntax-err `(match-let* ,@args) "syntax error in"))))
2022    (if (pair? args)
2023        (if (null? (car args))
2024            (if (and (list? (cdr args)) (pair? (cdr args)))
2025                ((lambda (body) `(let* ,@args)) (cdr args))
2026                (g176))
2027            (if (and (pair? (car args))
2028                     (pair? (caar args))
2029                     (pair? (cdaar args))
2030                     (null? (cddaar args))
2031                     (list? (cdar args))
2032                     (list? (cdr args))
2033                     (pair? (cdr args)))
2034                ((lambda (pat exp rest body)
2035                   (if ((cadddr match:expanders) pat)
2036                       `(let ((,pat ,exp)) (match-let* ,rest ,@body))
2037                       `(match ,exp (,pat (match-let* ,rest ,@body)))))
2038                 (caaar args)
2039                 (cadaar args)
2040                 (cdar args)
2041                 (cdr args))
2042                (g176)))
2043        (g176))))
2044(define-macro (match-letrec . args)
2045  (let ((g200 (cadddr match:expanders))
2046        (g199 (lambda (p1 e1 p2 e2 body)
2047                `(match-letrec (((,p1 . ,p2) (cons ,e1 ,e2))) ,@body)))
2048        (g195 (lambda ()
2049                (match:syntax-err
2050                  `(match-letrec ,@args)
2051                  "syntax error in")))
2052        (g194 (lambda (pat exp body)
2053                `(match-letrec
2054                   ((,(list->vector pat) (vector ,@exp)))
2055                   ,@body)))
2056        (g186 (lambda (pat exp body)
2057                ((cadr match:expanders)
2058                 pat
2059                 exp
2060                 body
2061                 `(match-letrec ((,pat ,exp)) ,@body)))))
2062    (if (pair? args)
2063        (if (list? (car args))
2064            (if (match:andmap
2065                  (lambda (g206)
2066                    (if (and (pair? g206)
2067                             (g200 (car g206))
2068                             (pair? (cdr g206)))
2069                        (null? (cddr g206))
2070                        #f))
2071                  (car args))
2072                (if (and (list? (cdr args)) (pair? (cdr args)))
2073                    ((lambda () `(letrec ,@args)))
2074                    (let g189 ((g190 (car args)) (g188 '()) (g187 '()))
2075                      (if (null? g190)
2076                          (g195)
2077                          (if (and (pair? (car g190))
2078                                   (pair? (cdar g190))
2079                                   (null? (cddar g190)))
2080                              (g189 (cdr g190)
2081                                    (cons (cadar g190) g188)
2082                                    (cons (caar g190) g187))
2083                              (g195)))))
2084                (if (and (pair? (car args))
2085                         (pair? (caar args))
2086                         (pair? (cdaar args))
2087                         (null? (cddaar args)))
2088                    (if (null? (cdar args))
2089                        (if (and (list? (cdr args)) (pair? (cdr args)))
2090                            (g186 (caaar args) (cadaar args) (cdr args))
2091                            (let g189 ((g190 (car args))
2092                                       (g188 '())
2093                                       (g187 '()))
2094                              (if (null? g190)
2095                                  (g195)
2096                                  (if (and (pair? (car g190))
2097                                           (pair? (cdar g190))
2098                                           (null? (cddar g190)))
2099                                      (g189 (cdr g190)
2100                                            (cons (cadar g190) g188)
2101                                            (cons (caar g190) g187))
2102                                      (g195)))))
2103                        (if (and (pair? (cdar args))
2104                                 (pair? (cadar args))
2105                                 (pair? (cdadar args))
2106                                 (null? (cdr (cdadar args)))
2107                                 (null? (cddar args)))
2108                            (if (and (list? (cdr args)) (pair? (cdr args)))
2109                                (g199 (caaar args)
2110                                      (cadaar args)
2111                                      (caadar args)
2112                                      (car (cdadar args))
2113                                      (cdr args))
2114                                (let g189 ((g190 (car args))
2115                                           (g188 '())
2116                                           (g187 '()))
2117                                  (if (null? g190)
2118                                      (g195)
2119                                      (if (and (pair? (car g190))
2120                                               (pair? (cdar g190))
2121                                               (null? (cddar g190)))
2122                                          (g189 (cdr g190)
2123                                                (cons (cadar g190) g188)
2124                                                (cons (caar g190) g187))
2125                                          (g195)))))
2126                            (let g189 ((g190 (car args))
2127                                       (g188 '())
2128                                       (g187 '()))
2129                              (if (null? g190)
2130                                  (if (and (list? (cdr args))
2131                                           (pair? (cdr args)))
2132                                      (g194 (reverse g187)
2133                                            (reverse g188)
2134                                            (cdr args))
2135                                      (g195))
2136                                  (if (and (pair? (car g190))
2137                                           (pair? (cdar g190))
2138                                           (null? (cddar g190)))
2139                                      (g189 (cdr g190)
2140                                            (cons (cadar g190) g188)
2141                                            (cons (caar g190) g187))
2142                                      (g195))))))
2143                    (let g189 ((g190 (car args)) (g188 '()) (g187 '()))
2144                      (if (null? g190)
2145                          (if (and (list? (cdr args)) (pair? (cdr args)))
2146                              (g194 (reverse g187)
2147                                    (reverse g188)
2148                                    (cdr args))
2149                              (g195))
2150                          (if (and (pair? (car g190))
2151                                   (pair? (cdar g190))
2152                                   (null? (cddar g190)))
2153                              (g189 (cdr g190)
2154                                    (cons (cadar g190) g188)
2155                                    (cons (caar g190) g187))
2156                              (g195))))))
2157            (if (pair? (car args))
2158                (if (and (pair? (caar args))
2159                         (pair? (cdaar args))
2160                         (null? (cddaar args)))
2161                    (if (null? (cdar args))
2162                        (if (and (list? (cdr args)) (pair? (cdr args)))
2163                            (g186 (caaar args) (cadaar args) (cdr args))
2164                            (let g189 ((g190 (car args))
2165                                       (g188 '())
2166                                       (g187 '()))
2167                              (if (null? g190)
2168                                  (g195)
2169                                  (if (and (pair? (car g190))
2170                                           (pair? (cdar g190))
2171                                           (null? (cddar g190)))
2172                                      (g189 (cdr g190)
2173                                            (cons (cadar g190) g188)
2174                                            (cons (caar g190) g187))
2175                                      (g195)))))
2176                        (if (and (pair? (cdar args))
2177                                 (pair? (cadar args))
2178                                 (pair? (cdadar args))
2179                                 (null? (cdr (cdadar args)))
2180                                 (null? (cddar args)))
2181                            (if (and (list? (cdr args)) (pair? (cdr args)))
2182                                (g199 (caaar args)
2183                                      (cadaar args)
2184                                      (caadar args)
2185                                      (car (cdadar args))
2186                                      (cdr args))
2187                                (let g189 ((g190 (car args))
2188                                           (g188 '())
2189                                           (g187 '()))
2190                                  (if (null? g190)
2191                                      (g195)
2192                                      (if (and (pair? (car g190))
2193                                               (pair? (cdar g190))
2194                                               (null? (cddar g190)))
2195                                          (g189 (cdr g190)
2196                                                (cons (cadar g190) g188)
2197                                                (cons (caar g190) g187))
2198                                          (g195)))))
2199                            (let g189 ((g190 (car args))
2200                                       (g188 '())
2201                                       (g187 '()))
2202                              (if (null? g190)
2203                                  (if (and (list? (cdr args))
2204                                           (pair? (cdr args)))
2205                                      (g194 (reverse g187)
2206                                            (reverse g188)
2207                                            (cdr args))
2208                                      (g195))
2209                                  (if (and (pair? (car g190))
2210                                           (pair? (cdar g190))
2211                                           (null? (cddar g190)))
2212                                      (g189 (cdr g190)
2213                                            (cons (cadar g190) g188)
2214                                            (cons (caar g190) g187))
2215                                      (g195))))))
2216                    (let g189 ((g190 (car args)) (g188 '()) (g187 '()))
2217                      (if (null? g190)
2218                          (if (and (list? (cdr args)) (pair? (cdr args)))
2219                              (g194 (reverse g187)
2220                                    (reverse g188)
2221                                    (cdr args))
2222                              (g195))
2223                          (if (and (pair? (car g190))
2224                                   (pair? (cdar g190))
2225                                   (null? (cddar g190)))
2226                              (g189 (cdr g190)
2227                                    (cons (cadar g190) g188)
2228                                    (cons (caar g190) g187))
2229                              (g195)))))
2230                (g195)))
2231        (g195))))
2232(define-macro (match-define . args)
2233  (let ((g210 (cadddr match:expanders))
2234        (g209 (lambda ()
2235                (match:syntax-err
2236                  `(match-define ,@args)
2237                  "syntax error in"))))
2238    (if (pair? args)
2239        (if (g210 (car args))
2240            (if (and (pair? (cdr args)) (null? (cddr args)))
2241                ((lambda () `(begin (define ,@args))))
2242                (g209))
2243            (if (and (pair? (cdr args)) (null? (cddr args)))
2244                ((lambda (pat exp)
2245                   ((caddr match:expanders)
2246                    pat
2247                    exp
2248                    `(match-define ,@args)))
2249                 (car args)
2250                 (cadr args))
2251                (g209)))
2252        (g209))))
2253