diff options
author | Case Duckworth | 2023-08-13 23:13:53 -0500 |
---|---|---|
committer | Case Duckworth | 2023-08-13 23:13:53 -0500 |
commit | f4e64d32c5de15ddcc39ee9545ca5d465cc3d80d (patch) | |
tree | 0b7c1a1a78acb8272e8102a0c963614a71d447a1 /chicanery.extras.scm | |
parent | I don't even know any more (diff) | |
parent | Update README (diff) | |
download | chicanery-f4e64d32c5de15ddcc39ee9545ca5d465cc3d80d.tar.gz chicanery-f4e64d32c5de15ddcc39ee9545ca5d465cc3d80d.zip |
Return to the good old working days
Diffstat (limited to 'chicanery.extras.scm')
-rw-r--r-- | chicanery.extras.scm | 281 |
1 files changed, 143 insertions, 138 deletions
diff --git a/chicanery.extras.scm b/chicanery.extras.scm index f9bb4a1..ae2823e 100644 --- a/chicanery.extras.scm +++ b/chicanery.extras.scm | |||
@@ -1,145 +1,150 @@ | |||
1 | (module (chicanery extras) ( append for-each map | 1 | (export list-map list-for-each list-append |
2 | list-append list-for-each list-map | 2 | map for-each append) |
3 | ref copy | ||
4 | atom? defined? | ||
5 | read-port-chunk-size read-port | ||
6 | with-output-to-string with-input-from-string | ||
7 | displayed written print ->string) | ||
8 | (import scheme (chicanery base)) | ||
9 | |||
10 | (define list-append append) | ||
11 | (define list-for-each for-each) | ||
12 | (define list-map map) | ||
13 | |||
14 | (define (map proc . collections) | ||
15 | (let ((first (car collections))) ; we only need to check the first one | ||
16 | (cond | ||
17 | ((list? first) | ||
18 | (apply list-map proc collections)) | ||
19 | ((vector? first) | ||
20 | (apply vector-map proc collections)) | ||
21 | ((string? first) | ||
22 | (apply string-map proc collections)) | ||
23 | (else (error "Bad datatype" first))))) | ||
24 | |||
25 | (define (for-each proc . collections) | ||
26 | (let ((first (car collections))) ; we only need to check the first one | ||
27 | (cond | ||
28 | ((list? first) | ||
29 | (apply list-for-each proc collections)) | ||
30 | ((vector? first) | ||
31 | (apply vector-for-each proc collections)) | ||
32 | ((string? first) | ||
33 | (apply string-for-each proc collections)) | ||
34 | (else (error "Bad datatype" first))))) | ||
35 | |||
36 | (define (append . collections) | ||
37 | (let ((first (car collections))) ; we only need to check the first one | ||
38 | (cond | ||
39 | ((list? first) | ||
40 | (apply list-append collections)) | ||
41 | ((vector? first) | ||
42 | (apply vector-append collections)) | ||
43 | ((string? first) | ||
44 | (apply string-append collections)) | ||
45 | ((bytevector? first) | ||
46 | (apply bytevector-append collections)) | ||
47 | (else (error "Bad datatype" first))))) | ||
48 | 3 | ||
49 | ;;; Extended generic functions. | 4 | (define list-map map) |
50 | ;; These functions already have a list- version defined, but no non-prefixed | 5 | (define list-for-each for-each) |
51 | ;; one. So I'm fixing that. | 6 | (define list-append append) |
52 | (define (ref collection k) | 7 | |
8 | (define (map proc . collections) | ||
9 | (let ((first (car collections))) ; we only need to check the first one | ||
10 | (cond | ||
11 | ((list? first) | ||
12 | (apply list-map proc collections)) | ||
13 | ((vector? first) | ||
14 | (apply vector-map proc collections)) | ||
15 | ((string? first) | ||
16 | (apply string-map proc collections)) | ||
17 | (else (error "Bad datatype" first))))) | ||
18 | |||
19 | (define (for-each proc . collections) | ||
20 | (let ((first (car collections))) ; we only need to check the first one | ||
53 | (cond | 21 | (cond |
54 | ((list? collection) | 22 | ((list? first) |
55 | (list-ref collection k)) | 23 | (apply list-for-each proc collections)) |
56 | ((vector? collection) | 24 | ((vector? first) |
57 | (vector-ref collection k)) | 25 | (apply vector-for-each proc collections)) |
58 | ((string? collection) | 26 | ((string? first) |
59 | (string-ref collection k)) | 27 | (apply string-for-each proc collections)) |
60 | ((bytevector? collection) | 28 | (else (error "Bad datatype" first))))) |
61 | (bytevector-u8-ref collection k)) | 29 | |
62 | (else (error "Bad datatype" collection)))) | 30 | (define (append . collections) |
63 | 31 | (let ((first (car collections))) ; we only need to check the first one | |
64 | ;; I'm not going to generalize -copy! because I don't think it's a great idea, | ||
65 | ;; really. | ||
66 | (define (copy collection) | ||
67 | (cond | 32 | (cond |
68 | ((list? collection) | 33 | ((list? first) |
69 | (list-copy collection)) | 34 | (apply list-append collections)) |
70 | ((vector? collection) | 35 | ((vector? first) |
71 | (vector-copy collection)) | 36 | (apply vector-append collections)) |
72 | ((string? collection) | 37 | ((string? first) |
73 | (string-copy collection)) | 38 | (apply string-append collections)) |
74 | ((bytevector? collection) | 39 | ((bytevector? first) |
75 | (bytevector-copy collection)) | 40 | (apply bytevector-append collections)) |
76 | (else (error "Bad datatype" collection)))) | 41 | (else (error "Bad datatype" first))))) |
42 | |||
43 | ;;; Extended generic functions. | ||
44 | ;; These functions already have a list- version defined, but no non-prefixed | ||
45 | ;; one. So I'm fixing that. | ||
46 | (define (ref collection k) | ||
47 | (cond | ||
48 | ((list? collection) | ||
49 | (list-ref collection k)) | ||
50 | ((vector? collection) | ||
51 | (vector-ref collection k)) | ||
52 | ((string? collection) | ||
53 | (string-ref collection k)) | ||
54 | ((bytevector? collection) | ||
55 | (bytevector-u8-ref collection k)) | ||
56 | (else (error "Bad datatype" collection)))) | ||
57 | |||
58 | ;; I'm not going to generalize -copy! because I don't think it's a great idea, | ||
59 | ;; really. | ||
60 | (define (copy collection) | ||
61 | (cond | ||
62 | ((list? collection) | ||
63 | (list-copy collection)) | ||
64 | ((vector? collection) | ||
65 | (vector-copy collection)) | ||
66 | ((string? collection) | ||
67 | (string-copy collection)) | ||
68 | ((bytevector? collection) | ||
69 | (bytevector-copy collection)) | ||
70 | (else (error "Bad datatype" collection)))) | ||
77 | 71 | ||
78 | ;;; Definitions that should be in scheme | 72 | ;;; Definitions that should be in scheme |
79 | ;; This sections should be as small as possible | 73 | ;; This sections should be as small as possible |
80 | 74 | ||
81 | (define (atom? x) | 75 | (export read-port |
82 | (and (not (pair? x)) | 76 | read-port-chunk-size) |
83 | (not (null? x)))) | 77 | |
84 | 78 | ||
85 | (define read-port-chunk-size | 79 | (define (%read-port port) |
86 | (make-parameter 512)) | 80 | (let ((chunk-size (read-port-chunk-size))) |
87 | 81 | (let loop ((next (read-string chunk-size port)) | |
88 | (define (%read-port port) | 82 | (blank? #f) |
89 | (let ((chunk-size (read-port-chunk-size))) | 83 | (acc '())) |
90 | (let loop ((next (read-string chunk-size port)) | 84 | (cond |
91 | (blank? #f) | 85 | ((or (eof-object? next) |
92 | (acc '())) | 86 | (and blank? (equal? next ""))) |
93 | (cond | 87 | (apply string-append (reverse acc))) |
94 | ((or (eof-object? next) | 88 | ((equal? next "") |
95 | (and blank? (equal? next ""))) | 89 | (loop (read-string chunk-size port) |
96 | (apply string-append (reverse acc))) | 90 | #t |
97 | ((equal? next "") | 91 | (cons next acc))) |
98 | (loop (read-string chunk-size port) | 92 | (else |
99 | #t | 93 | (loop (read-string chunk-size port) |
100 | (cons next acc))) | 94 | blank? |
101 | (else | 95 | (cons next acc))))))) |
102 | (loop (read-string chunk-size port) | 96 | |
103 | blank? | 97 | (define read-port-chunk-size |
104 | (cons next acc))))))) | 98 | (make-parameter 512)) |
105 | 99 | ||
106 | (define read-port | 100 | (define read-port |
107 | (case-lambda | 101 | (case-lambda |
108 | (() (%read-port (current-input-port))) | 102 | (() (%read-port (current-input-port))) |
109 | ((p) (%read-port p)))) | 103 | ((p) (%read-port p)))) |
110 | 104 | ||
111 | (define (defined? sym) | 105 | (export atom? defined?) |
112 | (call-with-current-continuation | 106 | |
113 | (lambda (k) | 107 | (define (atom? x) |
114 | (with-exception-handler | 108 | (not (or (null? x) |
115 | (lambda (e) (k #f)) | 109 | (pair? x)))) |
116 | (lambda () | 110 | |
117 | (eval sym (interaction-environment)) | 111 | (define (defined? sym) |
118 | #t))))) | 112 | (call-with-current-continuation |
119 | 113 | (lambda (k) | |
120 | (define (with-output-to-string thunk) | 114 | (with-exception-handler |
121 | (call-with-port (open-output-string) | 115 | (lambda (e) (k #f)) |
122 | (lambda (port) | 116 | (lambda () |
123 | (parameterize ((current-output-port port)) | 117 | (eval sym (interaction-environment)) |
124 | (thunk)) | 118 | #t))))) |
125 | (get-output-string port)))) | 119 | |
126 | 120 | (export with-output-to-string | |
127 | (define (with-input-from-string s thunk) | 121 | with-input-from-string) |
128 | (call-with-port (open-input-string s) | 122 | |
129 | (lambda (port) | 123 | (define (with-output-to-string thunk) |
130 | (parameterize ((current-input-port port)) | 124 | (call-with-port (open-output-string) |
131 | (thunk))))) | 125 | (lambda (port) |
132 | 126 | (parameterize ((current-output-port port)) | |
133 | (define (displayed x) | 127 | (thunk)) |
134 | (with-output-to-string | 128 | (get-output-string port)))) |
135 | (lambda () (display x)))) | 129 | |
136 | 130 | (define (with-input-from-string s thunk) | |
137 | (define (written x) | 131 | (call-with-port (open-input-string s) |
138 | (with-output-to-string | 132 | (lambda (port) |
139 | (lambda () (write x)))) | 133 | (parameterize ((current-input-port port)) |
140 | 134 | (thunk))))) | |
141 | (define (print . xs) | 135 | |
142 | (for-each display xs) | 136 | (export displayed ->string written print) |
143 | (newline)) | 137 | |
144 | 138 | (define (displayed x) | |
145 | (define ->string displayed)) | 139 | (with-output-to-string |
140 | (lambda () (display x)))) | ||
141 | |||
142 | (define (written x) | ||
143 | (with-output-to-string | ||
144 | (lambda () (write x)))) | ||
145 | |||
146 | (define (print . xs) | ||
147 | (for-each display xs) | ||
148 | (newline)) | ||
149 | |||
150 | (define ->string displayed) | ||