aboutsummaryrefslogtreecommitdiff
path: root/libs/regex.neb
blob: e6bff34e93276446b09d018cc11e80d3dd7bee92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
; regex
; for doing regex matches

(func match? :bool (pattern :string text :string)
    
    (func match-one :bool (left right)
        (in? left (list "" "." right)))

    (func match-? :bool (pattern text)
        (or
            (and 
                (match-one (first-char pattern) (first-char text))
                (match-inner (rest-char (rest-char pattern)) (rest-char text)))
            (match-inner (rest-char (rest-char pattern)) text)))

    (func match-* (pattern text)
        (or
            (and
                (match-one (first-char pattern) (first-char text))
                (match-inner pattern (rest-char text)))
            (match-inner (rest-char (rest-char pattern)) text)))

    (func match-inner (pattern text)
        (branch
            ((eq? "" pattern) #true)
            ((and (eq? "$" pattern) (eq? "" text)) #true)
            ((eq? "" text) #false)
            ((and (>= (length pattern) 2) (eq? "?" (first-char (rest-char pattern))))
                (match-? pattern text))
            ((and (>= (length pattern) 2) (eq? "*" (first-char (rest-char pattern))))
                (match-* pattern text))
            (#true
                (and
                    (match-one (first-char pattern) (first-char text))
                    (match-inner (rest-char pattern) (rest-char text))))))

    (func search (pattern text)
        (if (eq? "^" (first-char pattern))
            (match-inner (rest-char pattern) text)
            (block
                (def progress text)
                (def out (list))
                (for-count (length text)
                    (redef out (append out (match-inner pattern progress)))
                    (redef progress (rest-char progress)))
                (or
                    (eq? 0 (list-length out))
                    (if (eq? 1 (list-length out))
                        (first out)
                        (apply or out))))))

    (search pattern text))