; regex ; for doing regex matches (func match? :bool (pattern :string text :string) (if (eq? 0 (length pattern)) #true (.search pattern text))) (func .match-one :bool (left right) (in? left (list "" "." right))) (func .match-? :bool (pattern text) (or (and (.match-one (first pattern) (first text)) (.match-inner (rest (rest pattern)) (rest text))) (.match-inner (rest (rest pattern)) text))) (func .match-* (pattern text) (or (and (.match-one (first pattern) (first text)) (.match-inner pattern (rest text))) (.match-inner (rest (rest pattern)) text))) (func .read-inner (pattern end) (.read-inner pattern end "")) (func .read-inner (pattern end progress) (if (eq? end (first pattern)) (list (rest pattern) progress) (.read-inner (rest pattern) end (concat progress (first pattern))))) (func .match-bracket (pattern text) (def processed (.read-inner (rest pattern) "]")) (not (empty? (drop-while (split (last processed)) (not (.match-inner (concat _item_ (first processed)) text)))))) (func .match-inner (pattern text) (branch ((eq? "" pattern) #true) ((and (eq? "$" pattern) (eq? "" text)) #true) ((eq? "" text) #false) ((eq? "[" (first pattern)) (.match-bracket pattern text)) ((and (>= (length pattern) 2) (eq? "?" (first (rest pattern)))) (.match-? pattern text)) ((and (>= (length pattern) 2) (eq? "*" (first (rest pattern)))) (.match-* pattern text)) (#true (and (.match-one (first pattern) (first text)) (.match-inner (rest pattern) (rest text)))))) (func .search (pattern text) (if (eq? "^" (first pattern)) (.match-inner (rest pattern) text) ;(.match-inner (concat ".*" pattern) text))) ; this is elegant but requires going through the entire string (block (def seed (list)) (for-count (length text) (redef seed (append seed _idx_))) (not (empty? (drop-while seed (not (.match-inner pattern (join (slice (split text) _item_) "")))))))))