(module (chibi match) - (export match match-lambda match-lambda* match-let match-letrec match-let*) - (import-immutable (scheme)) - (include "match/match.scm")) -
diff --git a/Makefile b/Makefile index b22a556e..dba4a9fd 100755 --- a/Makefile +++ b/Makefile @@ -169,11 +169,13 @@ lib/%$(SO): lib/%.c $(INCLUDES) $(CHIBI) tools/chibi-doc $< > $@ doc/lib/chibi/%.html: lib/chibi/%.module tools/chibi-doc chibi-scheme$(EXE) - $(CHIBI) tools/chibi-doc $< > $@ + $(CHIBI) tools/chibi-doc chibi.$* > $@ -MODULE_DOCS := doc/lib/chibi/match.html +MODULE_DOCS := ast disasm equiv filesystem generic heap-stats io loop \ + match mime modules net pathname process repl scribble stty \ + system test time type-inference uri weak -doc: doc/chibi.html $(MODULE_DOCS) +doc: doc/chibi.html $(MODULE_DOCS:%=doc/lib/chibi/%.html) clean: rm -f *.o *.i *.s *.8 diff --git a/doc/chibi.scrbl b/doc/chibi.scrbl index f2bf69f7..9b8c1b4c 100755 --- a/doc/chibi.scrbl +++ b/doc/chibi.scrbl @@ -963,117 +963,52 @@ SRFIs used in standard Chibi modules Additional non-standard modules are put in the @scheme{(chibi)} module namespace. -@subsection{Internals Interface} +@itemlist[ -The @scheme{(chibi ast)} module provides access to the Abstract Syntax Tree and -other internal data structures not typically needed for everyday programs. +@item{@hyperlink["lib/chibi/ast.html"]{(chibi ast) - Abstract Syntax Tree and other internal data types}} -@subsection{Disassember} +@item{@hyperlink["lib/chibi/disasm.html"]{(chibi disasm) - Disassembler for the virtual machine}} -The @scheme{(chibi disasm)} module provides a disassembler for the virtual -machine. +@item{@hyperlink["lib/chibi/equiv.html"]{(chibi equiv) - A version of @scheme{equal?} which is guaranteed to terminate}} -@subsection{Printed Equivalence} +@item{@hyperlink["lib/chibi/filesystem.html"]{(chibi filesystem) - Interface to the filesystem and file descriptor objects}} -The @scheme{(chibi equiv)} module provides the @scheme{equiv?} procedure, which -is similar to @scheme{equal?} but is guaranteed to terminate. It takes two -arguments and returns true iff they would print the same using SRFI-38 style -read/write syntax. +@item{@hyperlink["lib/chibi/generic.html"]{(chibi generic) - Generic methods for CLOS-style object oriented programming}} -@subsection{Filesystem Interface} +@item{@hyperlink["lib/chibi/heap-stats.html"]{(chibi heap-stats) - Utilities for gathering statistics on the heap}} -The @scheme{(chibi filesystem)} module provides access to the filesystem and -file descriptor objects. +@item{@hyperlink["lib/chibi/io.html"]{(chibi io) - Various I/O extensions and custom ports}} -@subsection{Generic Functions} +@item{@hyperlink["lib/chibi/loop.html"]{(chibi loop) - Fast and extensible loop syntax}} -The @scheme{(chibi generic)} module provides generic methods for CLOS-style -object oriented programming. +@item{@hyperlink["lib/chibi/match.html"]{(chibi match) - Intuitive and widely supported pattern matching syntax}} -@subsection{Heap Introspection} +@item{@hyperlink["lib/chibi/mime.html"]{(chibi mime) - Parse MIME files into SXML}} -The @scheme{(chibi heap-stats)} module provides utilities for gathering -statistics on the heap. +@item{@hyperlink["lib/chibi/modules.html"]{(chibi modules) - Introspection for the module system itself}} -@subsection{Input/Output Extensions} +@item{@hyperlink["lib/chibi/net.html"]{(chibi net) - Simple networking interface}} -The @scheme{(chibi io)} module provides various I/O extensions, including -custom ports. +@item{@hyperlink["lib/chibi/pathname.html"]{(chibi pathname) - Utilities to decompose and manipulate pathnames}} -@subsection{Extensible Loop Syntax} +@item{@hyperlink["lib/chibi/process.html"]{(chibi process) - Interface to spawn processes and handle signals}} -The @scheme{(chibi loop)} module provides a fast and extensible loop syntax. +@item{@hyperlink["lib/chibi/repl.html"]{(chibi repl) - A full-featured Read/Eval/Print Loop}} -@subsection{Pattern-Matching} +@item{@hyperlink["lib/chibi/scribble.html"]{(chibi scribble) - A parser for the scribble syntax used to write this manual}} -The @scheme{(chibi match)} module provides an intuitive and widely supported -pattern matching syntax. +@item{@hyperlink["lib/chibi/stty.html"]{(chibi stty) - A high-level interface to ioctl}} -@subsection{RFC2045 MIME} +@item{@hyperlink["lib/chibi/system.html"]{(chibi system) - Access to the host system and current user information}} -The @scheme{(chibi mime)} module provides utilities for parsing MIME -files into an SXML format. +@item{@hyperlink["lib/chibi/test.html"]{(chibi test) - A simple unit testing framework}} -@subsection{Module Introspection} +@item{@hyperlink["lib/chibi/time.html"]{(chibi time) - An interface to the current system time}} -The @scheme{(chibi modules)} module provides introspection utilities for the -module system itself. +@item{@hyperlink["lib/chibi/type-inference.html"]{(chibi type-inference) - An easy-to-use type inference system}} -@subsection{Networking Interface} +@item{@hyperlink["lib/chibi/uri.html"]{(chibi uri) - Utilities to parse and construct URIs}} -The @scheme{(chibi net)} module provides a simple networking interface. - -@subsection{Pathname Utilities} - -The @scheme{(chibi pathname)} module provides utilities to decompose and -manipulate pathnames. - -@subsection{Processes and Signals} - -The @scheme{(chibi process)} module provides utilities to spawn processes and -send and handle signals between processes. - -@subsection{Read/Eval/Print Loop} - -The @scheme{(chibi repl)} module provides a more full-featured repl than the -chibi-scheme executable. - -@subsection{Scribble Syntax} - -The @scheme{(chibi scribble)} module provides a parser for the scribble syntax -used to write this manual. - -@subsection{Stty Interface} - -The @scheme{(chibi stty)} provides a high-level interface to ioctl. - -@subsection{System Information} - -The @scheme{(chibi system)} module provides access to the host system and -current user information. - -@subsection{Line Editing} - -The @scheme{(chibi term edit-line)} provides an @scheme{edit-line} procedure -for interactive line editing. - -@subsection{Testing} - -The @scheme{(chibi test)} provides a simple unit testing framework. - -@subsection{Times and Dates} - -The @scheme{(chibi time)} provides an interface to the current system time. - -@subsection{Type Inference} - -The @scheme{(chibi type-inference)} is an easy-to-use type inference system. - -@subsection{URI Utilities} - -The @scheme{(chibi uri)} module provides utilities to parse and construct URIs. - -@subsection{Weak References} - -The @scheme{(chibi weak)} module provides data structures with weak references. +@item{@hyperlink["lib/chibi/weak.html"]{(chibi weak) - Data structures with weak references}} +] diff --git a/doc/lib/chibi/match.html b/doc/lib/chibi/match.html index 94b304dc..1a073107 100755 --- a/doc/lib/chibi/match.html +++ b/doc/lib/chibi/match.html @@ -1,10 +1,10 @@ -
+(module (chibi match) - (export match match-lambda match-lambda* match-let match-letrec match-let*) - (import-immutable (scheme)) - (include "match/match.scm")) -
+This is a full superset of the popular match
+package by Andrew Wright, written in fully portable syntax-rules
+and thus preserving hygiene.
+The most notable extensions are the ability to use non-linear
+patterns - patterns in which the same identifier occurs multiple
+times, tail patterns after ellipsis, and the experimental tree patterns.
+
+Patterns are written to look like the printed representation of
+the objects they match. The basic usage is
+(match expr (pat body ...) ...)
+where the result of expr
is matched against each pattern in
+turn, and the corresponding body is evaluated for the first to
+succeed. Thus, a list of three elements matches a list of three
+elements.
+
(let ((ls (list 1 2 3))) (match ls ((1 2 3) #)))
=> #t
+If no patterns match an error is signalled. +Identifiers will match anything, and make the corresponding +binding available in the body. +
(match (list 1 2 3) ((a b c) b))
=> 2
+If the same identifier occurs multiple times, the first instance
+will match anything, but subsequent instances must match a value
+which is equal?
to the first.
+
(match (list 1 2 1) ((a a b) 1) ((a b a) 2))
=> 2
+The special identifier _
matches anything, no matter how
+many times it is used, and does not bind the result in the body.
+
(match (list 1 2 1) ((_ _ b) 1) ((a b a) 2))
=> 1
+To match a literal identifier (or list or any other literal), use
+quote
.
+
(match 'a ('b 1) ('a 2))
=> 2
+Analogous to its normal usage in scheme, quasiquote
can
+be used to quote a mostly literally matching object with selected
+parts unquoted.
+
(match (list 1 2 3) (`(1 ,b ,c) (list b c)))
=> (2 3)
+Often you want to match any number of a repeated pattern. Inside
+a list pattern you can append ...
after an element to
+match zero or more of that pattern (like a regexp Kleene star).
+
(match (list 1 2) ((1 2 3 ...) #))
=> #t
+
(match (list 1 2 3) ((1 2 3 ...) #))
=> #t
+
(match (list 1 2 3 3 3) ((1 2 3 ...) #))
=> #t
+Pattern variables matched inside the repeated pattern are bound to +a list of each matching instance in the body. +
(match (list 1 2) ((a b c ...) c))
=> ()
+
(match (list 1 2 3) ((a b c ...) c))
=> (3)
+
(match (list 1 2 3 4 5) ((a b c ...) c))
=> (3 4 5)
+More than one ...
may not be used in the same list, since
+this would require exponential backtracking in the general case.
+However, ...
need not be the final element in the list,
+and may be succeeded by a fixed number of patterns.
+
(match (list 1 2 3 4) ((a b c ... d e) c))
=> ()
+
(match (list 1 2 3 4 5) ((a b c ... d e) c))
=> (3)
+
(match (list 1 2 3 4 5 6 7) ((a b c ... d e) c))
=> (3 4 5)
+___
is provided as an alias for ...
when it is
+inconvenient to use the ellipsis (as in a syntax-rules template).
+The ..1
syntax is exactly like the ...
except
+that it matches one or more repetitions (like a regexp "+").
+
(match (list 1 2) ((a b c ..1) c))
ERROR: match: "no matching pattern"
+
+
(match (list 1 2 3) ((a b c ..1) c))
=> (3)
+The boolean operators and
, or
and not
+can be used to group and negate patterns analogously to their
+Scheme counterparts.
+The and
operator ensures that all subpatterns match.
+This operator is often used with the idiom (and x pat)
to
+bind x
to the entire value that matches pat
+(c.f. "as-patterns" in ML or Haskell). Another common use is in
+conjunction with not
patterns to match a general case
+with certain exceptions.
+
(match 1 ((and) #))
=> #t
+
(match 1 ((and x) x))
=> 1
+
(match 1 ((and x 1) x))
=> 1
+The or
operator ensures that at least one subpattern
+matches. If the same identifier occurs in different subpatterns,
+it is matched independently. All identifiers from all subpatterns
+are bound if the or
operator matches, but the binding is
+only defined for identifiers from the subpattern which matched.
+
(match 1 ((or) #) (else #))
=> #f
+
(match 1 ((or x) x))
=> 1
+
(match 1 ((or x 2) x))
=> 1
+The not
operator succeeds if the given pattern doesn't
+match. None of the identifiers used are available in the body.
+
(match 1 ((not 2) #))
=> #t
+The more general operator ?
can be used to provide a
+predicate. The usage is (? predicate pat ...)
where
+predicate
is a Scheme expression evaluating to a predicate
+called on the value to match, and any optional patterns after the
+predicate are then matched as in an and
pattern.
+
(match 1 ((? odd? x) x))
=> 1
+The field operator =
is used to extract an arbitrary
+field and match against it. It is useful for more complex or
+conditional destructuring that can't be more directly expressed in
+the pattern syntax. The usage is (= field pat)
, where
+field
can be any expression, and should result in a
+procedure of one argument, which is applied to the value to match
+to generate a new value to match against pat
.
+Thus the pattern (and (= car x) (= cdr y))
is equivalent
+to (x . y)
, except it will result in an immediate error
+if the value isn't a pair.
+
(match '(1 . 2) ((= car x) x))
=> 1
+
(match 4 ((= sqrt x) x))
=> 2
+The record operator $
is used as a concise way to match
+records defined by SRFI-9 (or SRFI-99). The usage is
+($ rtd field ...)
, where rtd
should be the record
+type descriptor specified as the first argument to
+define-record-type
, and each field
is a subpattern
+matched against the fields of the record in order. Not all fields
+must be present.
+
(let ()
+ (define-record-type employee
+ (make-employee name title)
+ employee?
+ (name get-name)
+ (title get-title))
+ (match (make-employee "Bob" "Doctor")
+ (($ employee n t) (list t n))))
+
=> ("Doctor" "Bob")
+The set!
and get!
operators are used to bind an
+identifier to the setter and getter of a field, respectively. The
+setter is a procedure of one argument, which mutates the field to
+that argument. The getter is a procedure of no arguments which
+returns the current value of the field.
+
(let ((x (cons 1 2))) (match x ((1 . (set! s)) (s 3) x)))
=> (1 . 3)
+
(match '(1 . 2) ((1 . (get! g)) (g)))
=> 2
+The new operator ***
can be used to search a tree for
+subpatterns. A pattern of the form (x *** y)
represents
+the subpattern y
located somewhere in a tree where the path
+from the current object to y
can be seen as a list of the
+form (x ...)
. y
can immediately match the current
+object in which case the path is the empty list. In a sense it's
+a 2-dimensional version of the ...
pattern.
+As a common case the pattern (_ *** y)
can be used to
+search for y
anywhere in a tree, regardless of the path
+used.
+
(match '(a (a (a b))) ((x *** 'b) x))
=> (a a a)
+
(match '(a (b) (c (d e) (f g))) ((x *** 'g) x))
=> (a c f)
+
+The result of expr
is matched against each pattern
in
+turn, according to the pattern rules described in the previous
+section, until the the first pattern
matches. When a match is
+found, the corresponding body
s are evaluated in order,
+and the result of the last expression is returned as the result
+of the entire match
. If a failure
is provided,
+then it is bound to a procedure of no arguments which continues,
+processing at the next pattern
. If no pattern
matches,
+an error is signalled.
Shortcut for lambda
+ match
. Creates a
+procedure of one argument, and matches that argument against each
+clause.
Similar to match-lambda
. Creates a procedure of any
+number of arguments, and matches the argument list against each
+clause.
Matches each var to the corresponding expression, and evaluates
+the body with all match variables in scope. Raises an error if
+any of the expressions fail to match. Syntax analogous to named
+let can also be used for recursive functions which match on their
+arguments as in match-lambda*
.
Similar to match-let
, but analogously to letrec
+matches and binds the variables with all match variables in scope.
+Similar to match-let
, but analogously to let*
+matches and binds the variables in sequence, with preceding match
+variables in scope.