add simple pattern matcher contrib library
parent
035a64ad8b
commit
7a6ff3449a
|
@ -0,0 +1,8 @@
|
||||||
|
! Copyright (C) 2006 Chris Double.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
PROVIDE: match {
|
||||||
|
"match.factor"
|
||||||
|
"match.facts"
|
||||||
|
} {
|
||||||
|
"tests.factor"
|
||||||
|
} ;
|
|
@ -0,0 +1,38 @@
|
||||||
|
! Copyright (C) 2006 Chris Double.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
!
|
||||||
|
! Based on pattern matching code from Paul Graham's book 'On Lisp'.
|
||||||
|
IN: match
|
||||||
|
USING: kernel words sequences namespaces hashtables ;
|
||||||
|
|
||||||
|
SYMBOL: _
|
||||||
|
|
||||||
|
: match-var? ( symbol -- bool )
|
||||||
|
dup word? [
|
||||||
|
word-name first CHAR: ? =
|
||||||
|
] [
|
||||||
|
drop f
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
: (match) ( seq1 seq2 -- matched? )
|
||||||
|
{
|
||||||
|
{ [ 2dup = ] [ 2drop t ] }
|
||||||
|
{ [ over _ = ] [ 2drop t ] }
|
||||||
|
{ [ dup _ = ] [ 2drop t ] }
|
||||||
|
{ [ dup match-var? ] [ set t ] }
|
||||||
|
{ [ over match-var? ] [ swap set t ] }
|
||||||
|
{ [ over sequence? over sequence? and [ over first over first (match) ] [ f ] if ] [ >r 1 tail r> 1 tail (match) ] }
|
||||||
|
{ [ t ] [ 2drop f ] }
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: match ( seq1 seq2 -- bindings )
|
||||||
|
[ (match) ] make-hash swap [ drop f ] unless ;
|
||||||
|
|
||||||
|
SYMBOL: result
|
||||||
|
|
||||||
|
: match-cond ( seq assoc -- )
|
||||||
|
[
|
||||||
|
[ first over match dup result set ] find 2nip dup [ result get [ second call ] bind ] [ no-cond ] if
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
! Copyright (C) 2006 Chris Double.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: help match namespaces ;
|
||||||
|
|
||||||
|
HELP: match
|
||||||
|
{ $values { "seq1" "A sequence" } { "seq2" "A sequence" } { "bindings" "A hashtable" }
|
||||||
|
}
|
||||||
|
{ $description "Pattern match seq1 against seq2. The sequences can contain pattern variables, which are symbols that begin with '?'. The result is a hashtable of the bindings, mapping the pattern variables from one sequence to the equivalent value in the other sequence. The '_' symbol can be used to ignore the value at that point in the pattern for the match. " }
|
||||||
|
{ $examples
|
||||||
|
{ $example "SYMBOL: ?a\nSYMBOL: ?b\n{ ?a { 2 ?b } 5 } { 1 { 2 3 } _ } match\n => H{ { ?a 1 } { ?b 3 } }" }
|
||||||
|
}
|
||||||
|
{ $see-also match-cond } ;
|
||||||
|
|
||||||
|
HELP: match-cond
|
||||||
|
{ $values { "seq" "A sequence" } { "assoc" "A sequence of quotation pairs" }
|
||||||
|
}
|
||||||
|
{ $description "Calls the second quotation in the first pair whose first sequence yields a successful " { $link match } " against seq. The second quotation, when called, has the hashtable returned from the " { $link match } " call bound as the top namespace so " { $link get } " can be used to retrieve the values. To have a fallthrough match clause use the '_' match variable." }
|
||||||
|
{ $examples
|
||||||
|
{ $example "SYMBOL: ?value\n{ increment ?value } {\n { { increment ?value } [ ?value get do-something ] }\n { { decrement ?value } [ ?value get do-something-else ] }\n { _ [ no-match-found ] }\n} match-cond" }
|
||||||
|
}
|
||||||
|
{ $see-also match } ;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
! Copyright (C) 2006 Chris Double.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: test match namespaces arrays ;
|
||||||
|
IN: temporary
|
||||||
|
|
||||||
|
SYMBOL: ?a
|
||||||
|
SYMBOL: ?b
|
||||||
|
|
||||||
|
[ H{ { ?a 1 } { ?b 2 } } ] [
|
||||||
|
{ ?a ?b } { 1 2 } match
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ { 1 2 } ] [
|
||||||
|
{ 1 2 }
|
||||||
|
{
|
||||||
|
{ { ?a ?b } [ ?a get ?b get 2array ] }
|
||||||
|
} match-cond
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
{ 1 2 }
|
||||||
|
{
|
||||||
|
{ { 1 2 } [ t ] }
|
||||||
|
{ f [ f ] }
|
||||||
|
} match-cond
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
{ 1 3 }
|
||||||
|
{
|
||||||
|
{ { 1 2 } [ t ] }
|
||||||
|
{ { 1 3 } [ t ] }
|
||||||
|
} match-cond
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ f ] [
|
||||||
|
{ 1 5 }
|
||||||
|
{
|
||||||
|
{ { 1 2 } [ t ] }
|
||||||
|
{ { 1 3 } [ t ] }
|
||||||
|
{ _ [ f ] }
|
||||||
|
} match-cond
|
||||||
|
] unit-test
|
Loading…
Reference in New Issue