~ chicken-core (master) /irregex.scm
Trap1;;;; irregex.scm - container for irregex-core.scm2;3; Copyright (c) 2010-2022, The CHICKEN Team4; All rights reserved.5;6; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following7; conditions are met:8;9; Redistributions of source code must retain the above copyright notice, this list of conditions and the following10; disclaimer.11; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following12; disclaimer in the documentation and/or other materials provided with the distribution.13; Neither the name of the author nor the names of its contributors may be used to endorse or promote14; products derived from this software without specific prior written permission.15;16; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS17; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY18; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR19; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR20; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR21; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY22; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR23; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE24; POSSIBILITY OF SUCH DAMAGE.25262728(declare29 (unit irregex)30 (no-procedure-checks)31 (fixnum))3233(module chicken.irregex34 (;; Constructors, accessors and predicates35 irregex irregex? string->sre maybe-string->sre sre->irregex36 irregex-names irregex-num-submatches string->irregex3738 ;; Chunking constructor39 make-irregex-chunker4041 ;; Main API42 irregex-extract irregex-fold irregex-match irregex-match?43 irregex-search irregex-split irregex-replace irregex-replace/all4445 ;; Chunked main API46 irregex-fold/chunked irregex-match/chunked irregex-search/chunked4748 ;; Match extraction API49 irregex-match-data? irregex-match-names50 irregex-match-start-index irregex-match-end-index51 irregex-match-num-submatches irregex-match-substring52 irregex-match-valid-index?5354 ;; Chunked match API55 irregex-match-start-chunk irregex-match-end-chunk56 irregex-match-subchunk5758 ;; Utilities59 glob->sre sre->string irregex-opt irregex-quote)606162(import (except scheme integer->char))63(import chicken.base chicken.fixnum chicken.syntax chicken.type)64(import (only (scheme base) open-output-string get-output-string))6566(import-for-syntax chicken.fixnum)6768(define-inline (integer->char n)69 (##core#inline "C_make_character" (##core#inline "C_unfix" n)) )7071(include "common-declarations.scm")7273;; These should probably be taken out of irregex upstream74(declare (unused filter integer-log cset-size remove))7576;; Due to usual-integrations, find is the one from library.scm,77;; so find-tail is unused (it's only used in the "find" definition)78(declare (unused find-tail))7980;; This is to silence an "always true" warning that we can't fix81;; because we don't want to needlessly change irregex-core.82(declare (type (*allow-utf8-mode?* boolean)))8384(define-syntax build-cache85 (er-macro-transformer86 (lambda (x r c)87 ;; (build-cache N ARG FAIL)88 (let* ((n (cadr x))89 (n2 (* n 2))90 (arg (caddr x))91 (fail (cadddr x))92 (%cache (r 'cache))93 (%index (r 'index))94 (%arg (r 'arg))95 (%let (r 'let))96 (%let* (r 'let*))97 (%if (r 'if))98 (%fx+ (r 'fx+))99 (%fxmod (r 'fxmod))100 (%equal? (r 'equal?))101 (%quote (r 'quote))102 (%tmp (r 'tmp))103 (%begin (r 'begin))104 (cache (make-vector (add1 n2) #f)))105 (##sys#setslot cache n2 0) ; last slot: current index106 `(,%let* ((,%cache (,%quote ,cache)) ; we mutate a literal vector107 (,%arg ,arg))108 ,(let fold ((i 0))109 (if (fx>= i n)110 ;; this should be thread-safe: a context-switch can only111 ;; happen before this code and in the call to FAIL.112 `(,%let ((,%tmp ,fail)113 (,%index (##sys#slot ,%cache ,n2)))114 (##sys#setslot ,%cache ,%index ,%arg)115 (##sys#setslot ,%cache (,%fx+ ,%index 1) ,%tmp)116 (##sys#setislot117 ,%cache ,n2 (,%fxmod (,%fx+ ,%index 2) ,n2))118 ,%tmp)119 `(,%if (,%equal? (##sys#slot ,%cache ,(* i 2)) ,%arg)120 (##sys#slot ,%cache ,(add1 (* i 2)))121 ,(fold (add1 i))))))))))122123(declare (unused %substring=?))124(define-compiler-syntax %substring=?125 (syntax-rules ()126 ((_ a b start1 start2 len)127 (##core#inline "C_u_i_substring_equal_p" a b start1 start2 len))))128129(define-compiler-syntax make-irregex130 (syntax-rules ()131 ((_ dfa dfa/search nfa flags submatches lengths names)132 (##sys#make-structure133 'regexp dfa dfa/search nfa flags submatches lengths names))))134135(define-compiler-syntax make-irregex-match136 (syntax-rules ()137 ((_ count names)138 (##sys#make-structure139 'regexp-match140 (make-vector (* 4 (+ 2 count)) #f) ; #1: submatches141 names ; #2: (guess)142 #f ; #3: chunka143 #f)))) ; #4: fail144145(declare (unused reverse))146(define-compiler-syntax reverse147 (syntax-rules ()148 ((_ lst) (##sys#fast-reverse lst))))149150(declare (unused bit-shl))151(define-compiler-syntax bit-shl152 (syntax-rules ()153 ((_ n i) (fxshl n i))))154155(declare (unused bit-shr))156(define-compiler-syntax bit-shr157 (syntax-rules ()158 ((_ n i) (fxshr n i))))159160(declare (unused bit-not))161(define-compiler-syntax bit-not162 (syntax-rules ()163 ((_ n) (fxnot n))))164165(declare (unused bit-ior))166(define-compiler-syntax bit-ior167 (syntax-rules ()168 ((_ a b) (fxior a b))))169170(declare (unused bit-and))171(define-compiler-syntax bit-and172 (syntax-rules ()173 ((_ a b) (fxand a b))))174175(define-compiler-syntax match-vector-ref176 (syntax-rules ()177 ((_ m i) (##sys#slot (##sys#slot m 1) i))))178179(define-compiler-syntax match-vector-set!180 (syntax-rules ()181 ((_ m i x) (##sys#setslot (##sys#slot m 1) i x))))182183(declare (unused irregex-match-start-chunk-set!))184(define-compiler-syntax irregex-match-start-chunk-set!185 (syntax-rules ()186 ((_ m n start)187 (vector-set! (##sys#slot m 1) (* n 4) start))))188189(declare (unused irregex-match-start-index-set!))190(define-compiler-syntax irregex-match-start-index-set!191 (syntax-rules ()192 ((_ m n start)193 (vector-set! (##sys#slot m 1) (+ 1 (* n 4)) start))))194195(declare (unused irregex-match-end-chunk-set!))196(define-compiler-syntax irregex-match-end-chunk-set!197 (syntax-rules ()198 ((_ m n end)199 (vector-set! (##sys#slot m 1) (+ 2 (* n 4)) end))))200201(declare (unused irregex-match-end-index-set!))202(define-compiler-syntax irregex-match-end-index-set!203 (syntax-rules ()204 ((_ m n end)205 (vector-set! (##sys#slot m 1) (+ 3 (* n 4)) end))))206207(declare (unused irregex-match-chunk&index-from-tag-set!))208(define-compiler-syntax irregex-match-chunk&index-from-tag-set!209 (syntax-rules ()210 ((_ m t chunk index)211 (begin212 (vector-set! (##sys#slot m 1) (+ 4 (* t 2)) chunk)213 (vector-set! (##sys#slot m 1) (+ 5 (* t 2)) index)))))214215(include "irregex-core.scm")216(include "irregex-utils.scm")217218(set! *allow-utf8-mode?* #f)219220(define glob->sre221 (let ((list->string list->string)222 (string->list string->list))223 (lambda (s)224 (##sys#check-string s 'glob->sre)225 (cons226 ':227 (let loop ((cs (string->list s)) (dir #t))228 (if (null? cs)229 '()230 (let ((c (car cs))231 (rest (cdr cs)) )232 (cond ((char=? c #\*)233 (if dir234 `((or (: (~ ("./\\"))235 (* (~ ("/\\"))))236 (* (~ ("./\\"))))237 ,@(loop rest #f))238 `((* (~ ("/\\"))) ,@(loop rest #f))))239 ((char=? c #\?) (cons 'any (loop rest #f)))240 ((char=? c #\[)241 (let loop2 ((rest rest) (s '()))242 (cond ((not (pair? rest))243 (error 'glob->sre244 "unexpected end of character class" s))245 ((char=? #\] (car rest))246 `(,(if (> (length s) 1)247 `(or ,@s)248 (car s))249 ,@(loop (cdr rest) #f)))250 ((and (pair? (cdr rest))251 (pair? (cddr rest))252 (char=? #\- (cadr rest)) )253 (loop2 (cdddr rest)254 (cons `(/ ,(car rest) ,(caddr rest)) s)))255 ((and (pair? (cdr rest))256 (char=? #\- (car rest)))257 (loop2 (cddr rest)258 (cons `(~ ,(cadr rest)) s)))259 (else260 (loop2 (cdr rest) (cons (car rest) s))))))261 (else (cons c (loop rest (memq c '(#\\ #\/)))))))))))))262263)