@effekt-lang/effekt 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/bin/effekt +0 -0
  4. package/bin/effekt.sh +2 -0
  5. package/libraries/chez/THIRD-PARTY.txt +11 -0
  6. package/libraries/chez/callcc/datatype.ss +188 -0
  7. package/libraries/chez/callcc/effekt.effekt +221 -0
  8. package/libraries/chez/callcc/effekt.ss +31 -0
  9. package/libraries/chez/callcc/seq.ss +44 -0
  10. package/libraries/chez/callcc/seq0.ss +69 -0
  11. package/libraries/chez/callcc/tail.ss +76 -0
  12. package/libraries/chez/callcc/tail0.ss +89 -0
  13. package/libraries/chez/common/effekt_matching.ss +100 -0
  14. package/libraries/chez/common/effekt_primitives.ss +97 -0
  15. package/libraries/chez/common/immutable/cslist.effekt +31 -0
  16. package/libraries/chez/common/immutable/dequeue.effekt +78 -0
  17. package/libraries/chez/common/immutable/list.effekt +643 -0
  18. package/libraries/chez/common/immutable/option.effekt +39 -0
  19. package/libraries/chez/common/immutable/result.effekt +29 -0
  20. package/libraries/chez/common/io/args.effekt +20 -0
  21. package/libraries/chez/common/mutable/array.effekt +27 -0
  22. package/libraries/chez/common/mutable/dict.effekt +30 -0
  23. package/libraries/chez/common/mutable/heap.effekt +12 -0
  24. package/libraries/chez/common/test.effekt +59 -0
  25. package/libraries/chez/common/text/pregexp.scm +772 -0
  26. package/libraries/chez/common/text/regex.effekt +33 -0
  27. package/libraries/chez/common/text/string.effekt +46 -0
  28. package/libraries/chez/lift/effekt.effekt +217 -0
  29. package/libraries/chez/lift/effekt.ss +118 -0
  30. package/libraries/chez/monadic/effekt.effekt +218 -0
  31. package/libraries/chez/monadic/effekt.ss +84 -0
  32. package/libraries/chez/monadic/seq0.ss +76 -0
  33. package/libraries/js/effekt.effekt +284 -0
  34. package/libraries/js/effekt_builtins.js +26 -0
  35. package/libraries/js/effekt_matching.js +79 -0
  36. package/libraries/js/effekt_runtime.js +385 -0
  37. package/libraries/js/immutable/dequeue.effekt +78 -0
  38. package/libraries/js/immutable/list.effekt +643 -0
  39. package/libraries/js/immutable/option.effekt +49 -0
  40. package/libraries/js/immutable/result.effekt +29 -0
  41. package/libraries/js/io/args.effekt +9 -0
  42. package/libraries/js/io/async.effekt +28 -0
  43. package/libraries/js/io/async.js +2 -0
  44. package/libraries/js/io/file.effekt +50 -0
  45. package/libraries/js/io/file_include.js +13 -0
  46. package/libraries/js/mutable/array.effekt +98 -0
  47. package/libraries/js/mutable/heap.effekt +32 -0
  48. package/libraries/js/mutable/map.effekt +32 -0
  49. package/libraries/js/test.effekt +59 -0
  50. package/libraries/js/text/regex.effekt +34 -0
  51. package/libraries/js/text/string.effekt +64 -0
  52. package/libraries/js/unsafe/cont.effekt +11 -0
  53. package/libraries/js/web/dom.effekt +45 -0
  54. package/libraries/llvm/buffer.c +181 -0
  55. package/libraries/llvm/effekt.effekt +243 -0
  56. package/libraries/llvm/forward-declare-c.ll +24 -0
  57. package/libraries/llvm/hole.c +11 -0
  58. package/libraries/llvm/immutable/list.effekt +678 -0
  59. package/libraries/llvm/immutable/option.effekt +53 -0
  60. package/libraries/llvm/immutable/result.effekt +29 -0
  61. package/libraries/llvm/io/args.effekt +24 -0
  62. package/libraries/llvm/io.c +24 -0
  63. package/libraries/llvm/main.c +39 -0
  64. package/libraries/llvm/rts.ll +619 -0
  65. package/libraries/llvm/sanity.c +16 -0
  66. package/libraries/llvm/text/string.effekt +179 -0
  67. package/libraries/llvm/types.c +20 -0
  68. package/libraries/ml/effekt.effekt +267 -0
  69. package/libraries/ml/effekt.sml +63 -0
  70. package/libraries/ml/immutable/dequeue.effekt +81 -0
  71. package/libraries/ml/immutable/list.effekt +674 -0
  72. package/libraries/ml/immutable/option.effekt +53 -0
  73. package/libraries/ml/immutable/result.effekt +29 -0
  74. package/libraries/ml/immutable/seq.effekt +903 -0
  75. package/libraries/ml/internal/option.effekt +18 -0
  76. package/libraries/ml/io/args.effekt +41 -0
  77. package/libraries/ml/mutable/array.effekt +43 -0
  78. package/libraries/ml/random.effekt +85 -0
  79. package/libraries/ml/test.effekt +60 -0
  80. package/libraries/ml/text/regex.effekt +107 -0
  81. package/libraries/ml/text/string.effekt +81 -0
  82. package/licenses/THIRD-PARTY.txt +21 -0
  83. package/licenses/apache-2.0 - license-2.0.txt +202 -0
  84. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
  85. package/licenses/kiama-license.txt +373 -0
  86. package/licenses/kiama-readme.txt +186 -0
  87. package/licenses/mit license - mit-license.html +769 -0
  88. package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
  89. package/licenses/the bsd license - bsd-license.html +762 -0
  90. package/licenses/the mit license - mit.html +769 -0
  91. package/package.json +26 -18
@@ -0,0 +1,772 @@
1
+
2
+ ;; This file was obtained from:
3
+ ;; https://github.com/ds26gte/pregexp/blob/master/pregexp.scm
4
+ ;;
5
+ ;; Copyright (c) 1999-2015, Dorai Sitaram.
6
+ ;; All rights reserved.
7
+ ;;
8
+ ;; Permission to copy, modify, distribute, and use this work or
9
+ ;; a modified copy of this work, for any purpose, is hereby
10
+ ;; granted, provided that the copy includes this copyright
11
+ ;; notice, and in the case of a modified copy, also includes a
12
+ ;; notice of modification. This work is provided as is, with
13
+ ;; no warranty of any kind.
14
+
15
+ ;pregexp.scm
16
+ ;Portable regular expressions for Scheme
17
+ ;Dorai Sitaram
18
+ ;http://www.ccs.neu.edu/~dorai
19
+ ;dorai AT ccs DOT neu DOT edu
20
+ ;Oct 2, 1999
21
+
22
+ (define *pregexp-version* 20200130) ;last change
23
+
24
+ (define *pregexp-comment-char* #\;)
25
+
26
+ (define *pregexp-nul-char-int*
27
+ ;can't assume #\nul maps to 0 because of Scsh
28
+ (- (char->integer #\a) 97))
29
+
30
+ (define *pregexp-return-char*
31
+ ;can't use #\return because it isn't R5RS
32
+ (integer->char
33
+ (+ 13 *pregexp-nul-char-int*)))
34
+
35
+ (define *pregexp-tab-char*
36
+ ;can't use #\tab because it isn't R5RS
37
+ (integer->char
38
+ (+ 9 *pregexp-nul-char-int*)))
39
+
40
+ (define *pregexp-space-sensitive?* #t)
41
+
42
+ (define pregexp-reverse!
43
+ ;the useful reverse! isn't R5RS
44
+ (lambda (s)
45
+ (let loop ((s s) (r '()))
46
+ (if (null? s) r
47
+ (let ((d (cdr s)))
48
+ (set-cdr! s r)
49
+ (loop d s))))))
50
+
51
+ (define pregexp-error
52
+ ;R5RS won't give me a portable error procedure.
53
+ ;modify this as needed
54
+ (lambda whatever
55
+ (display "Error:")
56
+ (for-each (lambda (x) (display #\space) (write x))
57
+ whatever)
58
+ (newline)
59
+ (error 'pregexp-error "")))
60
+
61
+ (define pregexp-read-pattern
62
+ (lambda (s i n)
63
+ (if (>= i n)
64
+ (list
65
+ (list ':or (list ':seq)) i)
66
+ (let loop ((branches '()) (i i))
67
+ (if (or (>= i n)
68
+ (char=? (string-ref s i) #\)))
69
+ (list (cons ':or (pregexp-reverse! branches)) i)
70
+ (let ((vv (pregexp-read-branch
71
+ s
72
+ (if (char=? (string-ref s i) #\|) (+ i 1) i) n)))
73
+ (loop (cons (car vv) branches) (cadr vv))))))))
74
+
75
+ (define pregexp-read-branch
76
+ (lambda (s i n)
77
+ (let loop ((pieces '()) (i i))
78
+ (cond ((>= i n)
79
+ (list (cons ':seq (pregexp-reverse! pieces)) i))
80
+ ((let ((c (string-ref s i)))
81
+ (or (char=? c #\|)
82
+ (char=? c #\))))
83
+ (list (cons ':seq (pregexp-reverse! pieces)) i))
84
+ (else (let ((vv (pregexp-read-piece s i n)))
85
+ (loop (cons (car vv) pieces) (cadr vv))))))))
86
+
87
+ (define pregexp-read-piece
88
+ (lambda (s i n)
89
+ (let ((c (string-ref s i)))
90
+ (case c
91
+ ((#\^) (list ':bos (+ i 1)))
92
+ ((#\$) (list ':eos (+ i 1)))
93
+ ((#\.) (pregexp-wrap-quantifier-if-any
94
+ (list ':any (+ i 1)) s n))
95
+ ((#\[) (let ((i+1 (+ i 1)))
96
+ (pregexp-wrap-quantifier-if-any
97
+ (case (and (< i+1 n) (string-ref s i+1))
98
+ ((#\^)
99
+ (let ((vv (pregexp-read-char-list s (+ i 2) n)))
100
+ (list (list ':neg-char (car vv)) (cadr vv))))
101
+ (else (pregexp-read-char-list s i+1 n)))
102
+ s n)))
103
+ ((#\()
104
+ (pregexp-wrap-quantifier-if-any
105
+ (pregexp-read-subpattern s (+ i 1) n) s n))
106
+ ((#\\)
107
+ (pregexp-wrap-quantifier-if-any
108
+ (cond ((pregexp-read-escaped-number s i n) =>
109
+ (lambda (num-i)
110
+ (list (list ':backref (car num-i)) (cadr num-i))))
111
+ ((pregexp-read-escaped-char s i n) =>
112
+ (lambda (char-i)
113
+ (list (car char-i) (cadr char-i))))
114
+ (else (pregexp-error 'pregexp-read-piece 'backslash)))
115
+ s n))
116
+ (else
117
+ (if (or *pregexp-space-sensitive?*
118
+ (and (not (char-whitespace? c))
119
+ (not (char=? c *pregexp-comment-char*))))
120
+ (pregexp-wrap-quantifier-if-any
121
+ (list c (+ i 1)) s n)
122
+ (let loop ((i i) (in-comment? #f))
123
+ (if (>= i n) (list ':empty i)
124
+ (let ((c (string-ref s i)))
125
+ (cond (in-comment?
126
+ (loop (+ i 1)
127
+ (not (char=? c #\newline))))
128
+ ((char-whitespace? c)
129
+ (loop (+ i 1) #f))
130
+ ((char=? c *pregexp-comment-char*)
131
+ (loop (+ i 1) #t))
132
+ (else (list ':empty i))))))))))))
133
+
134
+ (define pregexp-read-escaped-number
135
+ (lambda (s i n)
136
+ ; s[i] = \
137
+ (and (< (+ i 1) n) ;must have at least something following \
138
+ (let ((c (string-ref s (+ i 1))))
139
+ (and (char-numeric? c)
140
+ (let loop ((i (+ i 2)) (r (list c)))
141
+ (if (>= i n)
142
+ (list (string->number
143
+ (list->string (pregexp-reverse! r))) i)
144
+ (let ((c (string-ref s i)))
145
+ (if (char-numeric? c)
146
+ (loop (+ i 1) (cons c r))
147
+ (list (string->number
148
+ (list->string (pregexp-reverse! r)))
149
+ i))))))))))
150
+
151
+ (define pregexp-read-escaped-char
152
+ (lambda (s i n)
153
+ ; s[i] = \
154
+ (and (< (+ i 1) n)
155
+ (let ((c (string-ref s (+ i 1))))
156
+ (case c
157
+ ((#\b) (list ':wbdry (+ i 2)))
158
+ ((#\B) (list ':not-wbdry (+ i 2)))
159
+ ((#\d) (list ':digit (+ i 2)))
160
+ ((#\D) (list '(:neg-char :digit) (+ i 2)))
161
+ ((#\n) (list #\newline (+ i 2)))
162
+ ((#\r) (list *pregexp-return-char* (+ i 2)))
163
+ ((#\s) (list ':space (+ i 2)))
164
+ ((#\S) (list '(:neg-char :space) (+ i 2)))
165
+ ((#\t) (list *pregexp-tab-char* (+ i 2)))
166
+ ((#\w) (list ':word (+ i 2)))
167
+ ((#\W) (list '(:neg-char :word) (+ i 2)))
168
+ (else (list c (+ i 2))))))))
169
+
170
+ (define pregexp-read-posix-char-class
171
+ (lambda (s i n)
172
+ ; lbrack, colon already read
173
+ (let ((neg? #f))
174
+ (let loop ((i i) (r (list #\:)))
175
+ (if (>= i n)
176
+ (pregexp-error 'pregexp-read-posix-char-class)
177
+ (let ((c (string-ref s i)))
178
+ (cond ((char=? c #\^)
179
+ (set! neg? #t)
180
+ (loop (+ i 1) r))
181
+ ((char-alphabetic? c)
182
+ (loop (+ i 1) (cons c r)))
183
+ ((char=? c #\:)
184
+ (if (or (>= (+ i 1) n)
185
+ (not (char=? (string-ref s (+ i 1)) #\])))
186
+ (pregexp-error 'pregexp-read-posix-char-class)
187
+ (let ((posix-class
188
+ (string->symbol
189
+ (list->string (pregexp-reverse! r)))))
190
+ (list (if neg? (list ':neg-char posix-class)
191
+ posix-class)
192
+ (+ i 2)))))
193
+ (else
194
+ (pregexp-error 'pregexp-read-posix-char-class)))))))))
195
+
196
+ (define pregexp-read-cluster-type
197
+ (lambda (s i n)
198
+ ; s[i-1] = left-paren
199
+ (let ((c (string-ref s i)))
200
+ (case c
201
+ ((#\?)
202
+ (let ((i (+ i 1)))
203
+ (case (string-ref s i)
204
+ ((#\:) (list '() (+ i 1)))
205
+ ((#\=) (list '(:lookahead) (+ i 1)))
206
+ ((#\!) (list '(:neg-lookahead) (+ i 1)))
207
+ ((#\>) (list '(:no-backtrack) (+ i 1)))
208
+ ((#\<)
209
+ (list (case (string-ref s (+ i 1))
210
+ ((#\=) '(:lookbehind))
211
+ ((#\!) '(:neg-lookbehind))
212
+ (else (pregexp-error 'pregexp-read-cluster-type)))
213
+ (+ i 2)))
214
+ (else (let loop ((i i) (r '()) (inv? #f))
215
+ (let ((c (string-ref s i)))
216
+ (case c
217
+ ((#\-) (loop (+ i 1) r #t))
218
+ ((#\i) (loop (+ i 1)
219
+ (cons (if inv? ':case-sensitive
220
+ ':case-insensitive) r) #f))
221
+ ((#\x)
222
+ (set! *pregexp-space-sensitive?* inv?)
223
+ (loop (+ i 1) r #f))
224
+ ((#\:) (list r (+ i 1)))
225
+ (else (pregexp-error
226
+ 'pregexp-read-cluster-type)))))))))
227
+ (else (list '(:sub) i))))))
228
+
229
+ (define pregexp-read-subpattern
230
+ (lambda (s i n)
231
+ (let* ((remember-space-sensitive? *pregexp-space-sensitive?*)
232
+ (ctyp-i (pregexp-read-cluster-type s i n))
233
+ (ctyp (car ctyp-i))
234
+ (i (cadr ctyp-i))
235
+ (vv (pregexp-read-pattern s i n)))
236
+ (set! *pregexp-space-sensitive?* remember-space-sensitive?)
237
+ (let ((vv-re (car vv))
238
+ (vv-i (cadr vv)))
239
+ (if (and (< vv-i n)
240
+ (char=? (string-ref s vv-i)
241
+ #\)))
242
+ (list
243
+ (let loop ((ctyp ctyp) (re vv-re))
244
+ (if (null? ctyp) re
245
+ (loop (cdr ctyp)
246
+ (list (car ctyp) re))))
247
+ (+ vv-i 1))
248
+ (pregexp-error 'pregexp-read-subpattern))))))
249
+
250
+ (define pregexp-wrap-quantifier-if-any
251
+ (lambda (vv s n)
252
+ (let ((re (car vv)))
253
+ (let loop ((i (cadr vv)))
254
+ (if (>= i n) vv
255
+ (let ((c (string-ref s i)))
256
+ (if (and (char-whitespace? c) (not *pregexp-space-sensitive?*))
257
+ (loop (+ i 1))
258
+ (case c
259
+ ((#\* #\+ #\? #\{)
260
+ (let* ((new-re (list ':between 'minimal?
261
+ 'at-least 'at-most re))
262
+ (new-vv (list new-re 'next-i)))
263
+ (case c
264
+ ((#\*) (set-car! (cddr new-re) 0)
265
+ (set-car! (cdddr new-re) #f))
266
+ ((#\+) (set-car! (cddr new-re) 1)
267
+ (set-car! (cdddr new-re) #f))
268
+ ((#\?) (set-car! (cddr new-re) 0)
269
+ (set-car! (cdddr new-re) 1))
270
+ ((#\{) (let ((pq (pregexp-read-nums s (+ i 1) n)))
271
+ (if (not pq)
272
+ (pregexp-error
273
+ 'pregexp-wrap-quantifier-if-any
274
+ 'left-brace-must-be-followed-by-number))
275
+ (set-car! (cddr new-re) (car pq))
276
+ (set-car! (cdddr new-re) (cadr pq))
277
+ (set! i (caddr pq)))))
278
+ (let loop ((i (+ i 1)))
279
+ (if (>= i n)
280
+ (begin (set-car! (cdr new-re) #f)
281
+ (set-car! (cdr new-vv) i))
282
+ (let ((c (string-ref s i)))
283
+ (cond ((and (char-whitespace? c)
284
+ (not *pregexp-space-sensitive?*))
285
+ (loop (+ i 1)))
286
+ ((char=? c #\?)
287
+ (set-car! (cdr new-re) #t)
288
+ (set-car! (cdr new-vv) (+ i 1)))
289
+ (else (set-car! (cdr new-re) #f)
290
+ (set-car! (cdr new-vv) i))))))
291
+ new-vv))
292
+ (else vv)))))))))
293
+
294
+ ;
295
+
296
+ (define pregexp-read-nums
297
+ (lambda (s i n)
298
+ ; s[i-1] = {
299
+ ; returns (p q k) where s[k] = }
300
+ (let loop ((p '()) (q '()) (k i) (reading 1))
301
+ (if (>= k n) (pregexp-error 'pregexp-read-nums))
302
+ (let ((c (string-ref s k)))
303
+ (cond ((char-numeric? c)
304
+ (if (= reading 1)
305
+ (loop (cons c p) q (+ k 1) 1)
306
+ (loop p (cons c q) (+ k 1) 2)))
307
+ ((and (char-whitespace? c) (not *pregexp-space-sensitive?*))
308
+ (loop p q (+ k 1) reading))
309
+ ((and (char=? c #\,) (= reading 1))
310
+ (loop p q (+ k 1) 2))
311
+ ((char=? c #\})
312
+ (let ((p (string->number (list->string (pregexp-reverse! p))))
313
+ (q (string->number (list->string (pregexp-reverse! q)))))
314
+ (cond ((and (not p) (= reading 1)) (list 0 #f k))
315
+ ((= reading 1) (list p p k))
316
+ (else (list p q k)))))
317
+ (else #f))))))
318
+
319
+ (define pregexp-invert-char-list
320
+ (lambda (vv)
321
+ (set-car! (car vv) ':none-of-chars)
322
+ vv))
323
+
324
+ ;
325
+
326
+ (define pregexp-read-char-list
327
+ (lambda (s i n)
328
+ (let loop ((r '()) (i i))
329
+ (if (>= i n)
330
+ (pregexp-error 'pregexp-read-char-list
331
+ 'character-class-ended-too-soon)
332
+ (let ((c (string-ref s i)))
333
+ (case c
334
+ ((#\]) (if (null? r)
335
+ (loop (cons c r) (+ i 1))
336
+ (list (cons ':one-of-chars (pregexp-reverse! r))
337
+ (+ i 1))))
338
+ ((#\\)
339
+ (let ((char-i (pregexp-read-escaped-char s i n)))
340
+ (if char-i (loop (cons (car char-i) r) (cadr char-i))
341
+ (pregexp-error 'pregexp-read-char-list 'backslash))))
342
+ ((#\-) (if (or (null? r)
343
+ (let ((i+1 (+ i 1)))
344
+ (and (< i+1 n)
345
+ (char=? (string-ref s i+1) #\]))))
346
+ (loop (cons c r) (+ i 1))
347
+ (let ((c-prev (car r)))
348
+ (if (char? c-prev)
349
+ (loop (cons (list ':char-range c-prev
350
+ (string-ref s (+ i 1))) (cdr r))
351
+ (+ i 2))
352
+ (loop (cons c r) (+ i 1))))))
353
+ ((#\[) (if (char=? (string-ref s (+ i 1)) #\:)
354
+ (let ((posix-char-class-i
355
+ (pregexp-read-posix-char-class s (+ i 2) n)))
356
+ (loop (cons (car posix-char-class-i) r)
357
+ (cadr posix-char-class-i)))
358
+ (loop (cons c r) (+ i 1))))
359
+ (else (loop (cons c r) (+ i 1)))))))))
360
+
361
+ ;
362
+
363
+ (define pregexp-string-match
364
+ (lambda (s1 s i n sk fk)
365
+ (let ((n1 (string-length s1)))
366
+ (if (> n1 n) (fk)
367
+ (let loop ((j 0) (k i))
368
+ (cond ((>= j n1) (sk k))
369
+ ((>= k n) (fk))
370
+ ((char=? (string-ref s1 j) (string-ref s k))
371
+ (loop (+ j 1) (+ k 1)))
372
+ (else (fk))))))))
373
+
374
+ (define pregexp-char-word?
375
+ (lambda (c)
376
+ ;too restrictive for Scheme but this
377
+ ;is what \w is in most regexp notations
378
+ (or (char-alphabetic? c)
379
+ (char-numeric? c)
380
+ (char=? c #\_))))
381
+
382
+ (define pregexp-at-word-boundary?
383
+ (lambda (s i n)
384
+ (or (= i 0) (>= i n)
385
+ (let ((c/i (string-ref s i))
386
+ (c/i-1 (string-ref s (- i 1))))
387
+ (let ((c/i/w? (pregexp-check-if-in-char-class?
388
+ c/i ':word))
389
+ (c/i-1/w? (pregexp-check-if-in-char-class?
390
+ c/i-1 ':word)))
391
+ (or (and c/i/w? (not c/i-1/w?))
392
+ (and (not c/i/w?) c/i-1/w?)))))))
393
+
394
+ (define pregexp-check-if-in-char-class?
395
+ (lambda (c char-class)
396
+ (case char-class
397
+ ((:any) (not (char=? c #\newline)))
398
+ ((:super-any) #t)
399
+ ;
400
+ ((:alnum) (or (char-alphabetic? c) (char-numeric? c)))
401
+ ((:alpha) (char-alphabetic? c))
402
+ ((:ascii) (< (char->integer c) 128))
403
+ ((:blank) (or (char=? c #\space) (char=? c *pregexp-tab-char*)))
404
+ ((:cntrl) (< (char->integer c) 32))
405
+ ((:digit) (char-numeric? c))
406
+ ((:graph) (and (>= (char->integer c) 32)
407
+ (not (char-whitespace? c))))
408
+ ((:lower) (char-lower-case? c))
409
+ ((:print) (>= (char->integer c) 32))
410
+ ((:punct) (and (>= (char->integer c) 32)
411
+ (not (char-whitespace? c))
412
+ (not (char-alphabetic? c))
413
+ (not (char-numeric? c))))
414
+ ((:space) (char-whitespace? c))
415
+ ((:upper) (char-upper-case? c))
416
+ ((:word) (or (char-alphabetic? c)
417
+ (char-numeric? c)
418
+ (char=? c #\_)))
419
+ ((:xdigit) (or (char-numeric? c)
420
+ (char-ci=? c #\a) (char-ci=? c #\b)
421
+ (char-ci=? c #\c) (char-ci=? c #\d)
422
+ (char-ci=? c #\e) (char-ci=? c #\f)))
423
+ (else (pregexp-error 'pregexp-check-if-in-char-class?)))))
424
+
425
+ (define pregexp-list-ref
426
+ (lambda (s i)
427
+ ;like list-ref but returns #f if index is
428
+ ;out of bounds
429
+ (let loop ((s s) (k 0))
430
+ (cond ((null? s) #f)
431
+ ((= k i) (car s))
432
+ (else (loop (cdr s) (+ k 1)))))))
433
+
434
+ ;re is a compiled regexp. It's a list that can't be
435
+ ;nil. pregexp-match-positions-aux returns a 2-elt list whose
436
+ ;car is the string-index following the matched
437
+ ;portion and whose cadr contains the submatches.
438
+ ;The proc returns false if there's no match.
439
+
440
+ ;Am spelling loop- as loup- because these shouldn't
441
+ ;be translated into CL loops by scm2cl (although
442
+ ;they are tail-recursive in Scheme)
443
+
444
+ (define pregexp-make-backref-list
445
+ (lambda (re)
446
+ (let sub ((re re))
447
+ (if (pair? re)
448
+ (let ((car-re (car re))
449
+ (sub-cdr-re (sub (cdr re))))
450
+ (if (eqv? car-re ':sub)
451
+ (cons (cons re #f) sub-cdr-re)
452
+ (append (sub car-re) sub-cdr-re)))
453
+ '()))))
454
+
455
+ (define pregexp-match-positions-aux
456
+ (lambda (re s sn start n i)
457
+ (let ((identity (lambda (x) x))
458
+ (backrefs (pregexp-make-backref-list re))
459
+ (case-sensitive? #t))
460
+ (let sub ((re re) (i i) (sk identity) (fk (lambda () #f)))
461
+ ;(printf "sub ~s ~s\n" i re)
462
+ (cond ((eqv? re ':bos)
463
+ ;(if (= i 0) (sk i) (fk))
464
+ (if (= i start) (sk i) (fk))
465
+ )
466
+ ((eqv? re ':eos)
467
+ ;(if (>= i sn) (sk i) (fk))
468
+ (if (>= i n) (sk i) (fk))
469
+ )
470
+ ((eqv? re ':empty)
471
+ (sk i))
472
+ ((eqv? re ':wbdry)
473
+ (if (pregexp-at-word-boundary? s i n)
474
+ (sk i)
475
+ (fk)))
476
+ ((eqv? re ':not-wbdry)
477
+ (if (pregexp-at-word-boundary? s i n)
478
+ (fk)
479
+ (sk i)))
480
+ ((and (char? re) (< i n))
481
+ ;(printf "bingo\n")
482
+ (if ((if case-sensitive? char=? char-ci=?)
483
+ (string-ref s i) re)
484
+ (sk (+ i 1)) (fk)))
485
+ ((and (not (pair? re)) (< i n))
486
+ (if (pregexp-check-if-in-char-class?
487
+ (string-ref s i) re)
488
+ (sk (+ i 1)) (fk)))
489
+ ((and (pair? re) (eqv? (car re) ':char-range) (< i n))
490
+ (let ((c (string-ref s i)))
491
+ (if (let ((c< (if case-sensitive? char<=? char-ci<=?)))
492
+ (and (c< (cadr re) c)
493
+ (c< c (caddr re))))
494
+ (sk (+ i 1)) (fk))))
495
+ ((pair? re)
496
+ (case (car re)
497
+ ((:char-range)
498
+ (if (>= i n) (fk)
499
+ (pregexp-error 'pregexp-match-positions-aux)))
500
+ ((:one-of-chars)
501
+ (if (>= i n) (fk)
502
+ (let loup-one-of-chars ((chars (cdr re)))
503
+ (if (null? chars) (fk)
504
+ (sub (car chars) i sk
505
+ (lambda ()
506
+ (loup-one-of-chars (cdr chars))))))))
507
+ ((:neg-char)
508
+ (if (>= i n) (fk)
509
+ (sub (cadr re) i
510
+ (lambda (i1) (fk))
511
+ (lambda () (sk (+ i 1))))))
512
+ ((:seq)
513
+ (let loup-seq ((res (cdr re)) (i i))
514
+ (if (null? res) (sk i)
515
+ (sub (car res) i
516
+ (lambda (i1)
517
+ (loup-seq (cdr res) i1))
518
+ fk))))
519
+ ((:or)
520
+ (let loup-or ((res (cdr re)))
521
+ (if (null? res) (fk)
522
+ (sub (car res) i
523
+ (lambda (i1)
524
+ (or (sk i1)
525
+ (loup-or (cdr res))))
526
+ (lambda () (loup-or (cdr res)))))))
527
+ ((:backref)
528
+ (let* ((c (pregexp-list-ref backrefs (cadr re)))
529
+ (backref
530
+ (cond (c => cdr)
531
+ (else
532
+ (pregexp-error 'pregexp-match-positions-aux
533
+ 'non-existent-backref re)
534
+ #f))))
535
+ (if backref
536
+ (pregexp-string-match
537
+ (substring s (car backref) (cdr backref))
538
+ s i n (lambda (i) (sk i)) fk)
539
+ (sk i))))
540
+ ((:sub)
541
+ (sub (cadr re) i
542
+ (lambda (i1)
543
+ (set-cdr! (assv re backrefs) (cons i i1))
544
+ (sk i1)) fk))
545
+ ((:lookahead)
546
+ (let ((found-it?
547
+ (sub (cadr re) i
548
+ identity (lambda () #f))))
549
+ (if found-it? (sk i) (fk))))
550
+ ((:neg-lookahead)
551
+ (let ((found-it?
552
+ (sub (cadr re) i
553
+ identity (lambda () #f))))
554
+ (if found-it? (fk) (sk i))))
555
+ ((:lookbehind)
556
+ (let ((n-actual n) (sn-actual sn))
557
+ (set! n i) (set! sn i)
558
+ (let ((found-it?
559
+ (sub (list ':seq '(:between #f 0 #f :super-any)
560
+ (cadr re) ':eos) start
561
+ identity (lambda () #f))))
562
+ (set! n n-actual) (set! sn sn-actual)
563
+ (if found-it? (sk i) (fk)))))
564
+ ((:neg-lookbehind)
565
+ (let ((n-actual n) (sn-actual sn))
566
+ (set! n i) (set! sn i)
567
+ (let ((found-it?
568
+ (sub (list ':seq '(:between #f 0 #f :super-any)
569
+ (cadr re) ':eos) start
570
+ identity (lambda () #f))))
571
+ (set! n n-actual) (set! sn sn-actual)
572
+ (if found-it? (fk) (sk i)))))
573
+ ((:no-backtrack)
574
+ (let ((found-it? (sub (cadr re) i
575
+ identity (lambda () #f))))
576
+ (if found-it?
577
+ (sk found-it?)
578
+ (fk))))
579
+ ((:case-sensitive :case-insensitive)
580
+ (let ((old case-sensitive?))
581
+ (set! case-sensitive?
582
+ (eqv? (car re) ':case-sensitive))
583
+ (sub (cadr re) i
584
+ (lambda (i1)
585
+ (set! case-sensitive? old)
586
+ (sk i1))
587
+ (lambda ()
588
+ (set! case-sensitive? old)
589
+ (fk)))))
590
+ ((:between)
591
+ (let* ((maximal? (not (cadr re)))
592
+ (p (caddr re))
593
+ (q (cadddr re))
594
+ (could-loop-infinitely? (and maximal? (not q)))
595
+ (re (car (cddddr re))))
596
+ (let loup-p ((k 0) (i i))
597
+ (if (< k p)
598
+ (sub re i
599
+ (lambda (i1)
600
+ (if (and could-loop-infinitely?
601
+ (= i1 i))
602
+ (pregexp-error
603
+ 'pregexp-match-positions-aux
604
+ 'greedy-quantifier-operand-could-be-empty))
605
+ (loup-p (+ k 1) i1))
606
+ fk)
607
+ (let ((q (and q (- q p))))
608
+ (let loup-q ((k 0) (i i))
609
+ (let ((fk (lambda ()
610
+ (sk i))))
611
+ (if (and q (>= k q)) (fk)
612
+ (if maximal?
613
+ (sub re i
614
+ (lambda (i1)
615
+ (if (and could-loop-infinitely?
616
+ (= i1 i))
617
+ (pregexp-error
618
+ 'pregexp-match-positions-aux
619
+ 'greedy-quantifier-operand-could-be-empty))
620
+ (or (loup-q (+ k 1) i1)
621
+ (fk)))
622
+ fk)
623
+ (or (fk)
624
+ (sub re i
625
+ (lambda (i1)
626
+ (loup-q (+ k 1) i1))
627
+ fk)))))))))))
628
+ (else (pregexp-error 'pregexp-match-positions-aux))))
629
+ ((>= i n) (fk))
630
+ (else (pregexp-error 'pregexp-match-positions-aux))))
631
+ ;(printf "done\n")
632
+ (let ((backrefs (map cdr backrefs)))
633
+ (and (car backrefs) backrefs)))))
634
+
635
+ (define pregexp-replace-aux
636
+ (lambda (str ins n backrefs)
637
+ (let loop ((i 0) (r ""))
638
+ (if (>= i n) r
639
+ (let ((c (string-ref ins i)))
640
+ (if (char=? c #\\)
641
+ (let* ((br-i (pregexp-read-escaped-number ins i n))
642
+ (br (if br-i (car br-i)
643
+ (if (char=? (string-ref ins (+ i 1)) #\&) 0
644
+ #f)))
645
+ (i (if br-i (cadr br-i)
646
+ (if br (+ i 2)
647
+ (+ i 1)))))
648
+ (if (not br)
649
+ (let ((c2 (string-ref ins i)))
650
+ (loop (+ i 1)
651
+ (if (char=? c2 #\$) r
652
+ (string-append r (string c2)))))
653
+ (loop i
654
+ (let ((backref (pregexp-list-ref backrefs br)))
655
+ (if backref
656
+ (string-append r
657
+ (substring str (car backref) (cdr backref)))
658
+ r)))))
659
+ (loop (+ i 1) (string-append r (string c)))))))))
660
+
661
+ (define pregexp
662
+ (lambda (s)
663
+ (set! *pregexp-space-sensitive?* #t) ;in case it got corrupted
664
+ (list ':sub (car (pregexp-read-pattern s 0 (string-length s))))))
665
+
666
+ (define pregexp-match-positions
667
+ (lambda (pat str . opt-args)
668
+ (cond ((string? pat) (set! pat (pregexp pat)))
669
+ ((pair? pat) #t)
670
+ (else (pregexp-error 'pregexp-match-positions
671
+ 'pattern-must-be-compiled-or-string-regexp
672
+ pat)))
673
+ (let* ((str-len (string-length str))
674
+ (start (if (null? opt-args) 0
675
+ (let ((start (car opt-args)))
676
+ (set! opt-args (cdr opt-args))
677
+ start)))
678
+ (end (if (null? opt-args) str-len
679
+ (car opt-args))))
680
+ (let loop ((i start))
681
+ (and (<= i end)
682
+ (or (pregexp-match-positions-aux
683
+ pat str str-len start end i)
684
+ (loop (+ i 1))))))))
685
+
686
+ (define pregexp-match
687
+ (lambda (pat str . opt-args)
688
+ (let ((ix-prs (apply pregexp-match-positions pat str opt-args)))
689
+ (and ix-prs
690
+ (map
691
+ (lambda (ix-pr)
692
+ (and ix-pr
693
+ (substring str (car ix-pr) (cdr ix-pr))))
694
+ ix-prs)))))
695
+
696
+ (define pregexp-split
697
+ (lambda (pat str)
698
+ ;split str into substrings, using pat as delimiter
699
+ (let ((n (string-length str)))
700
+ (let loop ((i 0) (r '()) (picked-up-one-undelimited-char? #f))
701
+ (cond ((>= i n) (pregexp-reverse! r))
702
+ ((pregexp-match-positions pat str i n)
703
+ =>
704
+ (lambda (y)
705
+ (let ((jk (car y)))
706
+ (let ((j (car jk)) (k (cdr jk)))
707
+ ;(printf "j = ~a; k = ~a; i = ~a~n" j k i)
708
+ (cond ((= j k)
709
+ ;(printf "producing ~s~n" (substring str i (+ j 1)))
710
+ (loop (+ k 1)
711
+ (cons (substring str i (+ j 1)) r) #t))
712
+ ((and (= j i) picked-up-one-undelimited-char?)
713
+ (loop k r #f))
714
+ (else
715
+ ;(printf "producing ~s~n" (substring str i j))
716
+ (loop k (cons (substring str i j) r) #f)))))))
717
+ (else (loop n (cons (substring str i n) r) #f)))))))
718
+
719
+ (define pregexp-replace
720
+ (lambda (pat str ins)
721
+ (let* ((n (string-length str))
722
+ (pp (pregexp-match-positions pat str 0 n)))
723
+ (if (not pp) str
724
+ (let ((ins-len (string-length ins))
725
+ (m-i (caar pp))
726
+ (m-n (cdar pp)))
727
+ (string-append
728
+ (substring str 0 m-i)
729
+ (pregexp-replace-aux str ins ins-len pp)
730
+ (substring str m-n n)))))))
731
+
732
+ (define pregexp-replace*
733
+ (lambda (pat str ins)
734
+ ;return str with every occurrence of pat
735
+ ;replaced by ins
736
+ (let ((pat (if (string? pat) (pregexp pat) pat))
737
+ (n (string-length str))
738
+ (ins-len (string-length ins)))
739
+ (let loop ((i 0) (r ""))
740
+ ;i = index in str to start replacing from
741
+ ;r = already calculated prefix of answer
742
+ (if (>= i n) r
743
+ (let ((pp (pregexp-match-positions pat str i n)))
744
+ (if (not pp)
745
+ (if (= i 0)
746
+ ;this implies pat didn't match str at
747
+ ;all, so let's return original str
748
+ str
749
+ ;else: all matches already found and
750
+ ;replaced in r, so let's just
751
+ ;append the rest of str
752
+ (string-append
753
+ r (substring str i n)))
754
+ (loop (cdar pp)
755
+ (string-append
756
+ r
757
+ (substring str i (caar pp))
758
+ (pregexp-replace-aux str ins ins-len pp))))))))))
759
+
760
+ (define pregexp-quote
761
+ (lambda (s)
762
+ (let loop ((i (- (string-length s) 1)) (r '()))
763
+ (if (< i 0) (list->string r)
764
+ (loop (- i 1)
765
+ (let ((c (string-ref s i)))
766
+ (if (memv c '(#\\ #\. #\? #\* #\+ #\| #\^ #\$
767
+ #\[ #\] #\{ #\} #\( #\)))
768
+ (cons #\\ (cons c r))
769
+ (cons c r))))))))
770
+
771
+ ;(trace pregexp-read-pattern pregexp-read-char-list pregexp-read-piece)
772
+ ;eof