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: (select-module gauche)
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52: (define-syntax %define-cxr
53: (syntax-rules ()
54: ((_ name a b)
55: (begin
56: (define-inline (name x) (a (b x)))
57: (define-in-module scheme name name)
58: (set! (setter name) (lambda (x v) (set! (a (b x)) v)))))))
59:
60: (%define-cxr caaar car caar)
61: (%define-cxr caadr car cadr)
62: (%define-cxr cadar car cdar)
63: (%define-cxr caddr car cddr)
64: (%define-cxr cdaar cdr caar)
65: (%define-cxr cdadr cdr cadr)
66: (%define-cxr cddar cdr cdar)
67: (%define-cxr cdddr cdr cddr)
68: (%define-cxr caaaar caar caar)
69: (%define-cxr caaadr caar cadr)
70: (%define-cxr caadar caar cdar)
71: (%define-cxr caaddr caar cddr)
72: (%define-cxr cadaar cadr caar)
73: (%define-cxr cadadr cadr cadr)
74: (%define-cxr caddar cadr cdar)
75: (%define-cxr cadddr cadr cddr)
76: (%define-cxr cdaaar cdar caar)
77: (%define-cxr cdaadr cdar cadr)
78: (%define-cxr cdadar cdar cdar)
79: (%define-cxr cdaddr cdar cddr)
80: (%define-cxr cddaar cddr caar)
81: (%define-cxr cddadr cddr cadr)
82: (%define-cxr cdddar cddr cdar)
83: (%define-cxr cddddr cddr cddr)
84:
85:
86:
87:
88: (define-inline (null-list? l)
89: (cond ((null? l))
90: ((pair? l) #f)
91: (else (error "argument must be a list, but got:" l))))
92:
93: (with-module gauche.internal
94: (define (%zip-nary-args arglists . seed)
95: (let loop ((as arglists)
96: (cars '())
97: (cdrs '()))
98: (cond ((null? as)
99: (values (reverse! (if (null? seed) cars (cons (car seed) cars)))
100: (reverse! cdrs)))
101: ((null? (car as)) (values #f #f))
102: ((pair? (car as))
103: (loop (cdr as) (cons (caar as) cars) (cons (cdar as) cdrs)))
104: (else
105: (error "argument lists contained an improper list ending with:"
106: (car as))))))
107: )
108:
109: (define (any pred lis . more)
110: (if (null? more)
111: (and (not (null-list? lis))
112: (let loop ((head (car lis)) (tail (cdr lis)))
113: (cond ((null-list? tail) (pred head))
114: ((pred head))
115: (else (loop (car tail) (cdr tail))))))
116: (let loop ((liss (cons lis more)))
117: (receive (cars cdrs)
118: ((with-module gauche.internal %zip-nary-args) liss)
119: (cond ((not cars) #f)
120: ((apply pred cars))
121: (else (loop cdrs)))))))
122:
123: (define (fold kons knil lis . more)
124: (if (null? more)
125: (let loop ((lis lis) (knil knil))
126: (if (null-list? lis) knil (loop (cdr lis) (kons (car lis) knil))))
127: (let loop ((liss (cons lis more)) (knil knil))
128: (receive (cars cdrs)
129: ((with-module gauche.internal %zip-nary-args) liss knil)
130: (if cars
131: (loop cdrs (apply kons cars))
132: knil)))))
133:
134: (define (fold-right kons knil lis . more)
135: (if (null? more)
136: (let rec ((lis lis))
137: (if (null-list? lis)
138: knil
139: (kons (car lis) (rec (cdr lis)))))
140: (let rec ((liss (cons lis more)))
141: (receive (cars cdrs)
142: ((with-module gauche.internal %zip-nary-args) liss)
143: (if cars
144: (apply kons (append! cars (list (rec cdrs))))
145: knil)))))
146:
147: (define (find pred lis)
148: (let loop ((lis lis))
149: (cond ((not (pair? lis)) #f)
150: ((pred (car lis)) (car lis))
151: (else (loop (cdr lis))))))
152:
153: (define (split-at lis i)
154: (let loop ((i i) (rest lis) (r '()))
155: (cond ((= i 0) (values (reverse! r) rest))
156: ((null? rest) (error "given list is too short:" lis))
157: (else (loop (- i 1) (cdr rest) (cons (car rest) r))))))
158:
159:
160:
161:
162:
163:
164:
165:
166:
167: (define-in-module scheme (string-set! str k ch)
168: (check-arg string? str)
169: (check-arg integer? k)
170: (check-arg exact? k)
171: (check-arg char? ch)
172: (let ((len (string-length str)))
173: (when (or (< k 0) (<= len k))
174: (error "string index out of range:" k))
175: (%string-replace-body! str
176: (string-append (substring str 0 k)
177: (string ch)
178: (substring str (+ k 1) len)))))
179:
180: (set! (setter string-ref) string-set!)
181:
182: (define (string-byte-set! str k b)
183: (check-arg string? str)
184: (check-arg integer? k)
185: (check-arg exact? k)
186: (check-arg integer? b)
187: (let ((siz (string-size str))
188: (out (open-output-string :private? #t)))
189: (when (or (< k 0) (<= siz k))
190: (error "string index out of range:" k))
191: (display (byte-substring str 0 k) out)
192: (write-byte b out)
193: (display (byte-substring str (+ k 1) siz) out)
194: (%string-replace-body! str (get-output-byte-string out))))
195:
196: (set! (setter string-byte-ref) string-byte-set!)
197:
198: (define (string-fill! str c . opts)
199: (check-arg string? str)
200: (check-arg char? c)
201: (let1 len (string-length str)
202: (let-optionals* opts ((start 0)
203: (end len))
204: (when (or (< start 0) (< len start))
205: (error "start index out of range:" start))
206: (when (or (< end 0) (< len end))
207: (error "end index out of range:" end))
208: (when (< end start)
209: (errorf "end index ~s is smaller than start index ~s" end start))
210: (if (and (= start 0) (= end len))
211: (%string-replace-body! str (make-string len c))
212: (%string-replace-body! str
213: (string-append (substring str 0 start)
214: (make-string (- end start) c)
215: (substring str end len)))))))
216:
217: (define-reader-ctor 'string-interpolate
218: (lambda (s) (string-interpolate s)))
219:
220:
221:
222:
223: (define-in-module scheme call/cc call-with-current-continuation)
224:
225:
226:
227:
228: (define-values (error errorf)
229: (let ()
230: (define (compose-error-message msg args)
231: (let1 p (open-output-string)
232: (display msg p)
233: (let loop ((args args))
234: (if (null? args)
235: (get-output-string p)
236: (begin (display " " p)
237: (write/ss (car args) p)
238: (loop (cdr args)))))))
239: (define (scan-keys args)
240: (let loop ((args args)
241: (keys '()))
242: (if (and (not (null? args))
243: (keyword? (car args))
244: (not (null? (cdr args))))
245: (loop (cddr args) (list* (cadr args) (car args) keys))
246: (values (reverse! keys) args))))
247:
248: (define (error msg . args)
249: (raise
250: (cond
251: ((is-a? msg <condition-meta>)
252: (receive (keys msgs) (scan-keys args)
253: (if (null? msgs)
254: (apply make msg keys)
255: (apply make msg
256: :message (compose-error-message (car msgs) (cdr msgs))
257: keys))))
258: (else (make <error> :message (compose-error-message msg args))))))
259:
260: (define (errorf fmt . args)
261: (raise
262: (cond
263: ((is-a? fmt <condition-meta>)
264: (receive (keys msgs) (scan-keys args)
265: (if (null? msgs)
266: (apply make fmt keys)
267: (apply make fmt
268: :message (apply format/ss #f msgs)
269: keys))))
270: (else (make <error> :message (apply format/ss #f fmt args))))))
271:
272: (values error errorf)))
273:
274: (define <exception> <condition>)
275:
276:
277:
278:
279: (define (symbol-bound? name . maybe-module)
280: (global-variable-bound? (get-optional maybe-module #f) name))
281:
282:
283:
284:
285: (define-in-module scheme (call-with-values producer consumer)
286: (receive vals (producer) (apply consumer vals)))
287:
288:
289:
290:
291: (define (sys-sigset . signals)
292: (if (null? signals)
293: (make <sys-sigset>)
294: (apply sys-sigset-add! (make <sys-sigset>) signals)))
295:
296:
297:
298:
299: (define (getter-with-setter get set)
300: (let ((proc (lambda x (apply get x))))
301: (set! (setter proc) set)
302: proc))
303:
304:
305:
306:
307:
308: (define read-with-shared-structure read)
309: (define read/ss read)
310:
311: (define (write-with-shared-structure obj . args)
312: (write* obj (if (pair? args) (car args) (current-output-port))))
313: (define write/ss write-with-shared-structure)
314:
315:
316:
317:
318:
319: (define (print . args) (for-each display args) (newline))
320:
321: (define-values (format format/ss)
322: (letrec ((format-int
323: (lambda (port fmt args shared?)
324: (cond ((eqv? port #f)
325: (let ((out (open-output-string :private? #t)))
326: (%format out fmt args shared?)
327: (get-output-string out)))
328: ((eqv? port #t)
329: (%format (current-output-port) fmt args shared?))
330: (else (%format port fmt args shared?)))))
331: (format
332: (lambda (fmt . args)
333: (if (string? fmt)
334: (format-int #f fmt args #f)
335: (format-int fmt (car args) (cdr args) #f))))
336: (format/ss
337: (lambda (fmt . args)
338: (if (string? fmt)
339: (format-int #f fmt args #t)
340: (format-int fmt (car args) (cdr args) #t))))
341: )
342: (values format format/ss)))
343:
344:
345:
346:
347:
348:
349:
350:
351: (define-in-module scheme (open-input-file filename . args)
352: (if (get-keyword :encoding args #f)
353: (apply %open-input-file/conv filename args)
354: (apply %open-input-file filename args)))
355:
356: (define-in-module scheme (open-output-file filename . args)
357: (if (get-keyword :encoding args #f)
358: (apply %open-output-file/conv filename args)
359: (apply %open-output-file filename args)))
360:
361:
362:
363: (define-in-module scheme (call-with-input-file filename proc . flags)
364: (let ((port (apply open-input-file filename flags)))
365: (with-error-handler
366: (lambda (e)
367: (when port (close-input-port port))
368: (raise e))
369: (lambda ()
370: (receive r (proc port)
371: (when port (close-input-port port))
372: (apply values r))))))
373:
374: (define-in-module scheme (call-with-output-file filename proc . flags)
375: (let ((port (apply open-output-file filename flags)))
376: (with-error-handler
377: (lambda (e)
378: (when port (close-output-port port))
379: (raise e))
380: (lambda ()
381: (receive r (proc port)
382: (when port (close-output-port port))
383: (apply values r))))))
384:
385: (define-in-module scheme (with-input-from-file filename thunk . flags)
386: (let ((port (apply open-input-file filename flags)))
387: (and port
388: (with-error-handler
389: (lambda (e) (close-input-port port) (raise e))
390: (lambda ()
391: (receive r (with-input-from-port port thunk)
392: (close-input-port port)
393: (apply values r)))))))
394:
395:
396: (define-in-module scheme (with-output-to-file filename thunk . flags)
397: (let ((port (apply open-output-file filename flags)))
398: (and port
399: (with-error-handler
400: (lambda (e) (close-output-port port) (raise e))
401: (lambda ()
402: (receive r (with-output-to-port port thunk)
403: (close-output-port port)
404: (apply values r)))))))
405:
406:
407:
408: (define (with-output-to-string thunk)
409: (let ((out (open-output-string)))
410: (with-output-to-port out thunk)
411: (get-output-string out)))
412:
413: (define (with-input-from-string str thunk)
414: (with-input-from-port (open-input-string str) thunk))
415:
416: (define (call-with-output-string proc)
417: (let ((out (open-output-string)))
418: (proc out)
419: (get-output-string out)))
420:
421: (define (call-with-input-string str proc)
422: (let ((in (open-input-string str)))
423: (proc in)))
424:
425: (define (call-with-string-io str proc)
426: (let ((out (open-output-string))
427: (in (open-input-string str)))
428: (proc in out)
429: (get-output-string out)))
430:
431: (define (with-string-io str thunk)
432: (with-output-to-string
433: (lambda ()
434: (with-input-from-string str
435: thunk))))
436:
437: (define (write-to-string obj . args)
438: (with-output-to-string
439: (lambda () ((if (pair? args) (car args) write) obj))))
440:
441: (define (read-from-string string . args)
442: (with-input-from-string
443: (if (null? args) string (apply %maybe-substring string args))
444: read))
445:
446:
447:
448: (define-syntax %with-ports
449: (syntax-rules ()
450: ((_ "tmp" (tmp ...) () (port ...) (param ...) thunk)
451: (let ((tmp #f) ...)
452: (dynamic-wind
453: (lambda () (when port (set! tmp (param port))) ...)
454: thunk
455: (lambda () (when tmp (param tmp)) ...))))
456: ((_ "tmp" tmps (port . more) ports params thunk)
457: (%with-ports "tmp" (tmp . tmps) more ports params thunk))
458: ((_ ((param port) ...) thunk)
459: (%with-ports "tmp" () (port ...) (port ...) (param ...) thunk))
460: ))
461:
462: (define (with-input-from-port port thunk)
463: (%with-ports ((current-input-port port)) thunk))
464:
465: (define (with-output-to-port port thunk)
466: (%with-ports ((current-output-port port)) thunk))
467:
468: (define (with-error-to-port port thunk)
469: (%with-ports ((current-error-port port)) thunk))
470:
471: (define (with-ports iport oport eport thunk)
472: (%with-ports ((current-input-port iport)
473: (current-output-port oport)
474: (current-error-port eport))
475: thunk))