]> gitweb.factorcode.org Git - factor.git/blob - basis/regexp/compiler/compiler.factor
Unfinished changes for regexp lookaround
[factor.git] / basis / regexp / compiler / compiler.factor
1 ! Copyright (C) 2009 Daniel Ehrenberg.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: regexp.classes kernel sequences regexp.negation
4 quotations regexp.minimize assocs fry math locals combinators
5 accessors words compiler.units kernel.private strings
6 sequences.private arrays regexp.matchers call ;
7 IN: regexp.compiler
8
9 : literals>cases ( literal-transitions -- case-body )
10     [ 1quotation ] assoc-map ;
11
12 : condition>quot ( condition -- quot )
13     dup condition? [
14         [ question>> ] [ yes>> ] [ no>> ] tri
15         [ condition>quot ] bi@
16         '[ dup _ class-member? _ _ if ]
17     ] [
18         [ [ 3drop ] ] [ '[ drop _ execute ] ] if-empty
19     ] if ;
20
21 : non-literals>dispatch ( non-literal-transitions -- quot )
22     table>condition condition>quot ;
23
24 : expand-one-or ( or-class transition -- alist )
25     [ seq>> ] dip '[ _ 2array ] map ;
26
27 : expand-or ( alist -- new-alist )
28     [
29         first2 over or-class?
30         [ expand-one-or ] [ 2array 1array ] if
31     ] map concat ;
32
33 : split-literals ( transitions -- case default )
34     >alist expand-or [ first integer? ] partition
35     [ literals>cases ] [ non-literals>dispatch ] bi* ;
36
37 :: step ( last-match index str case-body final? -- last-index/f )
38     final? index last-match ?
39     index str bounds-check? [
40         index 1+ str
41         index str nth-unsafe
42         case-body case
43     ] when ; inline
44
45 : transitions>quot ( transitions final-state? -- quot )
46     [ split-literals suffix ] dip
47     '[ { array-capacity sequence } declare _ _ step ] ;
48
49 : word>quot ( word dfa -- quot )
50     [ transitions>> at ]
51     [ final-states>> key? ] 2bi
52     transitions>quot ;
53
54 : states>code ( words dfa -- )
55     '[
56         [
57             dup _ word>quot
58             (( last-match index string -- ? ))
59             define-declared
60         ] each
61     ] with-compilation-unit ;
62
63 : transitions-at ( transitions assoc -- new-transitions )
64     dup '[
65         [ _ at ]
66         [ [ _ at ] assoc-map ] bi*
67     ] assoc-map ;
68
69 : states>words ( dfa -- words dfa )
70     dup transitions>> keys [ gensym ] H{ } map>assoc
71     [ [ transitions-at ] rewrite-transitions ]
72     [ values ]
73     bi swap ; 
74
75 : dfa>word ( dfa -- word )
76     states>words [ states>code ] keep start-state>> ;
77
78 : check-sequence ( string -- string )
79     ! Make this configurable
80     dup sequence? [ "String required" throw ] unless ;
81
82 : run-regexp ( start-index string word -- ? )
83     { [ f ] [ >fixnum ] [ check-sequence ] [ execute ] } spread ; inline
84
85 : dfa>quotation ( dfa -- quot )
86     dfa>word '[ _ run-regexp ] ;
87
88 TUPLE: quot-matcher quot ;
89 C: <quot-matcher> quot-matcher
90
91 M: quot-matcher match-index-from
92     quot>> call( index string -- i/f ) ;