From 1fe15b322d4811d8323c9333d7c7dcdb12fc2c1a Mon Sep 17 00:00:00 2001
From: Chris Double <chris.double@double.co.nz>
Date: Fri, 21 Dec 2007 11:38:25 +1300
Subject: [PATCH 1/3] Fix number/sequence error in match-replace

---
 extra/match/match.factor | 1 +
 1 file changed, 1 insertion(+)

diff --git a/extra/match/match.factor b/extra/match/match.factor
index 527d7f2465..a80001e724 100755
--- a/extra/match/match.factor
+++ b/extra/match/match.factor
@@ -54,6 +54,7 @@ MACRO: match-cond ( assoc -- )
 
 : replace-patterns ( object -- result )
     {
+	{ [ dup number? ] [ ] }
         { [ dup match-var? ] [ get ] }
         { [ dup sequence? ] [ [ replace-patterns ] map ] }
         { [ dup tuple? ] [ tuple>array replace-patterns >tuple ] }

From e7cf83a57a16ae4bb34be7c04b0f26a8c1672561 Mon Sep 17 00:00:00 2001
From: Chris Double <chris.double@double.co.nz>
Date: Fri, 21 Dec 2007 13:16:14 +1300
Subject: [PATCH 2/3] First attempt at compiling peg parsers to quotations

---
 extra/peg/peg.factor | 266 +++++++++++++++++++++++++++----------------
 1 file changed, 169 insertions(+), 97 deletions(-)

diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index 411a47b9bd..3d9128fec9 100644
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -1,12 +1,16 @@
 ! Copyright (C) 2007 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences strings namespaces math assocs shuffle 
-       vectors arrays combinators.lib memoize math.parser ;
+       vectors arrays combinators.lib memoize math.parser match ;
 IN: peg
 
 TUPLE: parse-result remaining ast ;
 
-GENERIC: (parse) ( state parser -- result )
+GENERIC: compile ( parser -- quot )
+
+: (parse) ( state parser -- result )
+  compile call ;
+
 
 <PRIVATE
 
@@ -72,135 +76,199 @@ PRIVATE>
 
 TUPLE: token-parser symbol ;
 
-M: token-parser (parse) ( input parser -- result )
-  token-parser-symbol 2dup head? [
-    dup >r length tail-slice r> <parse-result>
-  ] [
-    2drop f
-  ] if ;
-   
-TUPLE: satisfy-parser quot ;
+MATCH-VARS: ?token ;
 
-M: satisfy-parser (parse) ( state parser -- result )
-  over empty? [
-    2drop f 
-  ] [
-    satisfy-parser-quot [ unclip-slice dup ] dip call [  
-      <parse-result>
+: token-pattern ( -- quot )
+  [
+    ?token 2dup head? [
+      dup >r length tail-slice r> <parse-result>
     ] [
       2drop f
-    ] if
-  ] if ;
+    ] if 
+  ] ;
+  
+M: token-parser compile ( parser -- quot )
+  token-parser-symbol \ ?token token-pattern match-replace ;
+      
+TUPLE: satisfy-parser quot ;
+
+MATCH-VARS: ?quot ;
+
+: satisfy-pattern ( -- quot )
+  [
+    dup empty? [
+      drop f 
+    ] [
+      unclip-slice dup ?quot call [  
+        <parse-result>
+      ] [
+        2drop f
+      ] if
+    ] if 
+  ] ;
+
+M: satisfy-parser compile ( parser -- quot )
+  satisfy-parser-quot \ ?quot satisfy-pattern match-replace ;
 
 TUPLE: range-parser min max ;
 
-M: range-parser (parse) ( state parser -- result )
-  over empty? [
-    2drop f
-  ] [
-    0 pick nth dup rot 
-    { range-parser-min range-parser-max } get-slots between? [
-      [ 1 tail-slice ] dip <parse-result>
+MATCH-VARS: ?min ?max ;
+
+: range-pattern ( -- quot )
+  [
+    dup empty? [
+      drop f
     ] [
-      2drop f
-    ] if
-  ] if ;
+      0 over nth dup 
+      ?min ?max between? [
+         [ 1 tail-slice ] dip <parse-result>
+      ] [
+        2drop f
+      ] if
+    ] if 
+  ] ;
+
+M: range-parser compile ( parser -- quot )
+  T{ range-parser _ ?min ?max } range-pattern match-replace ;
 
 TUPLE: seq-parser parsers ;
 
-: do-seq-parser ( result parser -- result )
-  [ dup parse-result-remaining ] dip parse [
-    [ parse-result-remaining swap set-parse-result-remaining ] 2keep  
-    parse-result-ast dup ignore = [ drop ] [ swap [ parse-result-ast push ] keep ] if
-  ] [
-    drop f
-  ] if* ;
+: seq-pattern ( -- quot )
+  [
+    dup [
+      dup parse-result-remaining ?quot call [
+        [ parse-result-remaining swap set-parse-result-remaining ] 2keep
+        parse-result-ast dup ignore = [ 
+          drop  
+        ] [ 
+          swap [ parse-result-ast push ] keep 
+        ] if
+      ] [
+        drop f 
+      ] if*
+    ] [
+      drop f
+    ] if  
+  ] ;
 
-: (seq-parser) ( result parsers -- result )
-  dup empty? not pick and [
-    unclip swap [ do-seq-parser ] dip (seq-parser)
-  ] [
-    drop   
-  ] if ;
-
-M: seq-parser (parse) ( state parser -- result )
-  seq-parser-parsers [ V{ } clone <parse-result> ] dip  (seq-parser) ;
+M: seq-parser compile ( parser -- quot )
+  [
+    [ V{ } clone <parse-result> ] %
+    seq-parser-parsers [ compile \ ?quot seq-pattern match-replace % ] each 
+  ] [ ] make ;
 
 TUPLE: choice-parser parsers ;
-  
-: (choice-parser) ( state parsers -- result )
-  dup empty? [
-    2drop f
-  ] [
-    unclip pick swap parse [
-      2nip 
-    ] [
-      (choice-parser)
-    ] if* 
-  ] if ;
 
-M: choice-parser (parse) ( state parser -- result )
-  choice-parser-parsers (choice-parser) ;
+: choice-pattern ( -- quot )
+  [
+    dup [
+          
+    ] [
+      drop dup ?quot call   
+    ] if
+  ] ;
+
+M: choice-parser compile ( parser -- quot )
+  [
+    f ,
+    choice-parser-parsers [ compile \ ?quot choice-pattern match-replace % ] each
+    \ nip ,
+  ] [ ] make ;
 
 TUPLE: repeat0-parser p1 ;
 
-: (repeat-parser) ( parser result -- result )
-  2dup parse-result-remaining swap parse [
+: (repeat0) ( quot result -- result )
+  2dup parse-result-remaining swap call [
     [ parse-result-remaining swap set-parse-result-remaining ] 2keep 
     parse-result-ast swap [ parse-result-ast push ] keep
-    (repeat-parser) 
+    (repeat0) 
  ] [
     nip
-  ] if* ;
+  ] if* ; inline
 
-: clone-result ( result -- result )
-  { parse-result-remaining parse-result-ast }
-  get-slots 1vector  <parse-result> ;
+: repeat0-pattern ( -- quot )
+  [
+    ?quot swap (repeat0) 
+  ] ;
 
-M: repeat0-parser (parse) ( state parser -- result )
-     repeat0-parser-p1 2dup parse [ 
-       nipd clone-result (repeat-parser) 
-     ] [ 
-       drop V{ } clone <parse-result> 
-     ] if* ;
+M: repeat0-parser compile ( parser -- quot )
+  [
+    [ V{ } clone <parse-result> ] %
+    repeat0-parser-p1 compile \ ?quot repeat0-pattern match-replace %        
+  ] [ ] make ;
 
 TUPLE: repeat1-parser p1 ;
 
-M: repeat1-parser (parse) ( state parser -- result )
-   repeat1-parser-p1 tuck parse dup [ clone-result (repeat-parser) ] [ nip ] if ;
+: repeat1-pattern ( -- quot )
+  [
+    ?quot swap (repeat0) [
+      dup parse-result-ast empty? [
+        drop f
+      ] when  
+    ] [
+      f 
+    ] if*
+  ] ;
+
+M: repeat1-parser compile ( parser -- quot )
+  [
+    [ V{ } clone <parse-result> ] %
+    repeat1-parser-p1 compile \ ?quot repeat1-pattern match-replace % 
+  ] [ ] make ;
 
 TUPLE: optional-parser p1 ;
 
-M: optional-parser (parse) ( state parser -- result )
-   dupd optional-parser-p1 parse swap f <parse-result> or ;
+: optional-pattern ( -- quot )
+  [
+    dup ?quot call swap f <parse-result> or 
+  ] ;
+
+M: optional-parser compile ( parser -- quot )
+  optional-parser-p1 compile \ ?quot optional-pattern match-replace ;
 
 TUPLE: ensure-parser p1 ;
 
-M: ensure-parser (parse) ( state parser -- result )
-   dupd ensure-parser-p1 parse [
-     ignore <parse-result>  
-   ] [
-     drop f
-   ] if ;
+: ensure-pattern ( -- quot )
+  [
+    dup ?quot call [
+      ignore <parse-result>
+    ] [
+      drop f
+    ] if
+  ] ;
+
+M: ensure-parser compile ( parser -- quot )
+  ensure-parser-p1 compile \ ?quot ensure-pattern match-replace ;
 
 TUPLE: ensure-not-parser p1 ;
 
-M: ensure-not-parser (parse) ( state parser -- result )
-   dupd ensure-not-parser-p1 parse [
-     drop f
-   ] [
-     ignore <parse-result>  
-   ] if ;
+: ensure-not-pattern ( -- quot )
+  [
+    dup ?quot call [
+      drop f
+    ] [
+      ignore <parse-result>
+    ] if
+  ] ;
+
+M: ensure-not-parser compile ( parser -- quot )
+  ensure-not-parser-p1 compile \ ?quot ensure-not-pattern match-replace ;
 
 TUPLE: action-parser p1 quot ;
 
-M: action-parser (parse) ( state parser -- result )
-   tuck action-parser-p1 parse dup [ 
-     dup parse-result-ast rot action-parser-quot call
-     swap [ set-parse-result-ast ] keep
-   ] [
-     nip
-   ] if ;
+MATCH-VARS: ?action ;
+
+: action-pattern ( -- quot )
+  [
+    ?quot call dup [ 
+      dup parse-result-ast ?action call
+      swap [ set-parse-result-ast ] keep
+    ] when 
+  ] ;
+
+M: action-parser compile ( parser -- quot )
+  { action-parser-p1 action-parser-quot } get-slots [ compile ] dip 
+  2array { ?quot ?action } action-pattern match-replace ;
 
 : left-trim-slice ( string -- string )
   #! Return a new string without any leading whitespace
@@ -211,13 +279,17 @@ M: action-parser (parse) ( state parser -- result )
 
 TUPLE: sp-parser p1 ;
 
-M: sp-parser (parse) ( state parser -- result )
-  [ left-trim-slice ] dip sp-parser-p1 parse ;
+M: sp-parser compile ( parser -- quot )
+  [
+    \ left-trim-slice , sp-parser-p1 compile % 
+  ] [ ] make ;
 
 TUPLE: delay-parser quot ;
 
-M: delay-parser (parse) ( state parser -- result )
-  delay-parser-quot call parse ;
+M: delay-parser compile ( parser -- quot )
+  [
+    delay-parser-quot % \ compile , \ call ,
+  ] [ ] make ;
 
 PRIVATE>
 

From ffd25ce5a81628c9a0f012188dc87c9c78aee261 Mon Sep 17 00:00:00 2001
From: Chris Double <chris.double@double.co.nz>
Date: Fri, 21 Dec 2007 13:24:14 +1300
Subject: [PATCH 3/3] Fix missing vocab in match

---
 extra/match/match.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/match/match.factor b/extra/match/match.factor
index a80001e724..421aa926f9 100755
--- a/extra/match/match.factor
+++ b/extra/match/match.factor
@@ -3,7 +3,7 @@
 !
 ! Based on pattern matching code from Paul Graham's book 'On Lisp'.
 USING: parser kernel words namespaces sequences tuples
-combinators macros assocs ;
+combinators macros assocs math ;
 IN: match
 
 SYMBOL: _