Factor Pattern Matching Additions
I've made a couple of additions to the pattern matching library I wrote for Factor. The idea came from a suggestion from Slava in #concatenative.
The main addition is a 'match-replace' word. This matches an object against a pattern and constructs a new object given a second pattern. The second pattern can use pattern matching variables from the first pattern to control the object construction. Here are some examples:
Just for fun I created a 'shuffle' word that lets you do stack shuffling via pattern matching. The implementation of the word is complex as it manipulates Factor's datastack directly:
It takes two patterns on the stack. The first is how the stack looks now, the second is how it should look after the shuffling. Here's some examples of how standard Factor stack shuffling words look using this method:
Categories: factor
The main addition is a 'match-replace' word. This matches an object against a pattern and constructs a new object given a second pattern. The second pattern can use pattern matching variables from the first pattern to control the object construction. Here are some examples:
USE: matchThis is built on top of a 'replace-patterns' word which replaces pattern matching variables with the relevant symbol values in the accessable namespaces:
MATCH-VARS: ?a ?b ?c ;
{ 1 2 } { ?a ?b } { ?b ?a } match-replace .
! => { 2 1 }
TUPLE: foo one two ;
{ 1 2 { 3 4 } } { ?a _ { _ ?b } } T{ foo f ?a ?b } match-replace .
! => T{ foo f 1 4 }
1 2T{ foo f ?a ?b } T{ foo f ?b ?a } match-replace .
! => T{ foo f 2 1 }
{ 1 2 } { ?a ?b } match [
{ ?b ?a } replace-patterns
] bind .
! => { 2 1 }These words have been added to the 'libs/match' library and should appear in the darcs version of Factor soon. They are in my repository if you want them now.Just for fun I created a 'shuffle' word that lets you do stack shuffling via pattern matching. The implementation of the word is complex as it manipulates Factor's datastack directly:
: shuffle ( pattern1 pattern2 -- )As it uses 'datastack' and 'set-datastack' this word cannot be compiled. I haven't added it to the library for this reason and it encourages complex stack effects which should be avoided but it's pretty neat that Factor allows this sort of thing to be written.
dupd >vector >r >vector >r length >r
datastack clone r> over length swap - 2dup
tail r> r> match-replace
>r head r> append set-datastack ;
It takes two patterns on the stack. The first is how the stack looks now, the second is how it should look after the shuffling. Here's some examples of how standard Factor stack shuffling words look using this method:
! drop
1 2 3 { _ } { } shuffle .s clear
! => 1
! 2
! nip
1 2 3 { _ ?b } { ?b } shuffle .s clear
! => 1
! 3
! pick
1 2 3 { ?a ?b ?c } { ?a ?b ?c ?a } shuffle .s clear
! => 1
! 2
! 3
! 1
! 2dup
1 2 3 { ?a ?b } { ?a ?b ?a ?b } shuffle .s clear
! => 1
! 2
! 3
! 2
! 3
Categories: factor

1 Comments:
Way cool. The generic shuffle thing is exacly what I thought I should try to implement one day. You have been doing just incredible stuff with factor, I wonder if one day we'll see factor in a production environment.
Post a Comment
<< Home