📄 match.scm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Pattern Matching Syntactic Extensions for Scheme;;#;(define ##match#version "Version 1.18, July 17, 1995 (Chicken port)");;;; Report bugs to wright@research.nj.nec.com. The most recent version of;; this software can be obtained by anonymous FTP from ftp.nj.nec.com;; in file pub/wright/match.tar.Z. Be sure to set "type binary" when;; transferring this file.;;;; Written by Andrew K. Wright, 1993 (wright@research.nj.nec.com).;; Adapted from code originally written by Bruce F. Duba, 1991.;; This package also includes a modified version of Kent Dybvig's;; define-structure (see Dybvig, R.K., The Scheme Programming Language,;; Prentice-Hall, NJ, 1987).;;;; This software is in the public domain. Feel free to copy,;; distribute, and modify this software as desired. No warranties;; nor guarantees of any kind apply. Please return any improvements;; or bug fixes to wright@research.nj.nec.com so that they may be included;; in future releases.;;;; This macro package extends Scheme with several new expression forms.;; Following is a brief summary of the new forms. See the associated;; LaTeX documentation for a full description of their functionality.;;;;;; match expressions:;;;; exp ::= ...;; | (match exp clause ...);; | (match-lambda clause ...);; | (match-lambda* clause ...);; | (match-let ((pat exp) ...) body);; | (match-let* ((pat exp) ...) body);; | (match-letrec ((pat exp) ...) body);; | (match-define pat exp);;;; clause ::= (pat body) | (pat => exp);;;; patterns: matches:;;;; pat ::= identifier anything, and binds identifier;; | _ anything;; | () the empty list;; | #t #t;; | #f #f;; | string a string;; | number a number;; | character a character;; | 'sexp an s-expression;; | 'symbol a symbol (special case of s-expr);; | (pat_1 ... pat_n) list of n elements;; | (pat_1 ... pat_n . pat_{n+1}) list of n or more;; | (pat_1 ... pat_n pat_n+1 ooo) list of n or more, each element;; of remainder must match pat_n+1;; | #(pat_1 ... pat_n) vector of n elements;; | #(pat_1 ... pat_n pat_n+1 ooo) vector of n or more, each element;; of remainder must match pat_n+1;; | #&pat box;; | ($ struct-name pat_1 ... pat_n) a structure;; | (= field pat) a field of a structure;; | (and pat_1 ... pat_n) if all of pat_1 thru pat_n match;; | (or pat_1 ... pat_n) if any of pat_1 thru pat_n match;; | (not pat_1 ... pat_n) if all pat_1 thru pat_n don't match;; | (? predicate pat_1 ... pat_n) if predicate true and all of;; pat_1 thru pat_n match;; | (set! identifier) anything, and binds setter;; | (get! identifier) anything, and binds getter;; | `qp a quasi-pattern;;;; ooo ::= ... zero or more;; | ___ zero or more;; | ..k k or more;; | __k k or more;;;; quasi-patterns: matches:;;;; qp ::= () the empty list;; | #t #t;; | #f #f;; | string a string;; | number a number;; | character a character;; | identifier a symbol;; | (qp_1 ... qp_n) list of n elements;; | (qp_1 ... qp_n . qp_{n+1}) list of n or more;; | (qp_1 ... qp_n qp_n+1 ooo) list of n or more, each element;; of remainder must match qp_n+1;; | #(qp_1 ... qp_n) vector of n elements;; | #(qp_1 ... qp_n qp_n+1 ooo) vector of n or more, each element;; of remainder must match qp_n+1;; | #&qp box;; | ,pat a pattern;; | ,@pat a pattern;;;; The names (quote, quasiquote, unquote, unquote-splicing, ?, _, $,;; and, or, not, set!, get!, ..., ___) cannot be used as pattern variables.;;;;;; match:error-control controls what code is generated for failed matches.;; Possible values:;; 'unspecified - do nothing, ie., evaluate (cond [#f #f]);; 'fail - call match:error, or die at car or cdr;; 'error - call match:error with the unmatched value;; 'match - call match:error with the unmatched value _and_;; the quoted match expression;; match:error-control is set by calling match:set-error-control with;; the new value.;;;; match:error is called for a failed match.;; match:error is set by calling match:set-error with the new value.;;;; End of user visible/modifiable stuff.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10/07/00 - felix:;(declare (unit match) (run-time-macros) (disable-interrupts) (usual-integrations) )(cond-expand [paranoia] [else (declare (no-procedure-checks-for-usual-bindings) (no-bound-checks) ) ] );;; Procedures(define (##match#every fn lst) (or (null? lst) (and (fn (car lst)) (##match#every fn (cdr lst)))));;; Macros(define-macro (match . args) (cond ((and (list? args) (<= 1 (length args)) (##match#every (lambda (y) (and (list? y) (<= 2 (length y)))) (cdr args))) (let* ((exp (car args)) (clauses (cdr args)) (e (if (symbol? exp) exp (gensym)))) (if (symbol? exp) ((car ##match#expanders) e clauses `(match ,@args)) `(let ((,e ,exp)) ,((car ##match#expanders) e clauses `(match ,@args)))))) (else (##match#syntax-err `(match ,@args) "syntax error in"))))(define-macro (match-lambda . args) (if (and (list? args) (##match#every (lambda (g126) (if (and (pair? g126) (list? (cdr g126))) (pair? (cdr g126)) #f)) args)) ((lambda () (let ((e (gensym))) `(lambda (,e) (match ,e ,@args))))) ((lambda () (##match#syntax-err `(match-lambda ,@args) "syntax error in")))))(define-macro (match-lambda* . args) (if (and (list? args) (##match#every (lambda (g134) (if (and (pair? g134) (list? (cdr g134))) (pair? (cdr g134)) #f)) args)) ((lambda () (let ((e (gensym))) `(lambda ,e (match ,e ,@args))))) ((lambda () (##match#syntax-err `(match-lambda* ,@args) "syntax error in")))))(define-macro (match-let . args) (let ((g158 (lambda (pat exp body) `(match ,exp (,pat ,@body)))) (g154 (lambda (pat exp body) (let ((g (map (lambda (x) (gensym)) pat)) (vpattern (list->vector pat))) `(let ,(map list g exp) (match (vector ,@g) (,vpattern ,@body)))))) (g146 (lambda () (##match#syntax-err `(match-let ,@args) "syntax error in"))) (g145 (lambda (p1 e1 p2 e2 body) (let ((g1 (gensym)) (g2 (gensym))) `(let ((,g1 ,e1) (,g2 ,e2)) (match (cons ,g1 ,g2) ((,p1 . ,p2) ,@body)))))) (g136 (cadddr ##match#expanders))) (if (pair? args) (if (symbol? (car args)) (if (and (pair? (cdr args)) (list? (cadr args))) (let g161 ((g162 (cadr args)) (g160 '()) (g159 '()))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -