1 ;;;============================================================================
5 ;;; Copyright (c) 1994-2011 by Marc Feeley, All Rights Reserved.
7 ;;;============================================================================
9 (##include "header.scm")
11 ;;;============================================================================
13 ;;; Implementation of exceptions.
15 (implement-library-type-datum-parsing-exception)
17 (define-prim (##raise-datum-parsing-exception kind readenv . parameters)
19 (macro-make-datum-parsing-exception
24 (implement-library-type-unterminated-process-exception)
26 (define-prim (##raise-unterminated-process-exception proc . args)
27 (##extract-procedure-and-arguments
33 (lambda (procedure arguments dummy1 dummy2 dummy3)
35 (macro-make-unterminated-process-exception procedure arguments)))))
37 (implement-library-type-nonempty-input-port-character-buffer-exception)
39 (define-prim (##raise-nonempty-input-port-character-buffer-exception proc . args)
40 (##extract-procedure-and-arguments
46 (lambda (procedure arguments dummy1 dummy2 dummy3)
48 (macro-make-nonempty-input-port-character-buffer-exception procedure arguments)))))
50 (implement-library-type-no-such-file-or-directory-exception)
52 (define-prim (##raise-no-such-file-or-directory-exception proc . args)
53 (##extract-procedure-and-arguments
59 (lambda (procedure arguments dummy1 dummy2 dummy3)
61 (macro-make-no-such-file-or-directory-exception
65 ;;;----------------------------------------------------------------------------
67 ;;; Define type checking procedures.
69 (define-fail-check-type settings
72 (define-fail-check-type exact-integer-or-string-or-settings
73 'exact-integer-or-string-or-settings)
75 (define-fail-check-type string-or-ip-address
76 'string-or-ip-address)
78 ;;;----------------------------------------------------------------------------
80 ;;; Implementation of write environments.
82 (define-prim (##make-writeenv
105 ;;;----------------------------------------------------------------------------
107 ;;; Implementation of read environments.
109 (define-prim (##make-readenv
125 (define-prim (##readenv-current-filepos re)
126 (##readenv-relative-filepos re 0))
128 (define-prim (##readenv-relative-filepos re offset)
130 (macro-readenv-port re))
132 (macro-character-port-rlines port))
134 (##fixnum.- (##fixnum.+ (macro-character-port-rchars port)
135 (macro-character-port-rlo port))
138 (##fixnum.- char-count
139 (macro-character-port-rcurline port))))
140 (##make-filepos line col char-count)))
142 ;;;----------------------------------------------------------------------------
144 ;;; Implementation of port settings.
146 (define-prim (##make-psettings
153 (macro-make-psettings
155 (macro-make-psettings-options
156 (macro-default-readtable)
157 (macro-default-char-encoding)
158 (macro-default-char-encoding-errors)
159 (macro-default-eol-encoding)
160 (macro-default-buffering)
161 (macro-default-permanent-close))
162 (macro-make-psettings-options
163 (macro-default-readtable)
164 (macro-default-char-encoding-errors)
165 (macro-default-char-encoding)
166 (macro-default-eol-encoding)
167 (macro-default-buffering)
168 (macro-default-permanent-close))
171 (macro-default-arguments)
172 (macro-default-environment)
173 (macro-default-directory)
174 (macro-default-append)
175 (macro-default-create)
176 (macro-default-truncate)
177 (macro-default-permissions)
178 (macro-default-output-width)
179 (macro-default-stdin-redir)
180 (macro-default-stdout-redir)
181 (macro-default-stderr-redir)
182 (macro-default-pseudo-term)
183 (macro-default-show-console)
184 (macro-default-server-address)
185 (macro-default-port-number)
186 (macro-default-socket-type)
187 (macro-default-coalesce)
188 (macro-default-keep-alive)
189 (macro-default-backlog)
190 (macro-default-reuse-address)
191 (macro-default-broadcast)
192 (macro-default-ignore-hidden))))
200 (define-prim (##parse-psettings!
210 (define (error-improper-list)
213 (define (direction value)
214 (cond ((##eq? value 'input)
215 (macro-direction-in))
216 ((##eq? value 'output)
217 (macro-direction-out))
218 ((##eq? value 'input-output)
219 (macro-direction-inout))
223 (define (readtable value)
224 (cond ((macro-readtable? value)
229 (define (char-encoding value)
230 (cond ((##eq? value 'ASCII)
231 (macro-char-encoding-ASCII))
232 ((##eq? value 'ISO-8859-1)
233 (macro-char-encoding-ISO-8859-1))
234 ((##eq? value 'UTF-8)
235 (macro-char-encoding-UTF-8))
236 ((##eq? value 'UTF-16)
237 (macro-char-encoding-UTF-16))
238 ((##eq? value 'UTF-16LE)
239 (macro-char-encoding-UTF-16LE))
240 ((##eq? value 'UTF-16BE)
241 (macro-char-encoding-UTF-16BE))
243 (macro-char-encoding-UTF))
244 ((##eq? value 'UTF-fallback-ASCII)
245 (macro-char-encoding-UTF-fallback-ASCII))
246 ((##eq? value 'UTF-fallback-ISO-8859-1)
247 (macro-char-encoding-UTF-fallback-ISO-8859-1))
248 ((##eq? value 'UTF-fallback-UTF-8)
249 (macro-char-encoding-UTF-fallback-UTF-8))
250 ((##eq? value 'UTF-fallback-UTF-16)
251 (macro-char-encoding-UTF-fallback-UTF-16))
252 ((##eq? value 'UTF-fallback-UTF-16LE)
253 (macro-char-encoding-UTF-fallback-UTF-16LE))
254 ((##eq? value 'UTF-fallback-UTF-16BE)
255 (macro-char-encoding-UTF-fallback-UTF-16BE))
256 ((##eq? value 'UCS-2)
257 (macro-char-encoding-UCS-2))
258 ((##eq? value 'UCS-2LE)
259 (macro-char-encoding-UCS-2LE))
260 ((##eq? value 'UCS-2BE)
261 (macro-char-encoding-UCS-2BE))
262 ((##eq? value 'UCS-4)
263 (macro-char-encoding-UCS-4))
264 ((##eq? value 'UCS-4LE)
265 (macro-char-encoding-UCS-4LE))
266 ((##eq? value 'UCS-4BE)
267 (macro-char-encoding-UCS-4BE))
268 ;; ((##eq? value 'wchar)
269 ;; (macro-char-encoding-wchar))
270 ;; ((##eq? value 'native)
271 ;; (macro-char-encoding-native))
275 (define (char-encoding-errors value)
276 (cond ((##eq? value #t)
277 (macro-char-encoding-errors-on))
279 (macro-char-encoding-errors-off))
283 (define (eol-encoding value)
284 (cond ((##eq? value 'lf)
285 (macro-eol-encoding-lf))
287 (macro-eol-encoding-cr))
288 ((##eq? value 'cr-lf)
289 (macro-eol-encoding-crlf))
293 (define (buffering value)
294 (cond ((##eq? value #t)
295 (macro-full-buffering))
297 (macro-line-buffering))
299 (macro-no-buffering))
303 (define (permanent-close value)
304 (cond ((##eq? value #t)
305 (macro-permanent-close))
307 (macro-no-permanent-close))
317 (define (arguments value)
318 (##copy-string-list value))
320 (define (environment value)
324 (##copy-string-list value))))
326 (define (directory value)
329 (define (append-flag value)
330 (cond ((##eq? (macro-psettings-direction psettings)
331 (macro-direction-in))
338 (define (create-flag value)
339 (cond ((##eq? (macro-psettings-direction psettings)
340 (macro-direction-in))
344 ((##eq? value 'maybe)
345 (macro-maybe-create))
351 (define (truncate-flag value)
352 (cond ((##eq? (macro-psettings-direction psettings)
353 (macro-direction-in))
358 (macro-no-truncate))))
360 (define (permissions value)
361 (cond ((##eq? (macro-psettings-direction psettings)
362 (macro-direction-in))
364 ((and (##fixnum? value)
365 (##not (##fixnum.< value 0))
366 (##fixnum.< value #o1000))
371 (define (output-width value)
372 (cond ((##eq? (macro-psettings-direction psettings)
373 (macro-direction-in))
375 ((and (##fixnum? value)
376 (##fixnum.< 0 value))
381 (define (stdin-redir value)
382 (cond ((##eq? value #t)
383 (macro-stdin-from-port))
385 (macro-stdin-unchanged))
389 (define (stdout-redir value)
390 (cond ((##eq? value #t)
391 (macro-stdout-to-port))
393 (macro-stdout-unchanged))
397 (define (stderr-redir value)
398 (cond ((##eq? value #t)
399 (macro-stderr-to-port))
401 (macro-stderr-unchanged))
405 (define (pseudo-term value)
406 (cond ((##eq? value #t)
409 (macro-no-pseudo-term))
413 (define (show-console value)
414 (cond ((##eq? value #t)
415 (macro-show-console))
417 (macro-no-show-console))
421 (define (port-number value)
422 (cond ((and (##fixnum? value)
423 (##fixnum.<= 0 value)
424 (##fixnum.<= value 65535))
429 (define (socket-type value)
430 (cond ((or (##eq? value 'TCP) (##eq? value 'tcp))
431 (macro-socket-type-TCP))
432 ((or (##eq? value 'UDP) (##eq? value 'udp))
433 (macro-socket-type-UDP))
434 ((or (##eq? value 'RAW) (##eq? value 'raw))
435 (macro-socket-type-RAW))
439 (define (coalesce value)
440 (cond ((##eq? value #t)
447 (define (keep-alive value)
448 (cond ((##eq? value #t)
451 (macro-no-keep-alive))
455 (define (backlog value)
456 (if (and (##fixnum? value)
457 (##not (##fixnum.< value 0)))
461 (define (reuse-address value)
462 (cond ((##eq? value #t)
463 (macro-reuse-address))
465 (macro-no-reuse-address))
469 (define (broadcast value)
470 (cond ((##eq? value #t)
473 (macro-no-broadcast))
477 (define (ignore-hidden value)
478 (cond ((##eq? (macro-psettings-direction psettings)
479 (macro-direction-out))
482 (macro-ignore-hidden))
484 (macro-ignore-nothing))
485 ((##eq? value 'dot-and-dot-dot)
486 (macro-ignore-dot-and-dot-dot))
490 (let loop ((lst settings))
491 (macro-force-vars (lst)
493 (let ((name (##car lst))
495 (macro-force-vars (name rest1)
496 (if (and (##memq name allowed-settings)
499 (let ((value (##car rest1))
500 (rest2 (##cdr rest1)))
501 (macro-force-vars (value)
503 (cond ((##eq? name 'direction:)
504 (let ((x (direction value)))
507 (macro-psettings-direction-set!
513 ((and (##eq? name 'input-readtable:)
516 (macro-psettings-direction psettings)
517 (macro-direction-out))))
518 (let ((x (readtable value)))
521 (macro-psettings-options-readtable-set!
522 (macro-psettings-roptions psettings)
527 ((and (##eq? name 'output-readtable:)
530 (macro-psettings-direction psettings)
531 (macro-direction-in))))
532 (let ((x (readtable value)))
535 (macro-psettings-options-readtable-set!
536 (macro-psettings-woptions psettings)
541 ((##eq? name 'readtable:)
542 (let ((x (readtable value)))
545 (macro-psettings-options-readtable-set!
546 (macro-psettings-roptions psettings)
548 (macro-psettings-options-readtable-set!
549 (macro-psettings-woptions psettings)
554 ((and (##eq? name 'input-char-encoding:)
557 (macro-psettings-direction psettings)
558 (macro-direction-out))))
559 (let ((x (char-encoding value)))
562 (macro-psettings-options-char-encoding-set!
563 (macro-psettings-roptions psettings)
568 ((and (##eq? name 'output-char-encoding:)
571 (macro-psettings-direction psettings)
572 (macro-direction-in))))
573 (let ((x (char-encoding value)))
576 (macro-psettings-options-char-encoding-set!
577 (macro-psettings-woptions psettings)
582 ((##eq? name 'char-encoding:)
583 (let ((x (char-encoding value)))
586 (macro-psettings-options-char-encoding-set!
587 (macro-psettings-roptions psettings)
589 (macro-psettings-options-char-encoding-set!
590 (macro-psettings-woptions psettings)
595 ((and (##eq? name 'input-char-encoding-errors:)
598 (macro-psettings-direction psettings)
599 (macro-direction-out))))
600 (let ((x (char-encoding-errors value)))
603 (macro-psettings-options-char-encoding-errors-set!
604 (macro-psettings-roptions psettings)
609 ((and (##eq? name 'output-char-encoding-errors:)
612 (macro-psettings-direction psettings)
613 (macro-direction-in))))
614 (let ((x (char-encoding-errors value)))
617 (macro-psettings-options-char-encoding-errors-set!
618 (macro-psettings-woptions psettings)
623 ((##eq? name 'char-encoding-errors:)
624 (let ((x (char-encoding-errors value)))
627 (macro-psettings-options-char-encoding-errors-set!
628 (macro-psettings-roptions psettings)
630 (macro-psettings-options-char-encoding-errors-set!
631 (macro-psettings-woptions psettings)
636 ((and (##eq? name 'input-eol-encoding:)
639 (macro-psettings-direction psettings)
640 (macro-direction-out))))
641 (let ((x (eol-encoding value)))
644 (macro-psettings-options-eol-encoding-set!
645 (macro-psettings-roptions psettings)
650 ((and (##eq? name 'output-eol-encoding:)
653 (macro-psettings-direction psettings)
654 (macro-direction-in))))
655 (let ((x (eol-encoding value)))
658 (macro-psettings-options-eol-encoding-set!
659 (macro-psettings-woptions psettings)
664 ((##eq? name 'eol-encoding:)
665 (let ((x (eol-encoding value)))
668 (macro-psettings-options-eol-encoding-set!
669 (macro-psettings-roptions psettings)
671 (macro-psettings-options-eol-encoding-set!
672 (macro-psettings-woptions psettings)
677 ((and (##eq? name 'input-buffering:)
680 (macro-psettings-direction psettings)
681 (macro-direction-out))))
682 (let ((x (buffering value)))
685 (macro-psettings-options-buffering-set!
686 (macro-psettings-roptions psettings)
691 ((and (##eq? name 'output-buffering:)
694 (macro-psettings-direction psettings)
695 (macro-direction-in))))
696 (let ((x (buffering value)))
699 (macro-psettings-options-buffering-set!
700 (macro-psettings-woptions psettings)
705 ((##eq? name 'buffering:)
706 (let ((x (buffering value)))
709 (macro-psettings-options-buffering-set!
710 (macro-psettings-roptions psettings)
712 (macro-psettings-options-buffering-set!
713 (macro-psettings-woptions psettings)
718 ((##eq? name 'permanent-close:)
719 (let ((x (permanent-close value)))
722 (macro-psettings-options-permanent-close-set!
723 (macro-psettings-roptions psettings)
725 (macro-psettings-options-permanent-close-set!
726 (macro-psettings-woptions psettings)
732 (let ((x (path value)))
735 (macro-psettings-path-set!
742 (let ((x (init value)))
745 (macro-psettings-init-set!
751 ((##eq? name 'arguments:)
752 (let ((x (arguments value)))
756 (macro-psettings-arguments-set!
761 ((##eq? name 'environment:)
762 (let ((x (environment value)))
766 (macro-psettings-environment-set!
771 ((##eq? name 'directory:)
772 (let ((x (directory value)))
776 (macro-psettings-directory-set!
781 ((##eq? name 'append:)
782 (let ((x (append-flag value)))
785 (macro-psettings-append-set!
791 ((##eq? name 'create:)
792 (let ((x (create-flag value)))
795 (macro-psettings-create-set!
801 ((##eq? name 'truncate:)
802 (let ((x (truncate-flag value)))
805 (macro-psettings-truncate-set!
811 ((##eq? name 'permissions:)
812 (let ((x (permissions value)))
815 (macro-psettings-permissions-set!
821 ((##eq? name 'output-width:)
822 (let ((x (output-width value)))
825 (macro-psettings-output-width-set!
831 ((##eq? name 'stdin-redirection:)
832 (let ((x (stdin-redir value)))
835 (macro-psettings-stdin-redir-set!
841 ((##eq? name 'stdout-redirection:)
842 (let ((x (stdout-redir value)))
845 (macro-psettings-stdout-redir-set!
851 ((##eq? name 'stderr-redirection:)
852 (let ((x (stderr-redir value)))
855 (macro-psettings-stderr-redir-set!
861 ((##eq? name 'pseudo-terminal:)
862 (let ((x (pseudo-term value)))
865 (macro-psettings-pseudo-term-set!
871 ((##eq? name 'show-console:)
872 (let ((x (show-console value)))
875 (macro-psettings-show-console-set!
881 ((##eq? name 'server-address:)
882 (cond ((##string? value)
883 (let ((address-and-port-number
884 (##string->address-and-port-number
886 (macro-default-server-address)
888 (if address-and-port-number
891 address-and-port-number))
894 address-and-port-number)))
895 (macro-psettings-server-address-set!
899 (macro-psettings-port-number-set!
904 ((##ip-address? value)
905 (macro-psettings-server-address-set!
912 ((##eq? name 'port-number:)
913 (let ((x (port-number value)))
916 (macro-psettings-port-number-set!
922 ((##eq? name 'socket-type:)
923 (let ((x (socket-type value)))
926 (macro-psettings-socket-type-set!
932 ((##eq? name 'coalesce:)
933 (let ((x (coalesce value)))
936 (macro-psettings-coalesce-set!
942 ((##eq? name 'keep-alive:)
943 (let ((x (keep-alive value)))
946 (macro-psettings-keep-alive-set!
952 ((##eq? name 'backlog:)
953 (let ((x (backlog value)))
956 (macro-psettings-backlog-set!
962 ((##eq? name 'reuse-address:)
963 (let ((x (reuse-address value)))
966 (macro-psettings-reuse-address-set!
972 ((##eq? name 'broadcast:)
973 (let ((x (broadcast value)))
976 (macro-psettings-broadcast-set!
982 ((##eq? name 'ignore-hidden:)
983 (let ((x (ignore-hidden value)))
986 (macro-psettings-ignore-hidden-set!
1001 (error-improper-list))))))
1003 (##define-macro (macro-stream-options-output-shift) 32768)
1005 (define-prim (##psettings->roptions psettings default-options)
1006 (##psettings-options->options
1007 (macro-psettings-roptions psettings)
1008 (##fixnum.modulo default-options (macro-stream-options-output-shift))))
1010 (define-prim (##psettings->woptions psettings default-options)
1011 (##psettings-options->options
1012 (macro-psettings-woptions psettings)
1013 (##fixnum.quotient default-options (macro-stream-options-output-shift))))
1015 (define-prim (##psettings->input-readtable psettings)
1016 (or (macro-psettings-options-readtable
1017 (macro-psettings-roptions psettings))
1018 (##current-readtable)))
1020 (define-prim (##psettings->output-readtable psettings)
1021 (or (macro-psettings-options-readtable
1022 (macro-psettings-woptions psettings))
1023 (##current-readtable)))
1025 (define-prim (##psettings-options->options options default-options)
1026 (let ((permanent-close
1027 (macro-psettings-options-permanent-close options))
1029 (macro-psettings-options-buffering options))
1031 (macro-psettings-options-eol-encoding options))
1033 (macro-psettings-options-char-encoding options))
1034 (char-encoding-errors
1035 (macro-psettings-options-char-encoding-errors options)))
1038 (##fixnum.* (macro-char-encoding-shift)
1039 (if (##fixnum.= char-encoding (macro-default-char-encoding))
1041 (##fixnum.quotient default-options
1042 (macro-char-encoding-shift))
1043 (macro-char-encoding-range))
1045 (##fixnum.* (macro-char-encoding-errors-shift)
1046 (if (##fixnum.= char-encoding-errors (macro-default-char-encoding-errors))
1048 (##fixnum.quotient default-options
1049 (macro-char-encoding-errors-shift))
1050 (macro-char-encoding-errors-range))
1051 char-encoding-errors))
1054 (##fixnum.* (macro-eol-encoding-shift)
1055 (if (##fixnum.= eol-encoding (macro-default-eol-encoding))
1057 (##fixnum.quotient default-options
1058 (macro-eol-encoding-shift))
1059 (macro-eol-encoding-range))
1062 (##fixnum.* (macro-open-state-shift)
1064 (##fixnum.quotient default-options
1065 (macro-open-state-shift))
1066 (macro-open-state-range)))
1068 (##fixnum.* (macro-permanent-close-shift)
1070 (##fixnum.* (macro-buffering-shift)
1071 (if (##fixnum.= buffering (macro-default-buffering))
1073 (##fixnum.quotient default-options
1074 (macro-buffering-shift))
1075 (macro-buffering-range))
1078 (define-prim (##psettings->device-flags psettings)
1080 (macro-psettings-direction psettings))
1082 (macro-psettings-append psettings))
1084 (macro-psettings-create psettings))
1086 (macro-psettings-truncate psettings)))
1088 (##fixnum.* (macro-direction-shift)
1091 (##fixnum.* (macro-append-shift)
1092 (if (##not (##fixnum.= append (macro-default-append)))
1096 (##fixnum.* (macro-create-shift)
1097 (cond ((##not (##fixnum.= create (macro-default-create)))
1099 ((##fixnum.= direction (macro-direction-out))
1100 (macro-maybe-create))
1102 (macro-no-create))))
1103 (##fixnum.* (macro-truncate-shift)
1104 (cond ((##not (##fixnum.= truncate (macro-default-truncate)))
1106 ((##fixnum.= direction (macro-direction-out))
1107 (if (##fixnum.= append (macro-append))
1111 (macro-no-truncate)))))))))
1113 (define-prim (##psettings->permissions psettings default-permissions)
1114 (let ((permissions (macro-psettings-permissions psettings)))
1115 (if (##not (##fixnum.= permissions (macro-default-permissions)))
1117 default-permissions)))
1119 (define-prim (##psettings->output-width psettings)
1120 (let ((output-width (macro-psettings-output-width psettings)))
1121 (if (##not (##fixnum.= output-width (macro-default-output-width)))
1125 ;;;----------------------------------------------------------------------------
1127 ;;; Implementation of port type checking.
1129 (define-prim (##port? obj)
1132 (define-prim (port? obj)
1133 (macro-force-vars (obj)
1136 (define-prim (##input-port? obj)
1137 (macro-input-port? obj))
1139 (define-prim (input-port? obj)
1140 (macro-force-vars (obj)
1141 (macro-input-port? obj)))
1143 (define-prim (##output-port? obj)
1144 (macro-output-port? obj))
1146 (define-prim (output-port? obj)
1147 (macro-force-vars (obj)
1148 (macro-output-port? obj)))
1150 (implement-check-type-port)
1151 (define-fail-check-type input-port 'input-port)
1152 (define-fail-check-type output-port 'output-port)
1153 (define-fail-check-type character-input-port 'character-input-port)
1154 (define-fail-check-type character-output-port 'character-output-port)
1155 (define-fail-check-type byte-port 'byte-port)
1156 (define-fail-check-type byte-input-port 'byte-input-port)
1157 (define-fail-check-type byte-output-port 'byte-output-port)
1158 (define-fail-check-type device-input-port 'device-input-port)
1159 (define-fail-check-type device-output-port 'device-output-port)
1161 ;;;----------------------------------------------------------------------------
1163 ;;; I/O condition variables.
1165 (define-prim (##make-io-condvar name for-writing?)
1166 (let ((cv (##make-condvar name)))
1167 (macro-btq-owner-set! cv (if for-writing? 2 0))
1170 (define-prim (##io-condvar? cv)
1171 (##fixnum? (macro-btq-owner cv)))
1173 (define-prim (##io-condvar-for-writing? cv)
1174 (##not (##fixnum.= 0 (##fixnum.bitwise-and 2 (macro-btq-owner cv)))))
1176 (define-prim (##io-condvar-port cv)
1177 (macro-condvar-specific cv))
1179 (define-prim (##io-condvar-port-set! cv port)
1180 (macro-condvar-specific-set! cv port))
1182 ;;;----------------------------------------------------------------------------
1184 ;;; Implementation of dummy ports.
1186 (define-prim (##make-dummy-port)
1190 (macro-object-kind))
1192 (macro-object-kind))
1209 (define (read-datum port re)
1212 (define (write-datum port obj we)
1215 (define (newline port)
1218 (define (force-output port level prim arg1 arg2 arg3 arg4)
1221 (define (close port prim arg1)
1224 (define (set-rtimeout port timeout thunk)
1227 (define (set-wtimeout port timeout thunk)
1249 (define (open-dummy)
1250 (##make-dummy-port))
1252 ;;;----------------------------------------------------------------------------
1254 ;;; Implementation of device ports.
1256 (define-prim (##make-device-port device-name rdevice wdevice psettings)
1258 (define char-buf-len 512) ;; character buffer length
1259 (define byte-buf-len 1024) ;; byte buffer length
1262 (macro-make-port-mutex))
1265 (##os-device-kind rdevice)
1269 (##os-device-kind wdevice)
1272 (if (##fixnum.= rkind (macro-none-kind))
1274 (##psettings->roptions
1276 (##os-device-stream-default-options rdevice))))
1282 (if (##fixnum.= wkind (macro-none-kind))
1284 (##psettings->woptions
1286 (##os-device-stream-default-options wdevice))))
1292 (and (##not (##fixnum.= rkind (macro-none-kind)))
1293 (##make-string (if (macro-unbuffered? roptions)
1311 (and (##not (##fixnum.= wkind (macro-none-kind)))
1312 (##make-string (if (macro-unbuffered? woptions)
1328 (##psettings->input-readtable psettings))
1330 (##psettings->output-readtable psettings))
1332 (and (##not (##fixnum.= rkind (macro-none-kind)))
1333 (##make-u8vector byte-buf-len)))
1341 (and (##not (##fixnum.= wkind (macro-none-kind)))
1342 (##make-u8vector byte-buf-len)))
1350 (and (##not (##fixnum.= rkind (macro-none-kind)))
1351 (##make-rdevice-condvar rdevice)))
1353 (and (##not (##fixnum.= wkind (macro-none-kind)))
1354 (##make-wdevice-condvar wdevice))))
1358 ;; It is assumed that the thread **does not** have exclusive
1359 ;; access to the port.
1361 (##declare (not interrupts-enabled))
1363 (macro-device-port-name port))
1365 (define (read-datum port re)
1367 ;; It is assumed that the thread **does not** have exclusive
1368 ;; access to the port.
1370 (##declare (not interrupts-enabled))
1372 (##read-datum-or-eof re))
1374 (define (write-datum port obj we)
1376 ;; It is assumed that the thread **does not** have exclusive
1377 ;; access to the port.
1379 (##declare (not interrupts-enabled))
1383 (define (newline port)
1385 ;; It is assumed that the thread **does not** have exclusive
1386 ;; access to the port.
1388 (##declare (not interrupts-enabled))
1390 (##write-char #\newline port))
1392 (define (force-output port level prim arg1 arg2 arg3 arg4)
1394 ;; It is assumed that the thread **does not** have exclusive
1395 ;; access to the port.
1397 (##declare (not interrupts-enabled))
1399 (macro-port-mutex-lock! port) ;; get exclusive access to port
1401 (let ((code (force-output-aux port level #t)))
1402 (macro-port-mutex-unlock! port)
1403 (if (##fixnum.< code 0)
1404 (##raise-os-exception #f code prim arg1 arg2 arg3 arg4)
1407 (define (force-output-aux port level block?)
1409 ;; It is assumed that the thread has exclusive access to the port.
1411 (##declare (not interrupts-enabled))
1413 (let ((code1 (drain-output port)))
1414 (if (##fixnum? code1)
1416 (let* ((wdevice-condvar (macro-device-port-wdevice-condvar port))
1417 (wdevice (macro-condvar-name wdevice-condvar))
1418 (code2 (##os-device-force-output wdevice level)))
1419 (cond ((##fixnum.= code2 ##err-code-EINTR)
1421 ;; the force was interrupted, so try again
1423 (force-output-aux port level block?))
1426 (##fixnum.= code2 ##err-code-EAGAIN))
1428 ;; the force would block, so wait and then try again
1430 (macro-port-mutex-unlock! port)
1433 (macro-device-port-wdevice-condvar port)
1434 (macro-port-wtimeout port))
1435 ((macro-port-wtimeout-thunk port)))))
1436 (macro-port-mutex-lock! port) ;; regain access to port
1438 (force-output-aux port level block?)
1444 (define (drain-output port)
1446 ;; It is assumed that the thread has exclusive access to the port.
1448 (##declare (not interrupts-enabled))
1450 (let ((code ((macro-character-port-wbuf-drain port) port)))
1451 (if (##fixnum? code)
1453 ((macro-byte-port-wbuf-drain port) port))))
1455 (define (close port prim arg1)
1457 ;; It is assumed that the thread **does not** have exclusive
1458 ;; access to the port.
1460 (##declare (not interrupts-enabled))
1462 (macro-port-mutex-lock! port) ;; get exclusive access to port
1464 (let ((result (close-aux1 port prim)))
1465 (macro-port-mutex-unlock! port)
1466 (if (##fixnum? result)
1467 (##raise-os-exception #f result prim arg1)
1470 (define (close-aux1 port prim)
1472 ;; It is assumed that the thread has exclusive access to the port.
1474 (##declare (not interrupts-enabled))
1476 (if (or (##fixnum.= (macro-port-wkind port) (macro-none-kind))
1477 (##eq? prim close-input-port))
1478 (close-aux2 port prim)
1479 (let ((code (force-output-aux port 0 #f)))
1480 (if (and (##fixnum.< code 0)
1481 (##not (##fixnum.= code ##err-code-EAGAIN)))
1485 ;; The close operation may have failed to force the output.
1486 ;; However the close operation is not allowed to block, so
1487 ;; we just continue and close the device. The user can make
1488 ;; sure that the output is forced by calling force-output
1489 ;; (which can block) before calling close-port.
1491 (close-aux2 port prim)))))
1493 (define (close-aux2 port prim)
1495 ;; It is assumed that the thread has exclusive access to the port.
1497 (##declare (not interrupts-enabled))
1501 (macro-device-port-rdevice-condvar port)
1502 (macro-device-port-wdevice-condvar port)
1505 (define (set-rtimeout port timeout thunk)
1507 ;; It is assumed that the thread **does not** have exclusive
1508 ;; access to the port.
1510 (##declare (not interrupts-enabled))
1512 (macro-port-mutex-lock! port) ;; get exclusive access to port
1514 (macro-port-rtimeout-set! port timeout)
1515 (macro-port-rtimeout-thunk-set! port thunk)
1516 (##condvar-signal-no-reschedule!
1517 (macro-device-port-rdevice-condvar port)
1519 (macro-port-mutex-unlock! port)
1522 (define (set-wtimeout port timeout thunk)
1524 ;; It is assumed that the thread **does not** have exclusive
1525 ;; access to the port.
1527 (##declare (not interrupts-enabled))
1529 (macro-port-mutex-lock! port) ;; get exclusive access to port
1531 (macro-port-wtimeout-set! port timeout)
1532 (macro-port-wtimeout-thunk-set! port thunk)
1533 (##condvar-signal-no-reschedule!
1534 (macro-device-port-wdevice-condvar port)
1536 (macro-port-mutex-unlock! port)
1539 (define (output-width port)
1541 ;; It is assumed that the thread **does not** have exclusive
1542 ;; access to the port.
1544 (##declare (not interrupts-enabled))
1546 (macro-port-mutex-lock! port) ;; get exclusive access to port
1548 (let* ((wdevice-condvar (macro-device-port-wdevice-condvar port))
1549 (wdevice (macro-condvar-name wdevice-condvar))
1550 (result (##os-device-stream-width wdevice)))
1551 (macro-port-mutex-unlock! port)
1552 (if (##fixnum.< result 0)
1553 (##raise-os-exception #f result output-port-width port)
1557 (macro-make-device-port
1605 (##io-condvar-port-set! rdevice-condvar port))
1607 (##io-condvar-port-set! wdevice-condvar port))
1610 (define-prim (##make-rdevice-condvar rdevice)
1611 (##make-io-condvar rdevice #f))
1613 (define-prim (##make-wdevice-condvar wdevice)
1614 (##make-io-condvar wdevice #t))
1616 (define-prim (##make-device-port-from-single-device
1620 (let ((direction (macro-psettings-direction psettings)))
1621 (cond ((##fixnum.= direction (macro-direction-in))
1622 (##make-device-port device-name
1626 ((##fixnum.= direction (macro-direction-out))
1627 (##make-device-port device-name
1632 (##make-device-port device-name
1637 (define-prim (##close-device port rdevice-condvar wdevice-condvar prim)
1639 (##declare (not interrupts-enabled))
1642 (if (##fixnum.= (macro-port-rkind port) (macro-none-kind))
1644 (macro-condvar-name rdevice-condvar)))
1646 (if (##fixnum.= (macro-port-wkind port) (macro-none-kind))
1648 (macro-condvar-name wdevice-condvar))))
1649 (if (and (##eq? rdevice wdevice)
1650 (##eq? prim close-port))
1652 (##os-device-close rdevice (macro-direction-inout))))
1653 (if (##fixnum.< code1 0)
1658 (##not (##eq? prim close-output-port)))
1659 (##os-device-close rdevice (macro-direction-in))
1661 (if (##fixnum.< code2 0)
1665 (##not (##eq? prim close-input-port)))
1666 (##os-device-close wdevice (macro-direction-out))
1668 (if (##fixnum.< code3 0)
1672 (define-prim (##input-port-byte-position
1675 (position (macro-absent-obj))
1676 (whence (macro-absent-obj)))
1679 (if (##eq? position (macro-absent-obj))
1680 (##os-device-stream-seek
1681 (macro-condvar-name (macro-device-port-rdevice-condvar port))
1685 (##flush-input-buffering port)
1686 (##os-device-stream-seek
1687 (macro-condvar-name (macro-device-port-rdevice-condvar port))
1689 (if (##eq? whence (macro-absent-obj)) 0 whence))))))
1690 (if (and (##fixnum? result)
1691 (##fixnum.< result 0))
1692 (if (or (##fixnum.= result ##err-code-EINTR)
1693 (##fixnum.= result ##err-code-EAGAIN))
1695 (##raise-os-exception
1698 input-port-byte-position
1704 (define-prim (input-port-byte-position
1707 (position (macro-absent-obj))
1708 (whence (macro-absent-obj)))
1709 (macro-force-vars (port position whence)
1710 (macro-check-device-input-port
1713 (input-port-byte-position port position whence)
1714 (cond ((##eq? position (macro-absent-obj))
1715 (##input-port-byte-position port))
1716 ((##not (macro-exact-int? position))
1717 (##fail-check-exact-integer 2 input-port-byte-position port position whence))
1718 ((##eq? whence (macro-absent-obj))
1719 (##input-port-byte-position port position))
1721 (macro-check-index-range-incl
1726 (input-port-byte-position port position whence)
1727 (##input-port-byte-position port position whence)))))))
1729 (define-prim (##output-port-byte-position
1732 (position (macro-absent-obj))
1733 (whence (macro-absent-obj)))
1736 (if (##eq? position (macro-absent-obj))
1737 (##os-device-stream-seek
1738 (macro-condvar-name (macro-device-port-wdevice-condvar port))
1742 (##force-output port)
1743 (##os-device-stream-seek
1744 (macro-condvar-name (macro-device-port-wdevice-condvar port))
1746 (if (##eq? whence (macro-absent-obj)) 0 whence))))))
1747 (if (and (##fixnum? result)
1748 (##fixnum.< result 0))
1749 (if (or (##fixnum.= result ##err-code-EINTR)
1750 (##fixnum.= result ##err-code-EAGAIN))
1752 (##raise-os-exception
1755 output-port-byte-position
1761 (define-prim (output-port-byte-position
1764 (position (macro-absent-obj))
1765 (whence (macro-absent-obj)))
1766 (macro-force-vars (port position whence)
1767 (macro-check-device-output-port
1770 (output-port-byte-position port position whence)
1771 (cond ((##eq? position (macro-absent-obj))
1772 (##output-port-byte-position port))
1773 ((##not (macro-exact-int? position))
1774 (##fail-check-exact-integer 2 output-port-byte-position port position whence))
1775 ((##eq? whence (macro-absent-obj))
1776 (##output-port-byte-position port position))
1778 (macro-check-index-range-incl
1783 (output-port-byte-position port position whence)
1784 (##output-port-byte-position port position whence)))))))
1786 (define-prim (##device-port-wait-for-input! port)
1788 ;; TODO: generalize this to all other types of ports.
1790 ;; The thread will wait until there is data available to read on the
1791 ;; port's device or the port's timeout is reached. The value #f is
1792 ;; returned when the timeout is reached. The value #t is returned
1793 ;; when there is data available to read on the port's device or the
1794 ;; thread was interrupted (for example with thread-interrupt!).
1796 ;; It is assumed that the thread **does not** have exclusive
1797 ;; access to the port.
1799 (##declare (not interrupts-enabled))
1802 (macro-device-port-rdevice-condvar port)
1803 (macro-port-rtimeout port)))
1805 ;;;----------------------------------------------------------------------------
1807 (define-prim (##char-rbuf-fill port want block?)
1809 ;; port is the character input-port
1810 ;; want is the number of characters that the caller wants (#f = max)
1811 ;; block? is a boolean indicating whether it is OK for the thread to block
1813 ;; This procedure returns one of the following values:
1814 ;; - #t if characters were added to the char buffer,
1815 ;; - #f if no character could be added to the char buffer (because
1816 ;; end-of-file was reached),
1817 ;; - fixnum indicating an error code (in particular, only if block?
1818 ;; is false or there was a read timeout and the timeout thunk
1819 ;; returned #f, ##err-code-EAGAIN is returned to indicate that no
1820 ;; character was currently available).
1822 ;; It is assumed that the thread has exclusive access to the port.
1824 (##declare (not interrupts-enabled))
1828 ;; keep track of number of characters read
1830 (macro-character-port-rchars-set!
1832 (##fixnum.+ (macro-character-port-rchars port)
1833 (macro-character-port-rhi port)))
1835 (macro-character-port-rlo-set! port 0)
1836 (macro-character-port-rhi-set! port 0)
1838 ;; convert bytes from the byte buffer into characters in the char buffer
1841 (if (macro-unbuffered? (macro-port-roptions port))
1845 (##os-port-decode-chars! port want #f)))
1847 (cond ((##not (##fixnum.= code1 0))
1849 ;; an error occurred, return the error code to caller
1853 ((##fixnum.< (macro-character-port-rlo port)
1854 (macro-character-port-rhi port))
1856 ;; characters were added to char buffer
1862 ;; no characters were added to char buffer, so try to get
1865 (let ((code2 ((macro-byte-port-rbuf-fill port)
1867 want ;; assumes chars are at least 1 byte long
1870 (cond ((##fixnum? code2)
1872 ;; an error occurred, return the error code to caller
1878 ;; bytes were added to byte buffer, so try again
1879 ;; to extract characters from the byte buffer
1885 ;; no bytes were added to byte buffer
1886 ;; (end-of-file was reached)
1888 ;; The following call to ##os-port-decode-chars! will
1889 ;; check that the byte buffer is empty. If the
1890 ;; buffer is not empty an error code is returned
1891 ;; to indicate that the remaining bytes can't
1892 ;; form a character, otherwise #f is returned.
1894 (let ((code3 (##os-port-decode-chars! port want #t)))
1895 (if (##fixnum.= code3 0)
1899 (define-prim (##byte-rbuf-fill port want block?)
1901 ;; port is the byte input-port
1902 ;; want is the number of bytes that the caller wants (#f = max)
1903 ;; block? is a boolean indicating whether it is OK for the thread to block
1905 ;; This procedure returns one of the following values:
1906 ;; - #t if bytes were added to the byte buffer,
1907 ;; - #f if no byte could be added to the byte buffer (because
1908 ;; end-of-file was reached),
1909 ;; - fixnum indicating an error code (in particular, only if block?
1910 ;; is false or there was a read timeout and the timeout thunk
1911 ;; returned #f, ##err-code-EAGAIN is returned to indicate that no
1912 ;; byte was currently available).
1914 ;; It is assumed that the thread has exclusive access to the port.
1916 (##declare (not interrupts-enabled))
1920 ;; shift bytes between rlo and rhi to beginning of buffer
1922 (let ((byte-rlo (macro-byte-port-rlo port))
1923 (byte-rhi (macro-byte-port-rhi port)))
1924 (if (##fixnum.< byte-rlo byte-rhi)
1925 (let ((byte-rbuf (macro-byte-port-rbuf port)))
1926 (##subu8vector-move! byte-rbuf byte-rlo byte-rhi byte-rbuf 0)))
1927 (macro-byte-port-rlo-set! port 0)
1928 (macro-byte-port-rhi-set! port (##fixnum.- byte-rhi byte-rlo)))
1930 ;; read into byte buffer at rhi
1933 (macro-byte-port-rbuf port))
1935 (macro-byte-port-rhi port))
1937 (##os-device-stream-read
1938 (macro-condvar-name (macro-device-port-rdevice-condvar port))
1941 (let ((rbuf-len (##u8vector-length byte-rbuf)))
1942 (if (and want (macro-unbuffered? (macro-port-roptions port)))
1943 (##fixnum.min (##fixnum.+ byte-rhi want) rbuf-len)
1946 (if (##fixnum.< n 0)
1948 ;; the read caused an error
1950 (cond ((##fixnum.= n ##err-code-EINTR)
1952 ;; the read was interrupted, so try again
1957 (##fixnum.= n ##err-code-EAGAIN))
1959 ;; the read would block and it is OK to block so wait
1960 ;; and then try again
1962 (macro-port-mutex-unlock! port)
1965 (macro-device-port-rdevice-condvar port)
1966 (macro-port-rtimeout port))
1967 ((macro-port-rtimeout-thunk port)))))
1968 (macro-port-mutex-lock! port) ;; regain access to port
1975 ;; return the error code to the caller
1979 ;; the read completed successfully
1981 (if (##fixnum.= n 0) ;; was end-of-file reached?
1984 (macro-byte-port-rhi-set! port
1985 (##fixnum.+ (macro-byte-port-rhi port) n))
1988 (define-prim (##char-wbuf-drain-no-reset port)
1990 ;; This procedure returns #f when the char buffer was successfully
1991 ;; drained or it returns an error code (fixnum). In particular,
1992 ;; only if there was a write timeout and the timeout thunk returned
1993 ;; #f, ##err-code-EAGAIN is returned to indicate that some chars
1994 ;; could not be written at this time.
1996 ;; It is assumed that the thread has exclusive access to the port.
1998 (##declare (not interrupts-enabled))
2002 ;; convert characters from char buffer into bytes in the byte buffer
2004 (let ((code1 (##os-port-encode-chars! port)))
2006 (cond ((##not (##fixnum.= code1 0))
2008 ;; an error occurred, return the error code to caller
2012 ((##fixnum.< (macro-character-port-wlo port)
2013 (macro-character-port-whi port))
2015 ;; the byte buffer is full, so drain it and continue
2016 ;; draining char buffer
2018 (let ((code2 ((macro-byte-port-wbuf-drain port) port)))
2020 (if (##fixnum? code2)
2022 ;; an error occurred, return the error code to caller
2026 ;; the byte buffer was successfully drained, continue
2027 ;; draining char buffer
2033 ;; the char buffer has been emptied
2037 (define-prim (##char-wbuf-drain port)
2039 ;; It is assumed that the thread has exclusive access to the port.
2041 (##declare (not interrupts-enabled))
2043 (or (##char-wbuf-drain-no-reset port)
2045 (macro-character-port-wchars-set!
2047 (##fixnum.+ (macro-character-port-wchars port)
2048 (macro-character-port-whi port)))
2049 (macro-character-port-wlo-set! port 0)
2050 (macro-character-port-whi-set! port 0)
2053 (define-prim (##byte-wbuf-drain-no-reset port)
2055 ;; This procedure returns #f when the byte buffer was successfully
2056 ;; drained or it returns an error code (fixnum). In particular,
2057 ;; only if there was a write timeout and the timeout thunk returned
2058 ;; #f, ##err-code-EAGAIN is returned to indicate that no byte could
2059 ;; be written at this time.
2061 ;; It is assumed that the thread has exclusive access to the port.
2063 (##declare (not interrupts-enabled))
2067 (let ((byte-wlo (macro-byte-port-wlo port))
2068 (byte-whi (macro-byte-port-whi port)))
2069 (if (##fixnum.< byte-wlo byte-whi)
2071 ;; the byte buffer is not empty, write content of byte buffer
2075 (##os-device-stream-write
2076 (macro-condvar-name (macro-device-port-wdevice-condvar port))
2077 (macro-byte-port-wbuf port)
2081 (if (##fixnum.< n 0)
2083 ;; the write caused an error
2085 (cond ((##fixnum.= n ##err-code-EINTR)
2087 ;; the write was interrupted, so try again
2091 ((##fixnum.= n ##err-code-EAGAIN)
2093 ;; the write would block, so wait and then try again
2095 (macro-port-mutex-unlock! port)
2098 (macro-device-port-wdevice-condvar port)
2099 (macro-port-wtimeout port))
2100 ((macro-port-wtimeout-thunk port)))))
2101 (macro-port-mutex-lock! port) ;; regain access to port
2108 ;; return the error code to the caller
2112 ;; some bytes (possibly zero) were written, advance
2113 ;; wlo and try to write more
2116 (macro-byte-port-wlo-set! port
2117 (##fixnum.+ (macro-byte-port-wlo port) n))
2120 ;; the byte buffer is empty
2124 (define-prim (##byte-wbuf-drain port)
2126 ;; It is assumed that the thread has exclusive access to the port.
2128 (##declare (not interrupts-enabled))
2130 (or (##byte-wbuf-drain-no-reset port)
2132 ;; the byte buffer is empty, reset wlo and whi
2133 (macro-byte-port-wlo-set! port 0)
2134 (macro-byte-port-whi-set! port 0)
2137 ;;;----------------------------------------------------------------------------
2139 ;;; Implementation of vector, string and u8vector ports.
2141 (##define-macro (define-prim-vector-port-procedures
2150 (apply string-append
2151 (map (lambda (s) (if (symbol? s) (symbol->string s) s))
2154 (let ((vector/character/byte
2155 (cond ((eq? name 'u8vector) 'byte)
2156 ((eq? name 'string) 'character)
2159 (define vect-input-port
2160 (sym name '-input-port))
2162 (define vect-output-port
2163 (sym name '-output-port))
2165 (define vect-or-settings
2166 (sym name '-or-settings))
2168 (define macro-check-vect-output-port
2169 (sym 'macro-check- name '-output-port))
2171 (define ##fail-check-vect-or-settings
2172 (sym '##fail-check- name '-or-settings))
2174 (define ##fail-check-vect (sym '##fail-check- name))
2175 (define ##make-vect (sym '##make- name))
2176 (define ##vect? (sym "##" name '?))
2177 (define ##vect-ref (sym "##" name '-ref))
2178 (define ##vect-set! (sym "##" name '-set!))
2179 (define ##vect-length (sym "##" name '-length))
2180 (define ##vect-shrink! (sym "##" name '-shrink!))
2181 (define ##subvect (sym '##sub name))
2182 (define ##subvect-move! (sym '##sub name '-move!))
2183 (define ##subvect->fifo (sym '##sub name '->fifo))
2184 (define ##fifo->vect (sym '##fifo-> name))
2185 (define ##open-vect-generic (sym '##open- name '-generic))
2186 (define ##open-vect-pipe-generic (sym '##open- name '-pipe-generic))
2187 (define ##open-input-vect (sym '##open-input- name))
2188 (define ##open-output-vect (sym '##open-output- name))
2189 (define ##open-vect (sym '##open- name))
2190 (define ##open-vect-pipe (sym '##open- name '-pipe))
2191 (define ##make-vect-port (sym '##make- name '-port))
2192 (define ##make-vect-pipe-port (sym '##make- name '-pipe-port))
2193 (define ##get-output-vect (sym '##get-output- name))
2195 (define open-vect (sym 'open- name))
2196 (define open-vect-pipe (sym 'open- name '-pipe))
2197 (define open-input-vect (sym 'open-input- name))
2198 (define open-output-vect (sym 'open-output- name))
2199 (define get-output-vect (sym 'get-output- name))
2201 (define call-with-input-vect (sym 'call-with-input- name))
2202 (define call-with-output-vect (sym 'call-with-output- name))
2203 (define with-input-from-vect (sym 'with-input-from- name))
2204 (define with-output-to-vect (sym 'with-output-to- name))
2206 (define define-vect-port-methods
2207 (sym 'define- name '-port-methods))
2209 (define macro-vect-port-rbuf
2210 (sym 'macro- vector/character/byte '-port-rbuf))
2211 (define macro-vect-port-rbuf-set!
2212 (sym 'macro- vector/character/byte '-port-rbuf-set!))
2213 (define macro-vect-port-rlo
2214 (sym 'macro- vector/character/byte '-port-rlo))
2215 (define macro-vect-port-rlo-set!
2216 (sym 'macro- vector/character/byte '-port-rlo-set!))
2217 (define macro-vect-port-rhi
2218 (sym 'macro- vector/character/byte '-port-rhi))
2219 (define macro-vect-port-rhi-set!
2220 (sym 'macro- vector/character/byte '-port-rhi-set!))
2221 (define macro-vect-port-rbuf-fill
2222 (sym 'macro- vector/character/byte '-port-rbuf-fill))
2223 (define macro-vect-port-rbuf-fill-set!
2224 (sym 'macro- vector/character/byte '-port-rbuf-fill-set!))
2225 (define macro-vect-port-wbuf
2226 (sym 'macro- vector/character/byte '-port-wbuf))
2227 (define macro-vect-port-wbuf-set!
2228 (sym 'macro- vector/character/byte '-port-wbuf-set!))
2229 (define macro-vect-port-wlo
2230 (sym 'macro- vector/character/byte '-port-wlo))
2231 (define macro-vect-port-wlo-set!
2232 (sym 'macro- vector/character/byte '-port-wlo-set!))
2233 (define macro-vect-port-whi
2234 (sym 'macro- vector/character/byte '-port-whi))
2235 (define macro-vect-port-whi-set!
2236 (sym 'macro- vector/character/byte '-port-whi-set!))
2237 (define macro-vect-port-wbuf-drain
2238 (sym 'macro- vector/character/byte '-port-wbuf-drain))
2239 (define macro-vect-port-wbuf-drain-set!
2240 (sym 'macro- vector/character/byte '-port-wbuf-drain-set!))
2242 (define macro-vect-port-peer
2243 (sym 'macro- name '-port-peer))
2244 (define macro-vect-port-peer-set!
2245 (sym 'macro- name '-port-peer-set!))
2246 (define macro-vect-port-fifo
2247 (sym 'macro- name '-port-fifo))
2248 (define macro-vect-port-fifo-set!
2249 (sym 'macro- name '-port-fifo-set!))
2250 (define macro-vect-port-rcondvar
2251 (sym 'macro- name '-port-rcondvar))
2252 (define macro-vect-port-rcondvar-set!
2253 (sym 'macro- name '-port-rcondvar-set!))
2254 (define macro-vect-port-wcondvar
2255 (sym 'macro- name '-port-wcondvar))
2256 (define macro-vect-port-wcondvar-set!
2257 (sym 'macro- name '-port-wcondvar-set!))
2258 (define macro-vect-port-buffering-limit
2259 (sym 'macro- name '-port-buffering-limit))
2260 (define macro-vect-port-buffering-limit-set!
2261 (sym 'macro- name '-port-buffering-limit-set!))
2263 (define vect-rbuf-fill
2264 (sym name '-rbuf-fill))
2266 (define vect-wbuf-drain
2267 (sym name '-wbuf-drain))
2271 (define-fail-check-type ,vect-input-port ',vect-input-port)
2272 (define-fail-check-type ,vect-output-port ',vect-output-port)
2273 (define-fail-check-type ,vect-or-settings ',vect-or-settings)
2275 (##define-macro (,define-vect-port-methods)
2278 (define (,',vect-rbuf-fill port want block?)
2280 ;; port is the vector input-port
2281 ;; want is the number of elements that the caller wants (#f = max)
2282 ;; block? is a boolean indicating whether it is OK for the
2285 ;; This procedure returns one of the following values:
2286 ;; - #t if something was added to the read buffer,
2287 ;; - #f if nothing could be added to the read buffer
2288 ;; (because end-of-file was reached),
2289 ;; - fixnum indicating an error code (in particular,
2290 ;; only if block? is false or there was a read timeout
2291 ;; and the timeout thunk returned #f, ##err-code-EAGAIN
2292 ;; is returned to indicate that nothing is currently
2293 ;; available to be read).
2295 ;; It is assumed that the thread has exclusive access to the port.
2297 (##declare (not interrupts-enabled))
2302 (if (##u8vector? (,',macro-vect-port-rbuf port))
2303 (pp (##list (,',macro-vect-port-rlo port)
2304 (,',macro-vect-port-rhi port)
2305 (,',macro-vect-port-wlo port)
2306 (,',macro-vect-port-whi port)
2307 (,',macro-vect-port-rbuf port)
2308 (,',macro-vect-port-wbuf port)
2312 (let* ((peer (,',macro-vect-port-peer port))
2313 (vect-rbuf (,',macro-vect-port-rbuf port))
2314 (vect-wbuf (,',macro-vect-port-wbuf peer)))
2315 (if (##not (##eq? vect-rbuf vect-wbuf))
2316 (let ((vect-rhi (,',macro-vect-port-rhi port))
2317 (len (,',##vect-length vect-rbuf)))
2318 (cond ((##fixnum.< vect-rhi len)
2319 (,',macro-vect-port-rhi-set! port len)
2322 (let ((new-vect-rbuf
2323 (macro-fifo-advance!
2324 (,',macro-vect-port-fifo port))))
2325 (,',macro-vect-port-wlo-set!
2327 (##fixnum.- (,',macro-vect-port-wlo port) len))
2328 (,',macro-vect-port-rbuf-set!
2332 ,',(if (eq? name 'string)
2335 ;; keep track of number of characters read
2337 (macro-character-port-rchars-set!
2339 (##fixnum.+ (macro-character-port-rchars port)
2340 (macro-character-port-rhi port))))
2344 (,',macro-vect-port-rlo-set! port 0)
2345 (,',macro-vect-port-rhi-set! port 0)
2346 (##condvar-signal-no-reschedule!
2347 (,',macro-vect-port-wcondvar peer)
2350 (let* ((vect-rhi (,',macro-vect-port-rhi port))
2351 (vect-whi (,',macro-vect-port-whi peer)))
2352 (cond ((##fixnum.< vect-rhi vect-whi)
2353 (,',macro-vect-port-rhi-set! port vect-whi)
2355 ((macro-closed? (macro-port-woptions peer))
2356 (if (##not (macro-perm-close?
2357 (macro-port-woptions peer)))
2358 (macro-port-woptions-set!
2360 (macro-unclose! (macro-port-woptions peer))))
2364 (or (##mutex-signal-and-condvar-wait!
2365 (macro-port-mutex port)
2366 (,',macro-vect-port-rcondvar port)
2367 (macro-port-rtimeout port))
2368 ((macro-port-rtimeout-thunk port)))))
2369 (macro-port-mutex-lock! port)
2372 ##err-code-EAGAIN)))
2374 ##err-code-EAGAIN)))))))
2376 (define (,',vect-wbuf-drain port)
2378 ;; This procedure returns #f when the write buffer was
2379 ;; successfully drained or it returns an error code
2380 ;; (fixnum). In particular, only if there was a write
2381 ;; timeout and the timeout thunk returned #f,
2382 ;; ##err-code-EAGAIN is returned to indicate that nothing
2383 ;; could be written at this time.
2385 ;; It is assumed that the thread has exclusive access to the port.
2387 (##declare (not interrupts-enabled))
2389 ;;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2393 (,',macro-vect-port-peer port))
2395 (,',macro-vect-port-buffering-limit port)))
2396 (if (and buffering-limit
2398 (##fixnum.- (,',macro-vect-port-wlo peer)
2399 (,',macro-vect-port-rlo peer))))
2400 (##fixnum.< buffering-limit unread)))
2402 (or (##mutex-signal-and-condvar-wait!
2403 (macro-port-mutex port)
2404 (,',macro-vect-port-wcondvar port)
2405 (macro-port-wtimeout port))
2406 ((macro-port-wtimeout-thunk port)))))
2407 (macro-port-mutex-lock! port)
2411 (let* ((new-vect-wbuf
2412 (,',##make-vect chunk-size))
2414 (,',macro-vect-port-wbuf port))
2416 (,',macro-vect-port-whi port)))
2417 (,',macro-vect-port-wlo-set!
2419 (##fixnum.+ (,',macro-vect-port-wlo peer) vect-whi))
2420 ,',(if (eq? name 'vector)
2422 `(macro-character-port-wchars-set!
2425 (macro-character-port-wchars port)
2427 (,',##vect-shrink! vect-wbuf vect-whi)
2428 (,',macro-vect-port-whi-set! port 0)
2429 (,',macro-vect-port-wbuf-set! port new-vect-wbuf)
2430 (macro-fifo-insert-at-tail!
2431 (,',macro-vect-port-fifo peer)
2433 (##condvar-signal-no-reschedule!
2434 (,',macro-vect-port-rcondvar peer)
2440 ;; It is assumed that the thread **does not** have exclusive
2441 ;; access to the port.
2443 (##declare (not interrupts-enabled))
2447 (define (force-output port level prim arg1 arg2 arg3 arg4)
2449 ;; It is assumed that the thread **does not** have exclusive
2450 ;; access to the port.
2452 (##declare (not interrupts-enabled))
2454 (macro-port-mutex-lock! port) ;; get exclusive access to port
2456 (let ((peer (,',macro-vect-port-peer port)))
2458 (##condvar-signal-no-reschedule!
2459 (,',macro-vect-port-rcondvar peer)
2463 `(let ((code (,drain-output port)))
2464 (macro-port-mutex-unlock! port)
2465 (if (##fixnum? code)
2466 (if (##fixnum.= code ##err-code-EAGAIN)
2467 #f;;;;;;;;;;;this doesn't appear to be right!
2468 (##raise-os-exception #f code prim arg1 arg2 arg3 arg4))
2471 (macro-port-mutex-unlock! port)
2474 (define (close port prim arg1)
2476 ;; It is assumed that the thread **does not** have exclusive
2477 ;; access to the port.
2479 (##declare (not interrupts-enabled))
2481 ((macro-port-force-output port)
2490 (macro-port-mutex-lock! port) ;; get exclusive access to port
2492 (let ((peer (,',macro-vect-port-peer port)))
2494 (if (##not (##eq? prim close-output-port))
2496 (macro-port-roptions-set!
2498 (macro-close! (macro-port-roptions port)))
2499 (##condvar-signal-no-reschedule!
2500 (,',macro-vect-port-wcondvar peer)
2503 (if (##not (##eq? prim close-input-port))
2505 (macro-port-woptions-set!
2507 (macro-close! (macro-port-woptions port)))
2508 (##condvar-signal-no-reschedule!
2509 (,',macro-vect-port-rcondvar peer)
2512 (macro-port-mutex-unlock! port)
2516 (define (set-rtimeout port timeout thunk)
2518 ;; It is assumed that the thread **does not** have exclusive
2519 ;; access to the port.
2521 (##declare (not interrupts-enabled))
2523 (macro-port-mutex-lock! port) ;; get exclusive access to port
2525 (macro-port-rtimeout-set! port timeout)
2526 (macro-port-rtimeout-thunk-set! port thunk)
2527 (##condvar-signal-no-reschedule!
2528 (,',macro-vect-port-rcondvar port)
2530 (macro-port-mutex-unlock! port)
2533 (define (set-wtimeout port timeout thunk)
2535 ;; It is assumed that the thread **does not** have exclusive
2536 ;; access to the port.
2538 (##declare (not interrupts-enabled))
2540 (macro-port-mutex-lock! port) ;; get exclusive access to port
2542 (macro-port-wtimeout-set! port timeout)
2543 (macro-port-wtimeout-thunk-set! port thunk)
2544 (##condvar-signal-no-reschedule!
2545 (,',macro-vect-port-wcondvar port)
2547 (macro-port-mutex-unlock! port)
2550 (define-prim (,##subvect->fifo vect start end chunk-size)
2551 (let ((fifo (macro-make-fifo)))
2552 (let loop ((lo start))
2553 (let ((hi (##fixnum.+ lo chunk-size)))
2554 (if (##fixnum.< hi end)
2556 (macro-fifo-insert-at-tail! fifo (,##subvect vect lo hi))
2559 (macro-fifo-insert-at-tail! fifo (,##subvect vect lo end))
2562 (define-prim (,##fifo->vect fifo start end)
2563 (let* ((len (##fixnum.max (##fixnum.- end start) 0))
2564 (vect (,##make-vect len)))
2565 (let loop ((elems (macro-fifo-next fifo))
2569 (if (##fixnum.< lo hi)
2571 (macro-fifo-elem elems))
2573 (,##vect-length chunk))
2575 (##fixnum.min (##fixnum.- chunk-len lo)
2576 (##fixnum.- hi lo))))
2577 (,##subvect-move! chunk lo (##fixnum.+ lo n) vect i)
2578 (loop (macro-fifo-next elems)
2579 (##fixnum.- hi chunk-len)
2580 (##fixnum.- (##fixnum.+ lo n) chunk-len)
2584 (define-prim (,##open-vect-generic
2589 (init-or-settings (macro-absent-obj))
2590 (arg2 (macro-absent-obj)))
2593 (,##fail-check-vect-or-settings 1 prim init-or-settings arg2))
2598 (cond ((##eq? init-or-settings (macro-absent-obj))
2600 ((,##vect? init-or-settings)
2601 (##list 'init: init-or-settings))
2607 (or (macro-psettings-init psettings)
2609 (if (##not (,##vect? init))
2615 (,##vect-length init)
2618 (define-prim (,##open-vect
2620 (init-or-settings (macro-absent-obj)))
2621 (,##open-vect-generic
2622 (macro-direction-inout)
2623 (lambda (port) port)
2627 (define-prim (,open-vect
2629 (init-or-settings (macro-absent-obj)))
2630 (macro-force-vars (init-or-settings)
2631 (,##open-vect init-or-settings)))
2633 (define-prim (,##make-vect-pipe-port
2636 (psettings2 (macro-absent-obj)))
2638 (or (macro-psettings-init psettings1)
2644 (,##vect-length init1)
2647 (if (##eq? psettings2 (macro-absent-obj))
2652 (let ((roptions (macro-psettings-roptions psettings1))
2653 (woptions (macro-psettings-woptions psettings1)))
2654 (macro-psettings-roptions-set! psettings1 woptions)
2655 (macro-psettings-woptions-set! psettings1 roptions)
2656 (cond ((##fixnum.= (macro-psettings-direction psettings1)
2657 (macro-direction-in))
2658 (macro-psettings-direction-set!
2660 (macro-direction-out)))
2661 ((##fixnum.= (macro-psettings-direction psettings1)
2662 (macro-direction-out))
2663 (macro-psettings-direction-set!
2665 (macro-direction-in))))
2668 (or (macro-psettings-init psettings2)
2673 (,##vect-length init2)
2675 (let ((wbuf1 (,macro-vect-port-wbuf port1))
2676 (wbuf2 (,macro-vect-port-wbuf port2))
2677 (whi1 (,macro-vect-port-whi port1))
2678 (whi2 (,macro-vect-port-whi port2)))
2679 (,macro-vect-port-wbuf-set! port1 wbuf2)
2680 (,macro-vect-port-wbuf-set! port2 wbuf1)
2681 (,macro-vect-port-whi-set! port1 whi2)
2682 (,macro-vect-port-whi-set! port2 whi1)
2683 (,macro-vect-port-peer-set! port1 port2)
2684 (,macro-vect-port-peer-set! port2 port1))
2685 (##values port1 port2)))
2687 (define-prim (,##open-vect-pipe-generic
2692 (init-or-settings1 (macro-absent-obj))
2693 (init-or-settings2 (macro-absent-obj)))
2696 (,##fail-check-vect-or-settings 1 prim init-or-settings1 init-or-settings2))
2699 (,##fail-check-vect-or-settings 2 prim init-or-settings1 init-or-settings2))
2704 (cond ((##eq? init-or-settings1 (macro-absent-obj))
2706 ((,##vect? init-or-settings1)
2707 (##list 'init: init-or-settings1))
2711 (lambda (psettings1)
2713 (or (macro-psettings-init psettings1)
2715 (if (##not (,##vect? init1))
2717 (if (##eq? init-or-settings2 (macro-absent-obj))
2718 (cont (,##make-vect-pipe-port psettings1))
2722 (cond ((,##vect? init-or-settings2)
2723 (##list 'init: init-or-settings2))
2727 (lambda (psettings2)
2729 (or (macro-psettings-init psettings2)
2731 (if (##not (,##vect? init2))
2733 (cont (,##make-vect-pipe-port psettings1 psettings2))))))))))))
2735 (define-prim (,##open-vect-pipe
2737 (init-or-settings1 (macro-absent-obj))
2738 (init-or-settings2 (macro-absent-obj)))
2739 (,##open-vect-pipe-generic
2740 (macro-direction-inout)
2741 (lambda (ports) ports)
2746 (define-prim (,open-vect-pipe
2748 (init-or-settings1 (macro-absent-obj))
2749 (init-or-settings2 (macro-absent-obj)))
2750 (macro-force-vars (init-or-settings1 init-or-settings2)
2751 (,##open-vect-pipe init-or-settings1 init-or-settings2)))
2753 (define-prim (,##open-input-vect
2755 (init-or-settings (macro-absent-obj)))
2756 (,##open-vect-generic
2757 (macro-direction-in)
2758 (lambda (port) port)
2762 (define-prim (,open-input-vect
2764 (init-or-settings (macro-absent-obj)))
2765 (macro-force-vars (init-or-settings)
2766 (,##open-input-vect init-or-settings)))
2768 (define-prim (,##open-output-vect
2770 (init-or-settings (macro-absent-obj)))
2771 (,##open-vect-generic
2772 (macro-direction-out)
2773 (lambda (port) port)
2777 (define-prim (,open-output-vect
2779 (init-or-settings (macro-absent-obj)))
2780 (macro-force-vars (init-or-settings)
2781 (,##open-output-vect init-or-settings)))
2783 (define-prim (,##get-output-vect port)
2785 (##declare (not interrupts-enabled))
2788 (,macro-vect-port-peer port)))
2790 ((macro-port-force-output peer)
2799 (macro-port-mutex-lock! port) ;; get exclusive access to port
2802 (,macro-vect-port-fifo peer))
2806 (,macro-vect-port-rlo peer)
2807 (##fixnum.+ (,macro-vect-port-wlo peer)
2808 (,macro-vect-port-whi port))))
2810 (macro-fifo-advance-to-tail! vect-fifo)))
2812 ;; zap the entries of the buffer to avoid leaks
2817 (,macro-vect-port-rbuf peer)
2819 (,macro-vect-port-rlo peer)
2821 (if (##fixnum.< i (,macro-vect-port-whi port))
2823 (,vect-zap! new-vect-buf i)
2824 (loop (##fixnum.+ i 1)))))
2827 (,macro-vect-port-rbuf-set! peer new-vect-buf)
2828 (,macro-vect-port-rlo-set! peer 0)
2829 (,macro-vect-port-rhi-set! peer 0)
2831 (,macro-vect-port-wbuf-set! port new-vect-buf)
2832 (,macro-vect-port-wlo-set! peer 0) ;;;;;;;;;;;; peer or port ?
2833 (,macro-vect-port-whi-set! port 0)
2835 (macro-port-mutex-unlock! port)
2839 (define-prim (,get-output-vect port)
2840 (macro-force-vars (port)
2841 (,macro-check-vect-output-port
2844 (,get-output-vect port)
2845 (,##get-output-vect port))))
2847 (define-prim (,call-with-input-vect init-or-settings proc)
2848 (macro-force-vars (init-or-settings proc)
2849 (macro-check-procedure
2852 (,call-with-input-vect init-or-settings proc)
2853 (,##open-vect-generic
2854 (macro-direction-in)
2856 (let ((results ;; may get bound to a multiple-values object
2858 (##close-input-port port)
2860 ,call-with-input-vect
2864 (define-prim (,call-with-output-vect init-or-settings proc)
2865 (macro-force-vars (init-or-settings proc)
2866 (macro-check-procedure
2869 (,call-with-output-vect init-or-settings proc)
2870 (,##open-vect-generic
2871 (macro-direction-out)
2873 (let ((results ;; may get bound to a multiple-values object
2875 (##force-output port)
2876 (##close-output-port port)
2877 (,##get-output-vect port)))
2878 ,call-with-output-vect
2882 (define-prim (,with-input-from-vect init-or-settings thunk)
2883 (macro-force-vars (init-or-settings thunk)
2884 (macro-check-procedure
2887 (,with-input-from-vect init-or-settings thunk)
2888 (,##open-vect-generic
2889 (macro-direction-in)
2891 (let ((results ;; may get bound to a multiple-values object
2892 (macro-dynamic-bind input-port port thunk)))
2893 (##close-input-port port)
2895 ,with-input-from-vect
2899 (define-prim (,with-output-to-vect init-or-settings thunk)
2900 (macro-force-vars (init-or-settings thunk)
2901 (macro-check-procedure
2904 (,with-output-to-vect init-or-settings thunk)
2905 (,##open-vect-generic
2906 (macro-direction-out)
2908 (let ((results ;; may get bound to a multiple-values object
2909 (macro-dynamic-bind output-port port thunk)))
2910 (##force-output port)
2911 (##close-output-port port)
2912 (,##get-output-vect port)))
2913 ,with-output-to-vect
2917 (define-prim (##vect-port-options options kind buffering)
2918 (##psettings-options->options
2921 (##fixnum.* (macro-open-state-shift)
2922 (if (##fixnum.= kind (macro-none-kind))
2923 (macro-open-state-closed)
2924 (macro-open-state-open)))
2925 (##fixnum.* (macro-buffering-shift)
2928 ;;;----------------------------------------------------------------------------
2930 ;;; Implementation of vector ports.
2932 (define-prim-vector-port-procedures
2935 (lambda (vect i) (##vector-set! vect i #f))
2944 (define-prim (##make-vector-port src start end psettings)
2946 (define chunk-size 16)
2949 (macro-psettings-direction psettings))
2951 (##fixnum.max (##fixnum.- end start) 0))
2953 (##subvector->fifo src start end chunk-size))
2955 (macro-make-port-mutex))
2957 (if (##fixnum.= direction (macro-direction-out))
2959 (macro-vector-kind)))
2961 (if (##fixnum.= direction (macro-direction-in))
2963 (macro-vector-kind)))
2965 (##vect-port-options
2966 (macro-psettings-roptions psettings)
2968 (macro-full-buffering)))
2974 (##vect-port-options
2975 (macro-psettings-woptions psettings)
2977 (macro-full-buffering)))
2983 (macro-fifo-elem (macro-fifo-next vector-fifo)))
2987 (##vector-length vector-rbuf))
2989 (macro-fifo-elem (macro-fifo-tail vector-fifo)))
2991 (##vector-length vector-wbuf))
2993 (##fixnum.- len vector-whi))
2995 (##make-io-condvar #f #f))
2997 (##make-io-condvar #f #t))
2998 (vector-buffering-limit
3001 (define (read-datum port re)
3003 ;; It is assumed that the thread **does not** have exclusive
3004 ;; access to the port.
3006 (##declare (not interrupts-enabled))
3008 (macro-port-mutex-lock! port) ;; get exclusive access to port
3012 (let ((vector-rlo (macro-vector-port-rlo port))
3013 (vector-rhi (macro-vector-port-rhi port)))
3014 (if (##fixnum.< vector-rlo vector-rhi)
3016 ;; the next object is in the object read buffer
3019 (macro-vector-port-rbuf port))
3021 (##vector-ref vector-rbuf vector-rlo)))
3023 ;; frequent simple case, just advance rlo and zap vector
3024 ;; to avoid retaining objects uselessly
3026 (##vector-set! vector-rbuf vector-rlo #f)
3027 (macro-vector-port-rlo-set! port (##fixnum.+ vector-rlo 1))
3028 (macro-port-mutex-unlock! port)
3031 ;; try to get more objects into the object read
3032 ;; buffer, and try again if successful otherwise
3033 ;; signal an error or return end-of-file object
3035 (let ((code ((macro-vector-port-rbuf-fill port)
3040 (cond ((##fixnum? code)
3042 ;; the conversion or read caused an error
3044 (macro-port-mutex-unlock! port)
3045 (if (##fixnum.= code ##err-code-EAGAIN)
3046 #!eof ;; the read timeout thunk returned #f
3047 (##raise-os-exception #f code read port)))
3051 ;; some objects were added to object buffer
3057 ;; no objects were added to object buffer
3059 (macro-port-mutex-unlock! port)
3062 (define (write-datum port obj we)
3064 ;; It is assumed that the thread **does not** have exclusive
3065 ;; access to the port.
3067 (##declare (not interrupts-enabled))
3069 (macro-port-mutex-lock! port) ;; get exclusive access to port
3073 (let ((vector-wbuf (macro-vector-port-wbuf port))
3074 (vector-whi+1 (##fixnum.+ (macro-vector-port-whi port) 1)))
3075 (if (##not (##fixnum.< (##vector-length vector-wbuf) vector-whi+1))
3077 ;; there is enough space in the object write buffer, so add
3078 ;; object and increment whi
3082 (##vector-set! vector-wbuf (##fixnum.- vector-whi+1 1) obj)
3086 (macro-vector-port-whi-set! port vector-whi+1)
3088 ;; force output if port is set for unbuffered output
3090 (if (macro-unbuffered? (macro-port-woptions port))
3092 (macro-port-mutex-unlock! port)
3093 ((macro-port-force-output port)
3100 (macro-absent-obj)))
3102 (macro-port-mutex-unlock! port)
3105 ;; make some space in the object buffer and try again
3107 (let ((code ((macro-vector-port-wbuf-drain port) port)))
3108 (if (##fixnum? code)
3110 (macro-port-mutex-unlock! port)
3111 (if (##fixnum.= code ##err-code-EAGAIN)
3113 (##raise-os-exception #f code write obj port)))
3116 (define (newline port)
3118 ;; It is assumed that the thread **does not** have exclusive
3119 ;; access to the port.
3121 (##declare (not interrupts-enabled))
3125 (define-vector-port-methods)
3128 (macro-make-vector-port
3158 vector-buffering-limit)))
3159 (macro-vector-port-peer-set! port port)
3160 (##io-condvar-port-set! vector-rcondvar port)
3161 (##io-condvar-port-set! vector-wcondvar port)
3164 ;;;----------------------------------------------------------------------------
3166 ;;; Implementation of string ports.
3168 (define-prim-vector-port-procedures
3184 (define-prim (##make-string-port src start end psettings)
3186 (define chunk-size 32)
3189 (macro-psettings-direction psettings))
3191 (##fixnum.max (##fixnum.- end start) 0))
3193 (##substring->fifo src start end chunk-size))
3195 (macro-make-port-mutex))
3197 (if (##fixnum.= direction (macro-direction-out))
3199 (macro-string-kind)))
3201 (if (##fixnum.= direction (macro-direction-in))
3203 (macro-string-kind)))
3205 (##vect-port-options
3206 (macro-psettings-roptions psettings)
3208 (macro-full-buffering)))
3214 (##vect-port-options
3215 (macro-psettings-woptions psettings)
3217 (macro-full-buffering)))
3223 (macro-fifo-elem (macro-fifo-next string-fifo)))
3227 (##string-length string-rbuf))
3237 (macro-fifo-elem (macro-fifo-tail string-fifo)))
3239 (##string-length string-wbuf))
3241 (##fixnum.- len string-whi))
3249 (##psettings->input-readtable psettings))
3251 (##psettings->output-readtable psettings))
3253 (##make-io-condvar #f #f))
3255 (##make-io-condvar #f #t))
3257 (##psettings->output-width psettings))
3258 (string-buffering-limit
3261 (define (read-datum port re)
3263 ;; It is assumed that the thread **does not** have exclusive
3264 ;; access to the port.
3266 (##declare (not interrupts-enabled))
3268 (##read-datum-or-eof re))
3270 (define (write-datum port obj we)
3272 ;; It is assumed that the thread **does not** have exclusive
3273 ;; access to the port.
3275 (##declare (not interrupts-enabled))
3279 (define (newline port)
3281 ;; It is assumed that the thread **does not** have exclusive
3282 ;; access to the port.
3284 (##declare (not interrupts-enabled))
3286 (##write-char #\newline port))
3288 (define (output-width port)
3290 ;; It is assumed that the thread **does not** have exclusive
3291 ;; access to the port.
3293 (##declare (not interrupts-enabled))
3295 (macro-string-port-width port))
3297 (define-string-port-methods)
3300 (macro-make-string-port
3341 string-buffering-limit)))
3342 (macro-string-port-peer-set! port port)
3343 (##io-condvar-port-set! string-rcondvar port)
3344 (##io-condvar-port-set! string-wcondvar port)
3347 ;;;----------------------------------------------------------------------------
3349 ;;; Implementation of u8vector ports.
3351 (define-prim-vector-port-procedures
3355 (lambda (port) ((macro-character-port-wbuf-drain port) port))
3356 (input-char-encoding:
3357 output-char-encoding:
3359 input-char-encoding-errors:
3360 output-char-encoding-errors:
3361 char-encoding-errors:
3363 output-eol-encoding:
3376 (define-prim (##make-u8vector-port src start end psettings)
3378 (define char-buf-len 32) ;; character buffer length
3379 (define chunk-size 64)
3380 ;;; (define char-buf-len 3) ;; character buffer length
3381 ;;; (define chunk-size 6)
3384 (macro-psettings-direction psettings))
3386 (##fixnum.max (##fixnum.- end start) 0))
3388 (##subu8vector->fifo src start end chunk-size))
3390 (macro-make-port-mutex))
3392 (if (##fixnum.= direction (macro-direction-out))
3394 (macro-u8vector-kind)))
3396 (if (##fixnum.= direction (macro-direction-in))
3398 (macro-u8vector-kind)))
3400 (##vect-port-options
3401 (macro-psettings-roptions psettings)
3403 (macro-full-buffering)))
3409 (##vect-port-options
3410 (macro-psettings-woptions psettings)
3412 (macro-full-buffering)))
3418 (and (##not (##fixnum.= rkind (macro-none-kind)))
3419 (##make-string (if (macro-unbuffered? roptions)
3437 (and (##not (##fixnum.= wkind (macro-none-kind)))
3438 (##make-string (if (macro-unbuffered? woptions)
3454 (##psettings->input-readtable psettings))
3456 (##psettings->output-readtable psettings))
3458 ;;;;;;;;;;;;;;;;;;;;;;;;
3460 (and (##not (##fixnum.= rkind (macro-none-kind)))
3461 (##make-u8vector byte-buf-len)))
3469 (and (##not (##fixnum.= wkind (macro-none-kind)))
3470 (##make-u8vector byte-buf-len)))
3477 ;;;;;;;;;;;;;;;;;;;;;;;;
3480 (macro-fifo-elem (macro-fifo-next u8vector-fifo)))
3484 (##u8vector-length u8vector-rbuf))
3486 (macro-fifo-elem (macro-fifo-tail u8vector-fifo)))
3488 (##u8vector-length u8vector-wbuf))
3490 (##fixnum.- len u8vector-whi))
3492 (##make-io-condvar #f #f))
3494 (##make-io-condvar #f #t))
3496 (##psettings->output-width psettings))
3497 (u8vector-buffering-limit
3500 (define (read-datum port re)
3502 ;; It is assumed that the thread **does not** have exclusive
3503 ;; access to the port.
3505 (##declare (not interrupts-enabled))
3507 (##read-datum-or-eof re))
3509 (define (write-datum port obj we)
3511 ;; It is assumed that the thread **does not** have exclusive
3512 ;; access to the port.
3514 (##declare (not interrupts-enabled))
3518 (define (newline port)
3520 ;; It is assumed that the thread **does not** have exclusive
3521 ;; access to the port.
3523 (##declare (not interrupts-enabled))
3525 (##write-char #\newline port))
3527 (define (output-width port)
3529 ;; It is assumed that the thread **does not** have exclusive
3530 ;; access to the port.
3532 (##declare (not interrupts-enabled))
3534 (macro-u8vector-port-width port))
3536 (define-u8vector-port-methods)
3538 (let ((fill u8vector-rbuf-fill)
3539 (drain u8vector-wbuf-drain))
3542 (define (u8vector-rbuf-fill port want block?)
3543 (pp (list 'u8vector-rbuf-fill port want block?))
3545 (fill port want block?))
3548 (define (u8vector-wbuf-drain port)
3549 (pp (list 'u8vector-wbuf-drain port))
3554 (macro-make-u8vector-port
3603 u8vector-buffering-limit)))
3604 (macro-u8vector-port-peer-set! port port)
3605 (##io-condvar-port-set! u8vector-rcondvar port)
3606 (##io-condvar-port-set! u8vector-wcondvar port)
3610 ;;;----------------------------------------------------------------------------
3612 ;;; Implementation of generic object port procedures.
3614 (define-prim (##port-of-kind? obj kind)
3615 (##declare (not interrupts-enabled))
3616 (and (macro-port? obj)
3617 (##fixnum.= (##fixnum.bitwise-and (##port-kind obj) kind) kind)))
3619 (define-prim (##port-kind port)
3620 (##declare (not interrupts-enabled))
3621 (let ((rkind (macro-port-rkind port)))
3622 (if (##fixnum.= rkind (macro-none-kind))
3623 (macro-port-wkind port)
3626 (define-prim (##port-device port)
3627 (##declare (not interrupts-enabled))
3628 (if (##fixnum.= (macro-port-rkind port) (macro-none-kind))
3629 (let ((wdevice-condvar (macro-device-port-wdevice-condvar port)))
3630 (macro-condvar-name wdevice-condvar))
3631 (let ((rdevice-condvar (macro-device-port-rdevice-condvar port)))
3632 (macro-condvar-name rdevice-condvar))))
3634 (define-prim (##port-name port)
3635 (##declare (not interrupts-enabled))
3636 ((macro-port-name port) port))
3638 (define-prim (##read port)
3640 (##declare (not interrupts-enabled))
3642 (if (macro-character-input-port? port)
3644 (lambda (re x) x)) ;; do not wrap datum
3648 (macro-character-port-input-readtable port)
3652 ((macro-port-read-datum port) port re))
3653 ((macro-port-read-datum port) port #f)))
3657 (port (macro-absent-obj)))
3658 (macro-force-vars (port)
3660 (if (##eq? port (macro-absent-obj))
3661 (macro-current-input-port)
3663 (macro-check-input-port p 1 (read p)
3666 (define-prim (##write-generic-to-character-port style port rt force? limit obj)
3668 (##declare (not interrupts-enabled))
3671 (and (macro-readtable-sharing-allowed? rt)
3672 (##make-marktable)))
3674 (##output-port-width port)))
3677 (let ((we1 (##make-writeenv 'mark port rt mt force? width 0 0 0 limit)))
3678 ((macro-port-write-datum port) port obj we1)))
3680 (let ((we2 (##make-writeenv style port rt mt force? width 0 0 0 limit)))
3681 ((macro-port-write-datum port) port obj we2)
3682 (##fixnum.- limit (macro-writeenv-limit we2)))))
3684 (define-prim (##write obj port #!optional (max-length ##max-fixnum))
3685 (if (macro-character-output-port? port)
3687 (##write-generic-to-character-port
3690 (macro-character-port-output-readtable port)
3691 (macro-if-forces #t #f)
3695 ((macro-port-write-datum port) port obj #f)))
3700 (port (macro-absent-obj)))
3701 (macro-force-vars (obj port)
3703 (if (##eq? port (macro-absent-obj))
3704 (macro-current-output-port)
3706 (macro-check-output-port p 2 (write obj p)
3709 (define-prim (##display obj port #!optional (max-length ##max-fixnum))
3710 (if (macro-character-output-port? port)
3712 (##write-generic-to-character-port
3715 (macro-character-port-output-readtable port)
3716 (macro-if-forces #t #f)
3720 ((macro-port-write-datum port) port obj #f)))
3722 (define-prim (display
3725 (port (macro-absent-obj)))
3726 (macro-force-vars (obj port)
3728 (if (##eq? port (macro-absent-obj))
3729 (macro-current-output-port)
3731 (macro-check-output-port p 2 (display obj p)
3732 (##display obj p)))))
3734 (define-prim (##pretty-print obj port #!optional (max-length ##max-fixnum))
3735 (if (macro-character-output-port? port)
3737 (##write-generic-to-character-port
3740 (macro-character-port-output-readtable port)
3741 (macro-if-forces #t #f)
3745 ((macro-port-write-datum port) port obj #f)))
3747 (define-prim (pretty-print
3750 (port (macro-absent-obj)))
3751 (macro-force-vars (obj port)
3753 (if (##eq? port (macro-absent-obj))
3754 (macro-current-output-port)
3756 (macro-check-output-port p 2 (pretty-print obj p)
3757 (##pretty-print obj p)))))
3759 (define-prim (##print-fringe obj port #!optional (max-length ##max-fixnum))
3760 (if (macro-character-output-port? port)
3762 (##write-generic-to-character-port
3765 (macro-character-port-output-readtable port)
3766 (macro-if-forces #t #f)
3770 ((macro-port-write-datum port) port obj #f)))
3773 #!key (port (macro-absent-obj))
3775 (macro-force-vars (port)
3777 (if (##eq? port (macro-absent-obj))
3778 (macro-current-output-port)
3780 (macro-check-output-port p 2 (print port: p . body)
3781 (##print-fringe body p)))))
3783 (define-prim (println
3784 #!key (port (macro-absent-obj))
3786 (macro-force-vars (port)
3788 (if (##eq? port (macro-absent-obj))
3789 (macro-current-output-port)
3791 (macro-check-output-port p 2 (println port: p . body)
3793 (##print-fringe body p)
3796 (define-prim (##newline port)
3797 (##declare (not interrupts-enabled))
3798 ((macro-port-newline port) port))
3800 (define-prim (newline
3802 (port (macro-absent-obj)))
3803 (macro-force-vars (port)
3805 (if (##eq? port (macro-absent-obj))
3806 (macro-current-output-port)
3808 (macro-check-output-port p 1 (newline p)
3811 (define-prim (##flush-input-buffering port)
3812 (##declare (not interrupts-enabled))
3813 (macro-character-port-peek-eof?-set! port #f)
3814 (macro-character-port-rlo-set! port (macro-character-port-rhi port))
3815 (if (macro-byte-input-port? port)
3816 (macro-byte-port-rlo-set! port (macro-byte-port-rhi port)))
3819 (define-prim (##force-output
3822 (level (macro-absent-obj)))
3823 (##declare (not interrupts-enabled))
3824 ((macro-port-force-output port)
3826 (if (##eq? level (macro-absent-obj)) 0 level)
3831 (macro-absent-obj)))
3833 (define-prim (force-output
3835 (port (macro-absent-obj))
3836 (level (macro-absent-obj)))
3837 (macro-force-vars (port level)
3839 (if (##eq? port (macro-absent-obj))
3840 (macro-current-output-port)
3842 (macro-check-output-port
3845 (force-output p level)
3846 (if (##eq? level (macro-absent-obj))
3848 (macro-check-index-range-incl
3853 (force-output p level)
3854 (##force-output p level)))))))
3856 (define-prim (##close-input-port port)
3857 (##declare (not interrupts-enabled))
3858 ((macro-port-close port) port close-input-port port))
3860 (define-prim (close-input-port port)
3861 (macro-force-vars (port)
3862 (macro-check-input-port port 1 (close-input-port port)
3863 (##close-input-port port))))
3865 (define-prim (##close-output-port port)
3866 (##declare (not interrupts-enabled))
3867 ((macro-port-close port) port close-output-port port))
3869 (define-prim (close-output-port port)
3870 (macro-force-vars (port)
3871 (macro-check-output-port port 1 (close-output-port port)
3872 (##close-output-port port))))
3874 (define-prim (##close-port port)
3875 (##declare (not interrupts-enabled))
3876 ((macro-port-close port) port close-port port))
3878 (define-prim (close-port port)
3879 (macro-force-vars (port)
3880 (macro-check-port port 1 (close-port port)
3881 (##close-port port))))
3883 (define-prim (input-port-readtable port)
3884 (macro-force-vars (port)
3885 (macro-check-character-input-port port 1 (input-port-readtable port)
3886 (macro-character-port-input-readtable port))))
3888 (define-prim (input-port-readtable-set! port rt)
3889 (macro-force-vars (port rt)
3890 (macro-check-character-input-port port 1 (input-port-readtable-set! port rt)
3891 (macro-check-readtable rt 2 (input-port-readtable-set! port rt)
3893 (macro-character-port-input-readtable-set! port rt)
3896 (define-prim (output-port-readtable port)
3897 (macro-force-vars (port)
3898 (macro-check-character-output-port port 1 (output-port-readtable port)
3899 (macro-character-port-output-readtable port))))
3901 (define-prim (output-port-readtable-set! port rt)
3902 (macro-force-vars (port rt)
3903 (macro-check-character-output-port port 1 (output-port-readtable-set! port rt)
3904 (macro-check-readtable rt 2 (output-port-readtable-set! port rt)
3906 (macro-character-port-output-readtable-set! port rt)
3909 (define-prim (##input-port-timeout-set! port absrel-timeout thunk)
3910 (##declare (not interrupts-enabled))
3911 (let ((timeout (##absrel-timeout->timeout absrel-timeout)))
3912 ((macro-port-set-rtimeout port) port timeout thunk)))
3914 (define-prim (input-port-timeout-set!
3918 (t (macro-absent-obj)))
3919 (macro-force-vars (port absrel-timeout t)
3921 (if (##eq? t (macro-absent-obj))
3924 (macro-check-input-port
3927 (input-port-timeout-set! port absrel-timeout t)
3928 (macro-check-absrel-time-or-false
3931 (input-port-timeout-set! port absrel-timeout t)
3932 (macro-check-procedure
3935 (input-port-timeout-set! port absrel-timeout t)
3936 (##input-port-timeout-set! port absrel-timeout thunk)))))))
3938 (define-prim (##output-port-timeout-set! port absrel-timeout thunk)
3939 (##declare (not interrupts-enabled))
3940 (let ((timeout (##absrel-timeout->timeout absrel-timeout)))
3941 ((macro-port-set-wtimeout port) port timeout thunk)))
3943 (define-prim (output-port-timeout-set!
3947 (t (macro-absent-obj)))
3948 (macro-force-vars (port absrel-timeout t)
3950 (if (##eq? t (macro-absent-obj))
3953 (macro-check-output-port
3956 (output-port-timeout-set! port absrel-timeout t)
3957 (macro-check-absrel-time-or-false
3960 (output-port-timeout-set! port absrel-timeout t)
3961 (macro-check-procedure
3964 (output-port-timeout-set! port absrel-timeout t)
3965 (##output-port-timeout-set! port absrel-timeout thunk)))))))
3967 (define-prim (##input-port-char-position port)
3968 (##fixnum.+ (macro-character-port-rchars port)
3969 (macro-character-port-rlo port)))
3971 (define-prim (input-port-char-position port)
3972 (macro-force-vars (port)
3973 (macro-check-character-input-port
3976 (input-port-char-position port)
3977 (##input-port-char-position port))))
3979 (define-prim (##output-port-char-position port)
3980 (##fixnum.+ (macro-character-port-wchars port)
3981 (macro-character-port-whi port)))
3983 (define-prim (output-port-char-position port)
3984 (macro-force-vars (port)
3985 (macro-check-character-output-port
3988 (output-port-char-position port)
3989 (##output-port-char-position port))))
3991 (define-prim (##input-port-line-set! port line)
3992 (##declare (not interrupts-enabled))
3993 (macro-character-port-rlines-set! port (##fixnum.- line 1)))
3995 (define-prim (##input-port-line port)
3996 (##declare (not interrupts-enabled))
3997 (##fixnum.+ (macro-character-port-rlines port) 1))
3999 (define-prim (input-port-line port)
4000 (macro-force-vars (port)
4001 (macro-check-character-input-port port 1 (input-port-line port)
4002 (##input-port-line port))))
4004 (define-prim (##input-port-column-set! port col)
4005 (##declare (not interrupts-enabled))
4006 (macro-character-port-rcurline-set!
4008 (##fixnum.+ (##fixnum.- (##fixnum.+ (macro-character-port-rchars port)
4009 (macro-character-port-rlo port))
4013 (define-prim (##input-port-column port)
4014 (##declare (not interrupts-enabled))
4015 (##fixnum.+ (##fixnum.- (##fixnum.+ (macro-character-port-rchars port)
4016 (macro-character-port-rlo port))
4017 (macro-character-port-rcurline port))
4020 (define-prim (input-port-column port)
4021 (macro-force-vars (port)
4022 (macro-check-character-input-port port 1 (input-port-column port)
4023 (##input-port-column port))))
4025 (define-prim (##output-port-line-set! port line)
4026 (##declare (not interrupts-enabled))
4027 (macro-character-port-wlines-set! port (##fixnum.- line 1)))
4029 (define-prim (##output-port-line port)
4030 (##declare (not interrupts-enabled))
4031 (##fixnum.+ (macro-character-port-wlines port) 1))
4033 (define-prim (output-port-line port)
4034 (macro-force-vars (port)
4035 (macro-check-character-output-port port 1 (output-port-line port)
4036 (##output-port-line port))))
4038 (define-prim (##output-port-column-set! port col)
4039 (##declare (not interrupts-enabled))
4040 (macro-character-port-wcurline-set!
4042 (##fixnum.+ (##fixnum.- (##fixnum.+ (macro-character-port-wchars port)
4043 (macro-character-port-whi port))
4047 (define-prim (##output-port-column port)
4048 (##declare (not interrupts-enabled))
4049 (##fixnum.+ (##fixnum.- (##fixnum.+ (macro-character-port-wchars port)
4050 (macro-character-port-whi port))
4051 (macro-character-port-wcurline port))
4054 (define-prim (output-port-column port)
4055 (macro-force-vars (port)
4056 (macro-check-character-output-port port 1 (output-port-column port)
4057 (##output-port-column port))))
4059 (define-prim (##output-port-width port)
4060 (##declare (not interrupts-enabled))
4061 ((macro-character-port-output-width port) port))
4063 (define-prim (output-port-width port)
4064 (macro-force-vars (port)
4065 (macro-check-character-output-port port 1 (output-port-width port)
4066 (##output-port-width port))))
4068 (define-prim (##object->truncated-string obj max-length)
4070 (##open-output-string))
4075 (macro-character-port-output-readtable port)
4077 (macro-if-forces #t #f)
4084 (##get-output-string port)))
4086 (define-prim (##object->string obj #!optional (max-length ##max-fixnum))
4087 (if (##fixnum.< 0 max-length)
4089 (##object->truncated-string
4091 (if (##fixnum.< max-length ##max-fixnum)
4092 (##fixnum.+ max-length 1)
4094 (##string->limited-string str max-length))
4097 (define-prim (object->string obj #!optional (m (macro-absent-obj)))
4098 (macro-force-vars (obj m)
4099 (if (##eq? m (macro-absent-obj))
4100 (##object->string obj)
4103 (define (type-error)
4104 (##fail-check-exact-integer 2 object->string obj m))
4106 (define (range-error)
4107 (##raise-range-exception 2 object->string obj m))
4109 (if (macro-exact-int? m)
4110 (if (or (##not (##fixnum? m)) (##fixnum.negative? m))
4112 (##object->string obj m))
4115 (define-prim (##string->limited-string str max-length)
4116 (if (##fixnum.< max-length (##string-length str))
4117 (##force-limited-string! (##substring str 0 max-length) max-length)
4120 (define-prim (##force-limited-string! str max-length)
4121 (if (##fixnum.< 0 max-length)
4123 (##string-set! str (##fixnum.- max-length 1) #\.)
4124 (if (##fixnum.< 1 max-length)
4126 (##string-set! str (##fixnum.- max-length 2) #\.)
4127 (if (##fixnum.< 2 max-length)
4128 (##string-set! str (##fixnum.- max-length 3) #\.))))))
4129 (##string-shrink! str max-length)
4132 ;;;----------------------------------------------------------------------------
4134 ;;; Implementation of generic char port procedures.
4136 (define-prim (##input-port-characters-buffered port)
4138 (##declare (not interrupts-enabled))
4140 (macro-port-mutex-lock! port) ;; get exclusive access to port
4143 (macro-character-port-rlo port))
4145 (macro-character-port-rhi port))
4146 (characters-buffered
4147 (if (macro-character-port-peek-eof? port)
4149 (##fixnum.- char-rhi char-rlo))))
4150 (macro-port-mutex-unlock! port)
4151 characters-buffered))
4153 (define-prim (input-port-characters-buffered port)
4154 (macro-force-vars (port)
4155 (macro-check-character-input-port
4158 (input-port-characters-buffered port)
4159 (##input-port-characters-buffered port))))
4161 (define-prim (##char-ready? port)
4163 (##declare (not interrupts-enabled))
4165 (macro-port-mutex-lock! port) ;; get exclusive access to port
4167 (if (macro-character-port-peek-eof? port)
4170 (macro-port-mutex-unlock! port)
4173 (let ((char-rlo (macro-character-port-rlo port))
4174 (char-rhi (macro-character-port-rhi port)))
4175 (if (##fixnum.< char-rlo char-rhi)
4177 (macro-port-mutex-unlock! port)
4179 (let ((code ((macro-character-port-rbuf-fill port)
4183 (if (##fixnum? code)
4184 (if (##fixnum.= code ##err-code-EAGAIN)
4186 (macro-port-mutex-unlock! port)
4187 #f) ;; a call to read-char would block
4189 (macro-port-mutex-unlock! port)
4190 (##raise-os-exception #f code char-ready? port)))
4193 (macro-character-port-peek-eof?-set! port #t))
4194 (macro-port-mutex-unlock! port)
4197 (define-prim (char-ready?
4199 (port (macro-absent-obj)))
4200 (macro-force-vars (port)
4202 (if (##eq? port (macro-absent-obj))
4203 (macro-current-input-port)
4205 (macro-check-character-input-port p 1 (char-ready? p)
4206 (##char-ready? p)))))
4208 (define-prim (##peek-char port)
4210 (##declare (not interrupts-enabled))
4212 (macro-port-mutex-lock! port) ;; get exclusive access to port
4216 (let ((char-rlo (macro-character-port-rlo port))
4217 (char-rhi (macro-character-port-rhi port)))
4218 (if (##fixnum.< char-rlo char-rhi)
4220 ;; the next character is in the character read buffer
4222 (let ((c (##string-ref (macro-character-port-rbuf port) char-rlo)))
4223 (macro-port-mutex-unlock! port)
4226 (if (macro-character-port-peek-eof? port)
4229 (macro-port-mutex-unlock! port)
4232 ;; try to get more characters into the character read
4233 ;; buffer, and try again if successful otherwise
4234 ;; signal an error or return end-of-file object
4236 (let ((code ((macro-character-port-rbuf-fill port)
4241 (cond ((##fixnum? code)
4243 ;; the conversion or read caused an error
4245 (if (##fixnum.= code ##err-code-EAGAIN)
4247 (macro-character-port-peek-eof?-set! port #t)
4248 (macro-port-mutex-unlock! port)
4249 #!eof) ;; the read timeout thunk returned #f
4251 (macro-port-mutex-unlock! port)
4252 (##raise-os-exception #f code peek-char port))))
4256 ;; some characters were added to char buffer
4262 ;; no characters were added to char buffer
4264 (macro-character-port-peek-eof?-set! port #t)
4265 (macro-port-mutex-unlock! port)
4268 (define-prim (peek-char
4270 (port (macro-absent-obj)))
4271 (macro-force-vars (port)
4273 (if (##eq? port (macro-absent-obj))
4274 (macro-current-input-port)
4276 (macro-check-character-input-port p 1 (peek-char p)
4279 (define-prim (##read-char port)
4281 (##declare (not interrupts-enabled))
4283 (macro-port-mutex-lock! port) ;; get exclusive access to port
4287 (let ((char-rlo (macro-character-port-rlo port))
4288 (char-rhi (macro-character-port-rhi port)))
4289 (if (##fixnum.< char-rlo char-rhi)
4291 ;; the next character is in the character read buffer
4293 (let ((c (##string-ref (macro-character-port-rbuf port) char-rlo)))
4294 (if (##not (##char=? c #\newline))
4296 ;; frequent simple case, just advance rlo
4299 (macro-character-port-rlo-set! port (##fixnum.+ char-rlo 1))
4300 (macro-port-mutex-unlock! port)
4303 ;; end-of-line processing requires updating counters
4305 (let ((char-rlo+1 (##fixnum.+ char-rlo 1)))
4309 (macro-character-port-rlo-set! port char-rlo+1)
4311 ;; keep track of number of characters read
4313 (let ((char-rchars (macro-character-port-rchars port)))
4314 (macro-character-port-rcurline-set! port
4315 (##fixnum.+ char-rchars char-rlo+1)))
4317 ;; keep track of number of lines read
4319 (let ((char-rlines (macro-character-port-rlines port)))
4320 (macro-character-port-rlines-set! port
4321 (##fixnum.+ char-rlines 1)))
4323 (macro-port-mutex-unlock! port)
4326 (if (macro-character-port-peek-eof? port)
4329 (macro-character-port-peek-eof?-set! port #f)
4330 (macro-port-mutex-unlock! port)
4333 ;; try to get more characters into the character read
4334 ;; buffer, and try again if successful otherwise
4335 ;; signal an error or return end-of-file object
4337 (let ((code ((macro-character-port-rbuf-fill port)
4342 (cond ((##fixnum? code)
4344 ;; the conversion or read caused an error
4346 (macro-port-mutex-unlock! port)
4347 (if (##fixnum.= code ##err-code-EAGAIN)
4348 #!eof ;; the read timeout thunk returned #f
4349 (##raise-os-exception #f code read-char port)))
4353 ;; some characters were added to char buffer
4359 ;; no characters were added to char buffer
4361 (macro-port-mutex-unlock! port)
4364 (define-prim (read-char
4366 (port (macro-absent-obj)))
4367 (macro-force-vars (port)
4369 (if (##eq? port (macro-absent-obj))
4370 (macro-current-input-port)
4372 (macro-check-character-input-port p 1 (read-char p)
4375 (define-prim (##read-substring
4381 (need (macro-absent-obj)))
4383 (##declare (not interrupts-enabled))
4386 (let ((remaining (##fixnum.- end (##fixnum.+ start n))))
4387 (if (##not (##fixnum.< 0 remaining))
4389 (macro-port-mutex-unlock! port)
4392 (macro-character-port-rlo port))
4394 (macro-character-port-rhi port))
4396 (##fixnum.- char-rhi char-rlo)))
4397 (if (##fixnum.< 0 chars-buffered)
4400 (##fixnum.min remaining chars-buffered))
4402 (##fixnum.+ char-rlo to-transfer))
4404 (macro-character-port-rbuf port)))
4405 (macro-character-port-rlo-set! port limit)
4411 (##fixnum.+ start n))
4412 (let loop2 ((rlo char-rlo))
4413 (if (##fixnum.< rlo limit)
4414 (let ((c (##string-ref char-rbuf rlo))
4415 (rlo+1 (##fixnum.+ rlo 1)))
4417 (if (##char=? c #\newline)
4420 ;; keep track of number of characters read
4423 (macro-character-port-rchars port)))
4424 (macro-character-port-rcurline-set! port
4425 (##fixnum.+ char-rchars rlo+1)))
4427 ;; keep track of number of lines read
4430 (macro-character-port-rlines port)))
4431 (macro-character-port-rlines-set! port
4432 (##fixnum.+ char-rlines 1)))))
4435 (loop (##fixnum.+ n to-transfer)))
4438 ((macro-character-port-rbuf-fill port)
4441 (or (##not (##fixnum? need))
4442 (##fixnum.< n need)))))
4443 (cond ((##fixnum? code)
4445 ;; an error occurred, signal an error if no
4446 ;; chars were previously transferred from char
4447 ;; buffer and (in the case of a read timeout)
4448 ;; the timeout thunk returned #f
4450 (macro-port-mutex-unlock! port)
4452 (if (or (##fixnum.< 0 n)
4453 (##fixnum.= code ##err-code-EAGAIN))
4455 (##raise-os-exception
4467 ;; chars were added to char buffer, so try again
4468 ;; to transfer chars from the char buffer
4474 ;; no chars were added to char buffer
4475 ;; (end-of-file was reached)
4477 (macro-port-mutex-unlock! port)
4480 (define-prim (read-substring
4485 (port (macro-absent-obj))
4486 (need (macro-absent-obj)))
4487 (macro-force-vars (str start end port need)
4489 (if (##eq? port (macro-absent-obj))
4490 (macro-current-input-port)
4495 (read-substring str start end port need)
4496 (macro-check-index-range-incl
4500 (##string-length str)
4501 (read-substring str start end port need)
4502 (macro-check-index-range-incl
4506 (##string-length str)
4507 (read-substring str start end port need)
4508 (macro-check-character-input-port
4511 (read-substring str start end port need)
4512 (if (##eq? need (macro-absent-obj))
4513 (##read-substring str start end p)
4517 (read-substring str start end port need)
4518 (##read-substring str start end p need))))))))))
4520 (define-prim (##read-line port separator include-separator? max-length)
4522 (define max-chunk-length 512)
4524 (define (read-chunk i ml)
4525 (if (##char? separator)
4527 (if (##fixnum.< i ml)
4528 (let ((c (macro-read-char port)))
4530 (if (##eq? c separator)
4531 (if include-separator?
4532 (let ((s (##make-string (##fixnum.+ i 1))))
4533 (##string-set! s i c)
4536 (let ((s (loop (##fixnum.+ i 1))))
4537 (##string-set! s i c)
4541 (let ((s (##make-string ml)))
4542 (let ((n (##read-substring s i ml port #f)))
4543 (##string-shrink! s (##fixnum.+ i n))
4546 (if (##fixnum.< 0 max-length)
4547 (let ((first (macro-read-char port)))
4550 (let* ((ml max-length)
4551 (m1 (##fixnum.min ml max-chunk-length))
4552 (chunk1 (read-chunk 1 m1)))
4553 (##string-set! chunk1 0 first)
4554 (if (or (##fixnum.< (##string-length chunk1) m1)
4555 (##eq? (##string-ref chunk1 (##fixnum.- m1 1))
4559 (let loop ((ml (##fixnum.- ml m1))
4560 (chunks (##list chunk1)))
4561 (let* ((m2 (##fixnum.min ml max-chunk-length))
4562 (new-chunk (read-chunk 0 m2))
4563 (new-chunks (##cons new-chunk chunks)))
4564 (if (or (##fixnum.< (##string-length new-chunk) m2)
4565 (##eq? (##string-ref new-chunk (##fixnum.- m2 1))
4568 (##append-strings (##reverse new-chunks))
4569 (loop (##fixnum.- ml m2)
4573 (if (##eq? first separator)
4574 (if include-separator?
4581 (define-prim (read-line
4583 (port (macro-absent-obj))
4584 (separator (macro-absent-obj))
4585 (include-separator? (macro-absent-obj))
4586 (max-length (macro-absent-obj)))
4587 (macro-force-vars (port separator include-separator? max-length)
4589 (if (##eq? port (macro-absent-obj))
4590 (macro-current-input-port)
4593 (if (##eq? separator (macro-absent-obj))
4597 (if (##eq? include-separator? (macro-absent-obj))
4599 include-separator?))
4601 (if (##eq? max-length (macro-absent-obj))
4604 (macro-check-character-input-port
4607 (read-line port separator include-separator? max-length)
4611 (read-line port separator include-separator? max-length)
4612 (##read-line p sep inc-sep? ml))))))
4614 (define-prim (##read-all port-or-readenv reader)
4615 (let ((fifo (macro-make-fifo)))
4617 (let ((obj (reader port-or-readenv)))
4618 (if (##eof-object? obj)
4619 (macro-fifo->list fifo)
4621 (macro-fifo-insert-at-tail! fifo obj)
4624 (define-prim (read-all
4626 (port (macro-absent-obj))
4627 (reader (macro-absent-obj)))
4628 (macro-force-vars (port reader)
4630 (if (##eq? port (macro-absent-obj))
4631 (macro-current-input-port)
4634 (if (##eq? reader (macro-absent-obj))
4637 (macro-check-input-port p 1 (read-all port reader)
4638 (macro-check-procedure r 2 (read-all port r)
4639 (##read-all p r))))))
4641 (define-prim (##read-all-as-a-begin-expr-from-path
4648 (##fail-check-string 1 open-input-file path))
4650 (##make-input-path-psettings
4651 (##list 'path: path)
4654 (let ((path (macro-psettings-path psettings)))
4657 (##read-all-as-a-begin-expr-from-psettings
4664 (define-prim (##read-all-as-a-begin-expr-from-psettings
4672 (##fail-check-string-or-settings 1 open-input-file path-or-settings))
4674 (let ((path (macro-psettings-path psettings)))
4677 (##open-file-generic-from-psettings
4681 (if (##fixnum? port)
4684 (##path-extension path))
4686 (let ((x (##assoc extension ##scheme-file-extensions)))
4689 (macro-readtable-start-syntax readtable)))))
4690 (##read-all-as-a-begin-expr-from-port
4698 path-or-settings))))
4700 (define-prim (##read-all-as-a-begin-expr-from-port
4707 (##with-exception-catcher
4710 (##close-input-port port))
4714 (##readtable-copy-shallow readtable)))
4715 (macro-readtable-start-syntax-set! rt start-syntax)
4717 (##make-readenv port rt wrap unwrap 'script))
4719 (##cons (wrap re '##begin)
4720 '())) ;; tail will be replaced with expressions read
4724 (##read-datum-or-eof re))
4726 (and (##eq? first (##script-marker))
4727 (##read-line port #\newline #f ##max-fixnum)))
4729 (##extract-language-and-tail script-line)))
4730 (if language-and-tail
4731 (let ((language (##car language-and-tail)))
4732 (##readtable-setup-for-language! rt language)))
4734 (if (##eof-object? first)
4736 (##read-all re ##read-datum-or-eof)))
4738 (##port-name port)))
4740 (##close-input-port port))
4741 (cond ((##eof-object? first)
4742 (##vector #f expr port-name))
4743 ((##eq? first (##script-marker))
4744 (##set-cdr! head rest)
4745 (##vector script-line expr port-name))
4747 (##set-cdr! head (##cons first rest))
4748 (##vector #f expr port-name)))))))))
4750 (define-prim (##write-char c port)
4752 (##declare (not interrupts-enabled))
4754 (macro-port-mutex-lock! port) ;; get exclusive access to port
4758 (let ((char-wbuf (macro-character-port-wbuf port))
4759 (char-whi+1 (##fixnum.+ (macro-character-port-whi port) 1)))
4760 (if (##not (##fixnum.< (##string-length char-wbuf) char-whi+1))
4762 ;; there is enough space in the character write buffer, so add
4763 ;; character and increment whi
4767 (##string-set! char-wbuf (##fixnum.- char-whi+1 1) c)
4771 (macro-character-port-whi-set! port char-whi+1)
4773 (if (##not (##char=? c #\newline))
4775 ;; force output if port is set for unbuffered output
4777 (if (macro-unbuffered? (macro-port-woptions port))
4779 (macro-port-mutex-unlock! port)
4780 ((macro-port-force-output port)
4787 (macro-absent-obj)))
4789 (macro-port-mutex-unlock! port)
4792 ;; end-of-line processing requires updating counters
4796 ;; keep track of number of characters written
4798 (let ((char-wchars (macro-character-port-wchars port)))
4799 (macro-character-port-wcurline-set! port
4800 (##fixnum.+ char-wchars char-whi+1)))
4802 ;; keep track of number of lines written
4804 (let ((char-wlines (macro-character-port-wlines port)))
4805 (macro-character-port-wlines-set! port
4806 (##fixnum.+ char-wlines 1)))
4808 ;; force output if port is not fully buffered
4810 (if (##not (macro-fully-buffered?
4811 (macro-port-woptions port)))
4813 (macro-port-mutex-unlock! port)
4814 ((macro-port-force-output port)
4821 (macro-absent-obj)))
4823 (macro-port-mutex-unlock! port)
4826 ;; make some space in the character buffer and try again
4828 (let ((code3 ((macro-character-port-wbuf-drain port) port)))
4829 (if (##fixnum? code3)
4831 (macro-port-mutex-unlock! port)
4832 (if (##fixnum.= code3 ##err-code-EAGAIN)
4834 (##raise-os-exception #f code3 write-char c port)))
4837 (define-prim (write-char
4840 (port (macro-absent-obj)))
4841 (macro-force-vars (c port)
4843 (if (##eq? port (macro-absent-obj))
4844 (macro-current-output-port)
4846 (macro-check-char c 1 (write-char c port)
4847 (macro-check-character-output-port p 2 (write-char c p)
4848 (##write-char c p))))))
4850 (define-prim (##write-substring str start end port)
4851 (##declare (not interrupts-enabled))
4852 (let loop ((i start))
4853 (if (##fixnum.< i end)
4855 (macro-write-char (##string-ref str i) port)
4857 (##declare (interrupts-enabled))
4858 (loop (##fixnum.+ i 1)))))))
4860 (define-prim (write-substring
4865 (port (macro-absent-obj)))
4866 (macro-force-vars (str start end port)
4868 (if (##eq? port (macro-absent-obj))
4869 (macro-current-output-port)
4871 (macro-check-string str 1 (write-substring str start end port)
4872 (macro-check-index-range-incl
4876 (##string-length str)
4877 (write-substring str start end port)
4878 (macro-check-index-range-incl
4882 (##string-length str)
4883 (write-substring str start end port)
4884 (macro-check-character-output-port
4887 (write-substring str start end p)
4888 (##write-substring str start end p))))))))
4890 (define-prim (##write-string str port)
4891 (##declare (not interrupts-enabled))
4892 (##write-substring str 0 (##string-length str) port))
4894 ;;;----------------------------------------------------------------------------
4896 ;;; Implementation of generic byte port procedures.
4898 (##define-macro (macro-lock-and-check-input-port-character-buffer-empty
4904 (macro-port-mutex-lock! ,port) ;; get exclusive access to port
4906 (if (or (##fixnum.< (macro-character-port-rlo ,port)
4907 (macro-character-port-rhi ,port))
4908 (macro-character-port-peek-eof? ,port))
4911 (macro-port-mutex-unlock! ,port)
4912 (##raise-nonempty-input-port-character-buffer-exception ,@form))
4916 (define-prim (##input-port-bytes-buffered port)
4918 (##declare (not interrupts-enabled))
4920 (macro-port-mutex-lock! port) ;; get exclusive access to port
4923 (macro-byte-port-rlo port))
4925 (macro-byte-port-rhi port))
4927 (##fixnum.- byte-rhi byte-rlo)))
4928 (macro-port-mutex-unlock! port)
4931 (define-prim (input-port-bytes-buffered port)
4932 (macro-force-vars (port)
4933 (macro-check-byte-input-port
4936 (input-port-bytes-buffered port)
4937 (##input-port-bytes-buffered port))))
4939 (define-prim (##read-u8 port)
4941 (##declare (not interrupts-enabled))
4943 (macro-lock-and-check-input-port-character-buffer-empty
4948 (macro-byte-port-rlo port))
4950 (macro-byte-port-rhi port)))
4951 (if (##fixnum.< byte-rlo byte-rhi)
4953 (macro-byte-port-rbuf port))
4955 (##u8vector-ref byte-rbuf byte-rlo)))
4956 (macro-byte-port-rlo-set! port (##fixnum.+ byte-rlo 1))
4957 (macro-port-mutex-unlock! port)
4960 ((macro-byte-port-rbuf-fill port)
4964 (cond ((##fixnum? code)
4966 ;; an error occurred
4968 (macro-port-mutex-unlock! port)
4970 (if (##fixnum.= code ##err-code-EAGAIN)
4971 #!eof ;; the read timeout thunk returned #f
4972 (##raise-os-exception
4980 ;; bytes were added to byte buffer, so try again
4981 ;; to transfer bytes from the byte buffer
4987 ;; no bytes were added to byte buffer
4988 ;; (end-of-file was reached)
4990 (macro-port-mutex-unlock! port)
4993 (define-prim (read-u8
4995 (port (macro-absent-obj)))
4996 (macro-force-vars (port)
4998 (if (##eq? port (macro-absent-obj))
4999 (macro-current-input-port)
5001 (macro-check-byte-input-port
5007 (define-prim (##read-subu8vector
5013 (need (macro-absent-obj)))
5015 (##declare (not interrupts-enabled))
5017 (macro-lock-and-check-input-port-character-buffer-empty
5019 (read-subu8vector u8vect start end port need)
5021 (let ((remaining (##fixnum.- end (##fixnum.+ start n))))
5022 (if (##not (##fixnum.< 0 remaining))
5024 (macro-port-mutex-unlock! port)
5027 (macro-byte-port-rlo port))
5029 (macro-byte-port-rhi port))
5031 (##fixnum.- byte-rhi byte-rlo)))
5032 (if (##fixnum.< 0 bytes-buffered)
5035 (##fixnum.min remaining bytes-buffered))
5037 (##fixnum.+ byte-rlo to-transfer))
5039 (macro-byte-port-rbuf port)))
5040 (macro-byte-port-rlo-set! port limit)
5041 (##subu8vector-move!
5046 (##fixnum.+ start n))
5047 (loop (##fixnum.+ n to-transfer)))
5050 ((macro-byte-port-rbuf-fill port)
5053 (or (##not (##fixnum? need))
5054 (##fixnum.< n need)))))
5055 (cond ((##fixnum? code)
5057 ;; an error occurred, signal an error if no
5058 ;; bytes were previously transferred from byte
5059 ;; buffer and (in the case of a read timeout)
5060 ;; the timeout thunk returned #f
5062 (macro-port-mutex-unlock! port)
5064 (if (or (##fixnum.< 0 n)
5065 (##fixnum.= code ##err-code-EAGAIN))
5067 (##raise-os-exception
5079 ;; bytes were added to byte buffer, so try again
5080 ;; to transfer bytes from the byte buffer
5086 ;; no bytes were added to byte buffer
5087 ;; (end-of-file was reached)
5089 (macro-port-mutex-unlock! port)
5092 (define-prim (read-subu8vector
5097 (port (macro-absent-obj))
5098 (need (macro-absent-obj)))
5099 (macro-force-vars (u8vect start end port need)
5101 (if (##eq? port (macro-absent-obj))
5102 (macro-current-input-port)
5104 (macro-check-u8vector
5107 (read-subu8vector u8vect start end port need)
5108 (macro-check-index-range-incl
5112 (##u8vector-length u8vect)
5113 (read-subu8vector u8vect start end port need)
5114 (macro-check-index-range-incl
5118 (##u8vector-length u8vect)
5119 (read-subu8vector u8vect start end port need)
5120 (macro-check-byte-input-port
5123 (read-subu8vector u8vect start end port need)
5124 (if (##eq? need (macro-absent-obj))
5125 (##read-subu8vector u8vect start end p)
5129 (read-subu8vector u8vect start end port need)
5130 (##read-subu8vector u8vect start end p need))))))))))
5132 (define-prim (##write-u8 b port)
5134 (##declare (not interrupts-enabled))
5136 (macro-port-mutex-lock! port) ;; get exclusive access to port
5139 (and (##fixnum.< (macro-character-port-wlo port)
5140 (macro-character-port-whi port))
5141 ((macro-character-port-wbuf-drain port) port))))
5142 (if (##fixnum? code)
5145 (macro-port-mutex-unlock! port)
5146 (##raise-os-exception
5155 (macro-byte-port-whi port))
5157 (macro-byte-port-wbuf port))
5159 (##fixnum.- (##u8vector-length byte-wbuf) byte-whi)))
5160 (if (##fixnum.< 0 bytes-free)
5162 (macro-byte-port-whi-set! port (##fixnum.+ byte-whi 1))
5163 (##u8vector-set! byte-wbuf byte-whi b)
5165 ;; force output if port is set for unbuffered output
5167 (if (macro-unbuffered? (macro-port-woptions port))
5169 (macro-port-mutex-unlock! port)
5170 ((macro-port-force-output port)
5177 (macro-absent-obj)))
5179 (macro-port-mutex-unlock! port)
5181 (let ((code ((macro-byte-port-wbuf-drain port) port)))
5182 (if (##fixnum? code)
5185 ;; an error occurred
5187 (macro-port-mutex-unlock! port)
5189 (##raise-os-exception
5196 ;; the byte buffer was successfully drained, so try
5197 ;; again to transfer bytes to the byte buffer
5201 (define-prim (write-u8
5204 (port (macro-absent-obj)))
5205 (macro-force-vars (b port)
5207 (if (##eq? port (macro-absent-obj))
5208 (macro-current-output-port)
5210 (macro-check-exact-unsigned-int8 b 1 (write-u8 b port)
5211 (macro-check-byte-output-port p 2 (write-u8 b p)
5212 (##write-u8 b p))))))
5214 (define-prim (##write-subu8vector u8vect start end port)
5216 (##declare (not interrupts-enabled))
5218 (macro-port-mutex-lock! port) ;; get exclusive access to port
5221 (and (##fixnum.< (macro-character-port-wlo port)
5222 (macro-character-port-whi port))
5223 ((macro-character-port-wbuf-drain port) port))))
5224 (if (##fixnum? code)
5227 (macro-port-mutex-unlock! port)
5228 (if (##fixnum.= code ##err-code-EAGAIN)
5230 (##raise-os-exception
5240 (let ((remaining (##fixnum.- end (##fixnum.+ start n))))
5241 (if (##not (##fixnum.< 0 remaining))
5244 ;; force output if port is set for unbuffered output
5246 (if (and (##fixnum.< start end)
5247 (macro-unbuffered? (macro-port-woptions port)))
5249 (macro-port-mutex-unlock! port)
5250 ((macro-port-force-output port)
5258 (macro-port-mutex-unlock! port))
5262 (macro-byte-port-whi port))
5264 (macro-byte-port-wbuf port))
5266 (##fixnum.- (##u8vector-length byte-wbuf) byte-whi)))
5267 (if (##fixnum.< 0 bytes-free)
5269 (##fixnum.min remaining bytes-free))
5271 (##fixnum.+ byte-whi to-transfer)))
5272 (macro-byte-port-whi-set! port limit)
5273 (let loop2 ((i (##fixnum.+ start n))
5275 (if (##fixnum.< j limit)
5277 (##u8vector-set! byte-wbuf j (##u8vector-ref u8vect i))
5278 (loop2 (##fixnum.+ i 1)
5279 (##fixnum.+ j 1)))))
5280 (loop1 (##fixnum.+ n to-transfer)))
5281 (let ((code ((macro-byte-port-wbuf-drain port) port)))
5282 (if (##fixnum? code)
5285 ;; an error occurred, signal an error if no bytes
5286 ;; were previously transferred from byte buffer
5287 ;; and (in the case of a write timeout) the
5288 ;; timeout thunk returned #f
5290 (macro-port-mutex-unlock! port)
5292 (if (or (##fixnum.< 0 n)
5293 (##fixnum.= code ##err-code-EAGAIN))
5295 (##raise-os-exception
5304 ;; the byte buffer was successfully drained, so try
5305 ;; again to transfer bytes to the byte buffer
5309 (define-prim (write-subu8vector
5314 (port (macro-absent-obj)))
5315 (macro-force-vars (u8vect start end port)
5317 (if (##eq? port (macro-absent-obj))
5318 (macro-current-output-port)
5320 (macro-check-u8vector u8vect 1 (write-subu8vector u8vect start end port)
5321 (macro-check-index-range-incl
5325 (##u8vector-length u8vect)
5326 (write-subu8vector u8vect start end port)
5327 (macro-check-index-range-incl
5331 (##u8vector-length u8vect)
5332 (write-subu8vector u8vect start end port)
5333 (macro-check-byte-output-port
5336 (write-subu8vector u8vect start end p)
5337 (##write-subu8vector u8vect start end p))))))))
5339 (define-prim (##options-set! port options)
5341 (##declare (not interrupts-enabled))
5344 (if (##fixnum.= (macro-port-rkind port) (macro-none-kind))
5346 (macro-condvar-name (macro-device-port-rdevice-condvar port))))
5348 (if (##fixnum.= (macro-port-wkind port) (macro-none-kind))
5350 (macro-condvar-name (macro-device-port-wdevice-condvar port)))))
5351 (if (##eq? rdevice wdevice)
5353 (##os-device-stream-options-set! rdevice options)))
5354 (if (##fixnum.< code1 0)
5359 (##os-device-stream-options-set! rdevice options)
5361 (if (##fixnum.< code2 0)
5365 (##os-device-stream-options-set! wdevice options)
5367 (if (##fixnum.< code3 0)
5371 (define-prim (##port-settings-set! port settings)
5373 (##declare (not interrupts-enabled))
5376 (##fail-check-settings 2 port-settings-set! port settings))
5378 (macro-lock-and-check-input-port-character-buffer-empty
5380 (port-settings-set! port settings)
5382 (macro-direction-inout)
5383 '(input-char-encoding:
5384 output-char-encoding:
5386 input-char-encoding-errors:
5387 output-char-encoding-errors:
5388 char-encoding-errors:
5390 output-eol-encoding:
5398 (let* ((old-roptions
5399 (macro-port-roptions port))
5401 (##psettings->roptions psettings
5404 (macro-port-woptions port))
5406 (##psettings->woptions psettings
5407 (##fixnum.* old-woptions
5408 (macro-stream-options-output-shift)))))
5410 (and (macro-output-port? port)
5411 (##not (##fixnum.= woptions old-woptions))
5412 (##fixnum.< (macro-character-port-wlo port)
5413 (macro-character-port-whi port))
5414 ((macro-character-port-wbuf-drain port) port))))
5415 (if (##fixnum? code)
5418 (macro-port-mutex-unlock! port)
5419 (##raise-os-exception
5429 (##fixnum.+ roptions
5430 (##fixnum.* woptions
5431 (macro-stream-options-output-shift))))))
5432 (if (##fixnum? result)
5434 (macro-port-mutex-unlock! port)
5435 (##raise-os-exception #f result port-settings-set! port settings))
5437 (macro-port-roptions-set! port roptions)
5438 (macro-port-woptions-set! port woptions)
5440 ;; change character buffers if needed
5442 (let ((rbuf (macro-character-port-rbuf port)))
5444 (let ((new-char-buf-len
5445 (if (macro-unbuffered? roptions)
5448 (if (##not (##fixnum.= (##string-length rbuf)
5450 (let ((new-rbuf (##make-string new-char-buf-len)))
5451 (macro-character-port-rchars-set!
5453 (##fixnum.+ (macro-character-port-rchars port)
5454 (macro-character-port-rlo port)))
5455 (macro-character-port-rlo-set! port 0)
5456 (macro-character-port-rhi-set! port 0)
5457 (macro-character-port-rbuf-set! port new-rbuf))))))
5459 (let ((wbuf (macro-character-port-wbuf port)))
5461 (let ((new-char-buf-len
5462 (if (macro-unbuffered? woptions)
5465 (if (##not (##fixnum.= (##string-length wbuf)
5467 (let ((new-wbuf (##make-string new-char-buf-len)))
5468 (macro-character-port-rchars-set!
5470 (##fixnum.+ (macro-character-port-wchars port)
5471 (macro-character-port-whi port)))
5472 (macro-character-port-wlo-set! port 0)
5473 (macro-character-port-whi-set! port 0)
5474 (macro-character-port-wbuf-set! port new-wbuf))))))
5476 (macro-port-mutex-unlock! port)
5479 (define-prim (port-settings-set! port settings)
5480 (macro-force-vars (port settings)
5481 (macro-check-byte-port
5484 (port-settings-set! port settings)
5485 (##port-settings-set! port settings))))
5487 ;;;----------------------------------------------------------------------------
5489 ;;; Implementation of tty device ports.
5491 (implement-check-type-tty-port)
5493 (define-prim (##tty? port)
5494 (##declare (not interrupts-enabled))
5495 (macro-tty-port? port))
5497 (define-prim (tty? port)
5498 (macro-force-vars (port)
5501 (define-prim (##tty-type-set! port term-type emacs-bindings)
5503 (##os-device-tty-type-set!
5504 (##port-device port)
5507 (if (##fixnum.< code 0)
5508 (##raise-os-exception #f code tty-type-set! port term-type emacs-bindings)
5511 (define-prim (tty-type-set! port term-type emacs-bindings)
5512 (macro-force-vars (port term-type emacs-bindings)
5513 (macro-check-tty-port
5516 (tty-type-set! port term-type emacs-bindings)
5520 (tty-type-set! port term-type emacs-bindings)
5521 (##tty-type-set! port term-type emacs-bindings)))))
5523 (define-prim (##tty-text-attributes-set! port input output)
5524 (##os-device-tty-text-attributes-set! (##port-device port) input output))
5526 (define-prim (tty-text-attributes-set! port input output)
5527 (macro-force-vars (port input output)
5528 (macro-check-tty-port
5531 (tty-text-attributes-set! port input output)
5532 (macro-check-fixnum-range
5537 (tty-text-attributes-set! port input output)
5538 (macro-check-fixnum-range
5543 (tty-text-attributes-set! port input output)
5544 (##tty-text-attributes-set! port input output))))))
5546 (define-prim (##tty-history port)
5547 (let ((result (##os-device-tty-history (##port-device port))))
5548 (if (##fixnum? result)
5549 (##raise-os-exception #f result tty-history port)
5552 (define-prim (tty-history port)
5553 (macro-force-vars (port)
5554 (macro-check-tty-port
5558 (##tty-history port))))
5560 (define-prim (##tty-history-set! port history)
5561 (let ((code (##os-device-tty-history-set! (##port-device port) history)))
5562 (if (##fixnum.< code 0)
5563 (##raise-os-exception #f code tty-history-set! port history)
5566 (define-prim (tty-history-set! port history)
5567 (macro-force-vars (port history)
5568 (macro-check-tty-port
5571 (tty-history-set! port history)
5575 (tty-history-set! port history)
5576 (##tty-history-set! port history)))))
5578 (define-prim (##tty-history-max-length-set! port max-length)
5579 (##os-device-tty-history-max-length-set! (##port-device port) max-length))
5581 (define-prim (tty-history-max-length-set! port max-length)
5582 (macro-force-vars (port max-length)
5583 (macro-check-tty-port
5586 (tty-history-max-length-set! port max-length)
5590 (tty-history-max-length-set! port max-length)
5591 (##tty-history-max-length-set! port max-length)))))
5593 (define-prim (##tty-paren-balance-duration-set! port duration)
5594 (##os-device-tty-paren-balance-duration-set! (##port-device port) duration))
5596 (define-prim (tty-paren-balance-duration-set! port duration)
5597 (macro-force-vars (port duration)
5598 (macro-check-tty-port
5601 (tty-paren-balance-duration-set! port duration)
5605 (tty-paren-balance-duration-set! port duration)
5606 (##tty-paren-balance-duration-set!
5608 (macro-real->inexact duration))))))
5610 (define-prim (##tty-mode-set!
5618 (##os-device-tty-mode-set!
5619 (##port-device port)
5625 (if (##fixnum.< code 0)
5626 (##raise-os-exception
5638 (define-prim (tty-mode-set!
5645 (s (macro-absent-obj)))
5646 (macro-force-vars (port
5653 (if (##eq? s (macro-absent-obj))
5656 (macro-check-tty-port
5665 (##tty-mode-set! port
5672 ;;;----------------------------------------------------------------------------
5674 ;;; Implementation of process device ports.
5676 (implement-check-type-process-port)
5678 (define-prim (##make-process-psettings
5695 input-char-encoding:
5696 output-char-encoding:
5698 input-char-encoding-errors:
5699 output-char-encoding-errors:
5700 char-encoding-errors:
5702 output-eol-encoding:
5715 (define-prim (##open-process-generic
5722 (arg2 (macro-absent-obj)))
5724 (define (psettings->options psettings)
5726 (macro-psettings-stdin-redir psettings))
5728 (macro-psettings-stdout-redir psettings))
5730 (macro-psettings-stderr-redir psettings))
5732 (macro-psettings-pseudo-term psettings))
5734 (macro-psettings-show-console psettings)))
5738 (##fixnum.* 2 stdout-redir)
5740 (##fixnum.* 4 stderr-redir)
5742 (##fixnum.* 8 pseudo-term)
5743 (##fixnum.* 16 show-console)))))))
5746 (##fail-check-string-or-settings 1 prim path-or-settings arg2))
5748 (##make-process-psettings
5750 (if (##string? path-or-settings)
5751 (##list 'path: path-or-settings)
5755 (let ((path (macro-psettings-path psettings))
5756 (directory (macro-psettings-directory psettings)))
5757 (if (or (##not (##string? path))
5758 (##not (or (##not directory)
5759 (##string? directory))))
5761 (let* ((path-and-arguments
5763 (macro-psettings-arguments psettings)))
5765 (macro-psettings-environment psettings))
5768 (##path-resolve directory)
5769 (##current-directory)))
5771 (macro-psettings-direction psettings)))
5773 ;; force creation of a bidirectional port
5774 (macro-psettings-direction-set!
5776 (macro-direction-inout))
5779 (##os-device-stream-open-process
5783 (psettings->options psettings))))
5784 (cond ((##fixnum? device)
5785 (if raise-os-exception?
5786 (##raise-os-exception
5795 (##make-device-port-from-single-device
5796 (##cons 'process path-and-arguments)
5800 ;; close unused direction
5801 (cond ((##fixnum.= direction (macro-direction-in))
5802 (##close-output-port port))
5803 ((##fixnum.= direction (macro-direction-out))
5804 (##close-input-port port)))
5806 (cont port)))))))))))
5808 (define-prim (##open-process path-or-settings)
5809 (##open-process-generic
5810 (macro-direction-inout)
5812 (lambda (port) port)
5816 (define-prim (open-process path-or-settings)
5817 (macro-force-vars (path-or-settings)
5818 (##open-process path-or-settings)))
5820 (define-prim (##open-input-process path-or-settings)
5821 (##open-process-generic
5822 (macro-direction-in)
5824 (lambda (port) port)
5828 (define-prim (open-input-process path-or-settings)
5829 (macro-force-vars (path-or-settings)
5830 (##open-input-process path-or-settings)))
5832 (define-prim (##open-output-process path-or-settings)
5833 (##open-process-generic
5834 (macro-direction-out)
5836 (lambda (port) port)
5840 (define-prim (open-output-process path-or-settings)
5841 (macro-force-vars (path-or-settings)
5842 (##open-output-process path-or-settings)))
5844 (define-prim (call-with-input-process path-or-settings proc)
5845 (macro-force-vars (path-or-settings proc)
5846 (macro-check-procedure
5849 (call-with-input-process path-or-settings proc)
5850 (##open-process-generic
5851 (macro-direction-in)
5854 (let ((results ;; may get bound to a multiple-values object
5857 (##process-status port) ;; wait for process to terminate
5859 call-with-input-process
5863 (define-prim (call-with-output-process path-or-settings proc)
5864 (macro-force-vars (path-or-settings proc)
5865 (macro-check-procedure
5868 (call-with-output-process path-or-settings proc)
5869 (##open-process-generic
5870 (macro-direction-out)
5873 (let ((results ;; may get bound to a multiple-values object
5875 (##force-output port)
5877 (##process-status port) ;; wait for process to terminate
5879 call-with-output-process
5883 (define-prim (with-input-from-process path-or-settings thunk)
5884 (macro-force-vars (path-or-settings thunk)
5885 (macro-check-procedure
5888 (with-input-from-process path-or-settings thunk)
5889 (##open-process-generic
5890 (macro-direction-in)
5893 (let ((results ;; may get bound to a multiple-values object
5894 (macro-dynamic-bind input-port port thunk)))
5896 (##process-status port) ;; wait for process to terminate
5898 with-input-from-process
5902 (define-prim (with-output-to-process path-or-settings thunk)
5903 (macro-force-vars (path-or-settings thunk)
5904 (macro-check-procedure
5907 (with-output-to-process path-or-settings thunk)
5908 (##open-process-generic
5909 (macro-direction-out)
5912 (let ((results ;; may get bound to a multiple-values object
5913 (macro-dynamic-bind output-port port thunk)))
5914 (##force-output port)
5916 (##process-status port) ;; wait for process to terminate
5918 with-output-to-process
5922 (define-prim (##process-pid port)
5923 (##os-device-process-pid (##port-device port)))
5925 (define-prim (process-pid port)
5926 (macro-force-vars (port)
5927 (macro-check-process-port
5931 (##process-pid port))))
5933 (define-prim (##process-status
5936 (absrel-timeout (macro-absent-obj))
5937 (timeout-val (macro-absent-obj)))
5941 (if (##eq? absrel-timeout (macro-absent-obj))
5944 (let loop ((poll-interval 0.001))
5945 (let ((result (##os-device-process-status (##port-device port))))
5946 (cond ((##not result)
5947 (let ((now (##current-time-point)))
5948 (if (##flonum.< now timeout)
5950 ;; Polling is evil but fixing this would require
5951 ;; substantial changes to the I/O subsystem. We'll
5952 ;; tackle that in a future release.
5953 (##thread-sleep! poll-interval)
5954 (loop (##flonum.min 0.2 (##flonum.* 1.2 poll-interval))))
5955 (if (##eq? timeout-val (macro-absent-obj))
5956 (##raise-unterminated-process-exception
5961 ((##fixnum.< result 0)
5962 (##raise-os-exception #f result process-status port))
5966 (define-prim (process-status
5969 (absrel-timeout (macro-absent-obj))
5970 (timeout-val (macro-absent-obj)))
5971 (macro-force-vars (port absrel-timeout)
5972 (macro-check-process-port
5975 (process-status port absrel-timeout timeout-val)
5976 (if (or (##eq? absrel-timeout (macro-absent-obj))
5977 (macro-absrel-time-or-false? absrel-timeout))
5978 (##process-status port absrel-timeout timeout-val)
5979 (##fail-check-absrel-time-or-false
5986 ;;;----------------------------------------------------------------------------
5988 ;;; Implementation of host-info objects.
5990 (implement-library-type-host-info)
5992 (define-prim (##host-info host)
5993 (let ((result (##os-host-info host)))
5994 (if (##fixnum? result)
5995 (##raise-os-exception #f result host-info host)
5997 (##structure-type-set! result (macro-type-host-info))
5998 (##subtype-set! result (macro-subtype-structure))
6001 (define-prim (host-info host)
6002 (macro-force-vars (host)
6003 (macro-check-string-or-ip-address host 1 (host-info host)
6004 (##host-info host))))
6006 (define-prim (##host-name)
6007 (let ((result (##os-host-name)))
6008 (if (##fixnum? result)
6009 (##raise-os-exception #f result host-name)
6012 (define-prim (host-name)
6015 (define-prim (##string-or-ip-address? obj)
6017 (##ip-address? obj)))
6019 (define-prim (##ip-address? obj)
6020 (cond ((##u8vector? obj)
6021 (##fixnum.= (##u8vector-length obj) 4))
6023 (##fixnum.= (##u16vector-length obj) 8))
6027 ;;;----------------------------------------------------------------------------
6029 ;;; Implementation of service-info objects.
6031 (implement-library-type-service-info)
6033 (define-prim (##service-info
6036 (protocol (macro-absent-obj)))
6040 (cond ((##string? protocol)
6042 ((##fixnum? protocol)
6043 (let ((p (##protocol-info protocol)))
6044 (macro-protocol-info-name p)))
6045 ((macro-protocol-info? protocol)
6046 (macro-protocol-info-name protocol))
6049 (if (##fixnum? result)
6050 (##raise-os-exception #f result service-info service protocol)
6052 (##structure-type-set! result (macro-type-service-info))
6053 (##subtype-set! result (macro-subtype-structure))
6056 (define-prim (service-info
6059 (protocol (macro-absent-obj)))
6060 (macro-force-vars (service protocol)
6061 (macro-check-string-or-nonnegative-fixnum
6064 (service-info service protocol)
6065 (if (##eq? protocol (macro-absent-obj))
6066 (##service-info service)
6067 (macro-check-string-or-nonnegative-fixnum
6070 (service-info service protocol)
6071 (##service-info service protocol))))))
6073 ;;;----------------------------------------------------------------------------
6075 ;;; Implementation of protocol-info objects.
6077 (implement-library-type-protocol-info)
6079 (define-prim (##protocol-info protocol)
6081 (##os-protocol-info protocol)))
6082 (if (##fixnum? result)
6083 (##raise-os-exception #f result protocol-info protocol)
6085 (##structure-type-set! result (macro-type-protocol-info))
6086 (##subtype-set! result (macro-subtype-structure))
6089 (define-prim (protocol-info protocol)
6090 (macro-force-vars (protocol)
6091 (macro-check-string-or-nonnegative-fixnum
6094 (protocol-info protocol)
6095 (##protocol-info protocol))))
6097 ;;;----------------------------------------------------------------------------
6099 ;;; Implementation of network-info objects.
6101 (implement-library-type-network-info)
6103 (define-prim (##network-info network)
6105 (##os-network-info network)))
6106 (if (##fixnum? result)
6107 (##raise-os-exception #f result network-info network)
6109 (##structure-type-set! result (macro-type-network-info))
6110 (##subtype-set! result (macro-subtype-structure))
6113 (define-prim (network-info network)
6114 (macro-force-vars (network)
6115 (macro-check-string-or-nonnegative-fixnum
6118 (network-info network)
6119 (##network-info network))))
6121 ;;;----------------------------------------------------------------------------
6123 ;;; Implementation of TCP client device ports.
6125 (implement-check-type-tcp-client-port)
6127 (define-prim (##make-tcp-psettings
6133 (define allowed-client-settings
6141 input-char-encoding:
6142 output-char-encoding:
6144 input-char-encoding-errors:
6145 output-char-encoding-errors:
6146 char-encoding-errors:
6148 output-eol-encoding:
6157 (define allowed-server-settings
6166 input-char-encoding:
6167 output-char-encoding:
6169 input-char-encoding-errors:
6170 output-char-encoding-errors:
6171 char-encoding-errors:
6173 output-eol-encoding:
6183 (macro-direction-inout)
6185 allowed-client-settings
6186 allowed-server-settings)
6191 (define-prim (##make-tcp-client-port name device psettings)
6192 (##make-device-port-from-single-device
6197 (define-prim (##open-tcp-client
6201 port-number-or-address-or-settings)
6203 (define (psettings->options psettings)
6205 (macro-psettings-coalesce psettings))
6207 (macro-psettings-keep-alive psettings)))
6209 (##fixnum.* 2 coalesce)
6213 (##fail-check-exact-integer-or-string-or-settings 1 prim port-number-or-address-or-settings))
6215 (##make-tcp-psettings
6217 (cond ((##fixnum? port-number-or-address-or-settings)
6218 (##list 'port-number: port-number-or-address-or-settings))
6219 ((##string? port-number-or-address-or-settings)
6220 (##list 'server-address: port-number-or-address-or-settings))
6222 port-number-or-address-or-settings))
6225 (let ((server-address-or-host
6226 (macro-psettings-server-address psettings)))
6228 (define (open server-address)
6230 (macro-psettings-port-number psettings)))
6231 (if (or (##eq? server-address #f)
6232 (##not port-number))
6235 (##os-device-tcp-client-open
6238 (psettings->options psettings))))
6239 (if (##fixnum? device)
6240 (if raise-os-exception?
6241 (##raise-os-exception #f device prim port-number-or-address-or-settings)
6244 (##make-tcp-client-port
6246 server-address-or-host
6250 ;; wait for connection to be established
6252 ;; (macro-device-port-wdevice-condvar port)
6253 ;; (macro-port-wtimeout port))
6256 (if (##string? server-address-or-host)
6257 (let ((info (##os-host-info server-address-or-host)))
6258 (if (##fixnum? info)
6259 (if raise-os-exception?
6260 (##raise-os-exception #f info prim port-number-or-address-or-settings)
6262 (open (##car (macro-host-info-addresses info)))))
6263 (open server-address-or-host))))))
6265 (define-prim (open-tcp-client port-number-or-address-or-settings)
6266 (macro-force-vars (port-number-or-address-or-settings)
6269 (lambda (port) port)
6271 port-number-or-address-or-settings)))
6273 (implement-library-type-socket-info)
6275 (define-prim (##socket-info-setup! si)
6276 (##vector-set! si 1 (##net-family-decode (##vector-ref si 1)))
6277 (##structure-type-set! si (macro-type-socket-info))
6278 (##subtype-set! si (macro-subtype-structure))
6281 (define-prim (##tcp-client-socket-info port prim)
6284 (##os-device-tcp-client-socket-info
6285 (macro-condvar-name (macro-device-port-rdevice-condvar port))
6286 (##eq? prim tcp-client-peer-socket-info))))
6287 (if (##fixnum? result)
6289 (if (and (##fixnum.= result ##err-code-EAGAIN)
6291 (macro-device-port-wdevice-condvar port)
6292 (macro-port-wtimeout port))
6293 ((macro-port-wtimeout-thunk port))))
6295 (##raise-os-exception #f result prim port))
6297 (##socket-info-setup! result)))))
6299 (define-prim (##tcp-client-self-socket-info port)
6300 (##tcp-client-socket-info port tcp-client-self-socket-info))
6302 (define-prim (tcp-client-self-socket-info port)
6303 (macro-force-vars (port)
6304 (macro-check-tcp-client-port port 1 (tcp-client-self-socket-info port)
6305 (##tcp-client-self-socket-info port))))
6307 (define-prim (##tcp-client-peer-socket-info port)
6308 (##tcp-client-socket-info port tcp-client-peer-socket-info))
6310 (define-prim (tcp-client-peer-socket-info port)
6311 (macro-force-vars (port)
6312 (macro-check-tcp-client-port port 1 (tcp-client-peer-socket-info port)
6313 (##tcp-client-peer-socket-info port))))
6315 (implement-library-type-address-info)
6317 (define-prim (##net-family-encode x)
6323 (define-prim (##net-family-decode x)
6329 (define-prim (##net-socket-type-encode x)
6336 (define-prim (##net-socket-type-decode x)
6343 (define-prim (##net-protocol-encode x)
6349 (define-prim (##net-protocol-decode x)
6355 (define-prim (##address-info-setup! ai)
6356 (##vector-set! ai 1 (##net-family-decode (##vector-ref ai 1)))
6357 (##vector-set! ai 2 (##net-socket-type-decode (##vector-ref ai 2)))
6358 (##vector-set! ai 3 (##net-protocol-decode (##vector-ref ai 3)))
6359 (let ((si (##vector-ref ai 4)))
6360 (##socket-info-setup! si))
6361 (##structure-type-set! ai (macro-type-address-info))
6362 (##subtype-set! ai (macro-subtype-structure))
6365 (define-prim (##address-infos
6367 (host (macro-absent-obj))
6368 (service (macro-absent-obj))
6369 ;;(flags (macro-absent-obj))
6370 (family (macro-absent-obj))
6371 (socket-type (macro-absent-obj))
6372 (protocol (macro-absent-obj)))
6373 (macro-force-vars (host service flags family socket-type protocol)
6374 (let ((flags (macro-absent-obj)))
6376 (define (check-host arg-num)
6377 (if (##eq? host (macro-absent-obj))
6378 (check-service arg-num "")
6379 (let ((arg-num (##fixnum.+ arg-num 2)))
6383 (address-infos host: host
6387 socket-type: socket-type
6389 (check-service arg-num host)))))
6391 (define (check-service arg-num h)
6392 (if (##eq? service (macro-absent-obj))
6393 (check-flags arg-num h "")
6394 (let ((arg-num (##fixnum.+ arg-num 2)))
6398 (address-infos host: host
6402 socket-type: socket-type
6404 (check-flags arg-num h service)))))
6406 (define (check-flags arg-num h s)
6407 (if (##eq? flags (macro-absent-obj))
6408 (check-family arg-num h s 0)
6409 (let ((arg-num (##fixnum.+ arg-num 2)))
6410 (macro-check-fixnum-range-incl
6415 (address-infos host: host
6419 socket-type: socket-type
6421 (check-family arg-num h s flags)))))
6423 (define (check-family arg-num h s f)
6424 (if (##eq? family (macro-absent-obj))
6425 (check-socket-type arg-num h s f 0)
6426 (let ((arg-num (##fixnum.+ arg-num 2)))
6427 (let ((x (##net-family-encode family)))
6428 (if (##eq? x family)
6429 (##raise-type-exception
6432 (##list address-infos
6437 socket-type: socket-type
6440 (check-socket-type arg-num h s f x))))))
6442 (define (check-socket-type arg-num h s f fam)
6443 (if (##eq? socket-type (macro-absent-obj))
6444 (check-protocol arg-num h s f fam 0)
6445 (let ((arg-num (##fixnum.+ arg-num 2)))
6446 (let ((x (##net-socket-type-encode socket-type)))
6447 (if (##eq? x socket-type)
6448 (##raise-type-exception
6450 'network-socket-type
6451 (##list address-infos
6456 socket-type: socket-type
6459 (check-protocol arg-num h s f fam x))))))
6461 (define (check-protocol arg-num h s f fam st)
6462 (if (##eq? protocol (macro-absent-obj))
6463 (checks-done h s f fam st 0)
6464 (let ((arg-num (##fixnum.+ arg-num 2)))
6465 (let ((x (##net-protocol-encode protocol)))
6466 (if (##eq? x protocol)
6467 (##raise-type-exception
6470 (##list address-infos
6475 socket-type: socket-type
6478 (checks-done h s f fam st x))))))
6480 (define (checks-done h s f fam st p)
6481 (let ((result (##os-address-infos h s f fam st p)))
6482 (if (##fixnum? result)
6483 (##raise-os-exception
6486 (##list address-infos
6491 socket-type: socket-type
6492 protocol: protocol))
6494 (##for-each ##address-info-setup! result)
6499 (define-prim (address-infos
6501 (host (macro-absent-obj))
6502 (service (macro-absent-obj))
6503 ;;(flags (macro-absent-obj))
6504 (family (macro-absent-obj))
6505 (socket-type (macro-absent-obj))
6506 (protocol (macro-absent-obj)))
6507 (##address-infos host: host
6511 socket-type: socket-type
6512 protocol: protocol))
6514 ;;;----------------------------------------------------------------------------
6516 ;; Implementation of TCP server ports.
6518 (implement-check-type-tcp-server-port)
6520 (define-prim (##make-tcp-server-port rdevice client-psettings)
6522 (macro-make-port-mutex))
6524 (macro-tcp-server-kind))
6540 (##make-rdevice-condvar rdevice)))
6542 (define (server-name port)
6544 ;; It is assumed that the thread **does not** have exclusive
6545 ;; access to the port.
6547 (##declare (not interrupts-enabled))
6550 (macro-psettings-port-number
6551 (macro-tcp-server-port-client-psettings port))))
6553 ;; This code gives a more informative name to the tcp-client port but
6554 ;; if ##os-device-tcp-client-socket-info raises an exception it leads
6555 ;; to an infinite loop.
6557 ;; (define (client-name port)
6559 ;; ;; It is assumed that the thread **does not** have exclusive
6560 ;; ;; access to the port.
6562 ;; (##declare (not interrupts-enabled))
6565 ;; (##os-device-tcp-client-socket-info
6566 ;; (macro-condvar-name
6567 ;; (macro-device-port-wdevice-condvar port))
6569 ;; (if (##fixnum? info)
6570 ;; (##list 'tcp-client
6571 ;; (macro-psettings-port-number
6572 ;; (macro-tcp-server-port-client-psettings port)))
6574 ;; (macro-socket-info-address info))
6576 ;; (macro-socket-info-port-number info)))
6577 ;; (##list 'tcp-client
6581 (define (read-datum port re)
6583 ;; It is assumed that the thread **does not** have exclusive
6584 ;; access to the port.
6586 (##declare (not interrupts-enabled))
6588 (macro-port-mutex-lock! port) ;; get exclusive access to port
6591 (let ((client-device
6592 (##os-device-tcp-server-read
6594 (macro-tcp-server-port-rdevice-condvar port)))))
6595 (if (##fixnum? client-device)
6597 (cond ((##fixnum.= client-device ##err-code-EINTR)
6599 ;; the read was interrupted, so try again
6603 ((##fixnum.= client-device ##err-code-EAGAIN)
6605 ;; the read would block, so wait and then try again
6607 (macro-port-mutex-unlock! port)
6610 (macro-tcp-server-port-rdevice-condvar port)
6611 (macro-port-rtimeout port))
6612 ((macro-port-rtimeout-thunk port)))))
6615 (macro-port-mutex-lock! port) ;; regain access to port
6623 (macro-port-mutex-unlock! port)
6624 (##raise-os-exception #f client-device read port)))
6627 (macro-port-mutex-unlock! port)
6629 (##make-tcp-client-port
6632 (macro-tcp-server-port-client-psettings port))))
6633 ;; (macro-port-name-set! port client-name)
6636 (define write-datum #f)
6640 (define force-output #f)
6642 (define (set-rtimeout port timeout thunk)
6644 ;; It is assumed that the thread **does not** have exclusive
6645 ;; access to the port.
6647 (##declare (not interrupts-enabled))
6649 (macro-port-mutex-lock! port) ;; get exclusive access to port
6651 (macro-port-rtimeout-set! port timeout)
6652 (macro-port-rtimeout-thunk-set! port thunk)
6653 (##condvar-signal-no-reschedule!
6654 (macro-tcp-server-port-rdevice-condvar port)
6656 (macro-port-mutex-unlock! port)
6659 (define set-wtimeout #f)
6661 (define (close port prim arg1)
6663 ;; It is assumed that the thread **does not** have exclusive
6664 ;; access to the port.
6666 (##declare (not interrupts-enabled))
6668 (macro-port-mutex-lock! port) ;; get exclusive access to port
6673 (macro-tcp-server-port-rdevice-condvar port)
6676 (macro-port-mutex-unlock! port)
6677 (if (##fixnum? result)
6678 (##raise-os-exception #f result prim arg1)
6682 (macro-make-tcp-server-port
6702 (##io-condvar-port-set! rdevice-condvar port)
6705 (define-prim (##process-tcp-server-psettings
6709 port-number-or-address-or-settings
6715 (##fail-check-exact-integer-or-string-or-settings 1 prim port-number-or-address-or-settings arg2 arg3 arg4))
6717 (##make-tcp-psettings
6719 (cond ((##fixnum? port-number-or-address-or-settings)
6720 (##list 'port-number: port-number-or-address-or-settings))
6721 ((##string? port-number-or-address-or-settings)
6722 (##list 'server-address: port-number-or-address-or-settings))
6724 port-number-or-address-or-settings))
6728 (define (continue-with-address server-address)
6729 (if (##eq? server-address #t)
6731 (cont (##cons psettings server-address))))
6733 (if (##not (macro-psettings-port-number psettings))
6735 (let ((server-address-or-host
6736 (macro-psettings-server-address psettings)))
6737 (if (##string? server-address-or-host)
6738 (let ((info (##os-host-info server-address-or-host)))
6739 (if (##fixnum? info)
6740 (if raise-os-exception?
6741 (##raise-os-exception #f info prim port-number-or-address-or-settings arg2 arg3 arg4)
6743 (continue-with-address
6744 (##car (macro-host-info-addresses info)))))
6745 (continue-with-address
6746 server-address-or-host)))))))
6748 (define-prim (##open-tcp-server-aux
6750 psettings-and-server-address
6753 port-number-or-address-or-settings
6758 (define (psettings->options psettings)
6759 (let ((reuse-address
6760 (macro-psettings-reuse-address psettings))
6762 (macro-psettings-coalesce psettings))
6764 (macro-psettings-keep-alive psettings)))
6766 (##fixnum.* 2048 reuse-address)
6768 (##fixnum.* 2 coalesce)
6772 (##car psettings-and-server-address))
6774 (##cdr psettings-and-server-address))
6776 (macro-psettings-port-number psettings))
6778 (##os-device-tcp-server-open
6781 (macro-psettings-backlog psettings)
6782 (psettings->options psettings))))
6783 (if (##fixnum? rdevice)
6784 (if raise-os-exception?
6785 (##raise-os-exception #f rdevice prim port-number-or-address-or-settings arg2 arg3 arg4)
6787 (cont (##make-tcp-server-port rdevice psettings)))))
6789 (define-prim (##open-tcp-server
6793 port-number-or-address-or-settings
6797 (##process-tcp-server-psettings
6799 (lambda (psettings-and-server-address)
6800 (##open-tcp-server-aux
6802 psettings-and-server-address
6805 port-number-or-address-or-settings
6810 port-number-or-address-or-settings
6815 (define-prim (open-tcp-server port-number-or-address-or-settings)
6816 (macro-force-vars (port-number-or-address-or-settings)
6819 (lambda (port) port)
6821 port-number-or-address-or-settings
6824 (macro-absent-obj))))
6826 (define-prim (##tcp-server-socket-info port)
6828 (##os-device-tcp-server-socket-info
6829 (macro-condvar-name (macro-tcp-server-port-rdevice-condvar port)))))
6830 (if (##fixnum? result)
6832 (##raise-os-exception #f result tcp-server-socket-info port))
6834 (##socket-info-setup! result)))
6836 (define-prim (tcp-server-socket-info port)
6837 (macro-force-vars (port)
6838 (macro-check-tcp-server-port port 1 (tcp-server-socket-info port)
6839 (##tcp-server-socket-info port))))
6841 (define-prim (##string->address-and-port-number
6850 (if (##string=? str "*")
6854 (let ((len (if str (##string-length str) 0)))
6855 (let loop ((i 0) (colon #f))
6857 (let ((c (##string-ref str i)))
6858 (cond ((##not colon)
6860 (if (##char=? c #\:) i colon)))
6861 ((and (##char<=? #\0 c) (##char<=? c #\9))
6867 (##cons (if (##fx= len 0)
6873 (##substring str (##fx+ colon 1) len)
6876 (##fixnum? port-num)
6878 (##fx<= port-num 65535))
6879 (##cons (if (##fx= colon 0)
6881 (addr (##substring str 0 colon)))
6885 ;;;----------------------------------------------------------------------------
6887 ;;; Implementation of directory ports.
6889 (implement-check-type-directory-port)
6891 (define-prim (##make-directory-psettings
6905 (define-prim (##make-directory-port rdevice path)
6907 (macro-make-port-mutex))
6909 (macro-directory-kind))
6925 (##make-rdevice-condvar rdevice)))
6929 ;; It is assumed that the thread **does not** have exclusive
6930 ;; access to the port.
6932 (##declare (not interrupts-enabled))
6934 (macro-directory-port-path port))
6936 (define (read-datum port re)
6938 ;; It is assumed that the thread **does not** have exclusive
6939 ;; access to the port.
6941 (##declare (not interrupts-enabled))
6943 (macro-port-mutex-lock! port) ;; get exclusive access to port
6947 (##os-device-directory-read
6949 (macro-directory-port-rdevice-condvar port)))))
6950 (if (##fixnum? datum)
6952 (cond ((##fixnum.= datum ##err-code-EINTR)
6954 ;; the read was interrupted, so try again
6958 ((##fixnum.= datum ##err-code-EAGAIN)
6960 ;; the read would block, so wait and then try again
6962 (macro-port-mutex-unlock! port)
6965 (macro-directory-port-rdevice-condvar port)
6966 (macro-port-rtimeout port))
6967 ((macro-port-rtimeout-thunk port)))))
6970 (macro-port-mutex-lock! port) ;; regain access to port
6978 (macro-port-mutex-unlock! port)
6979 (##raise-os-exception #f datum read port)))
6982 (macro-port-mutex-unlock! port)
6985 (define write-datum #f)
6989 (define force-output #f)
6991 (define (set-rtimeout port timeout thunk)
6993 ;; It is assumed that the thread **does not** have exclusive
6994 ;; access to the port.
6996 (##declare (not interrupts-enabled))
6998 (macro-port-mutex-lock! port) ;; get exclusive access to port
7000 (macro-port-rtimeout-set! port timeout)
7001 (macro-port-rtimeout-thunk-set! port thunk)
7002 (##condvar-signal-no-reschedule!
7003 (macro-directory-port-rdevice-condvar port)
7005 (macro-port-mutex-unlock! port)
7008 (define set-wtimeout #f)
7010 (define (close port prim arg1)
7012 ;; It is assumed that the thread **does not** have exclusive
7013 ;; access to the port.
7015 (##declare (not interrupts-enabled))
7017 (macro-port-mutex-lock! port) ;; get exclusive access to port
7022 (macro-directory-port-rdevice-condvar port)
7025 (macro-port-mutex-unlock! port)
7026 (if (##fixnum? result)
7027 (##raise-os-exception #f result prim arg1)
7031 (macro-make-directory-port
7051 (##io-condvar-port-set! rdevice-condvar port)
7054 (define-prim (##open-directory
7059 (path-or-settings (macro-absent-obj)))
7062 (##fail-check-string-or-settings 1 prim path-or-settings))
7064 (##make-directory-psettings
7065 (macro-direction-in)
7066 (cond ((##eq? path-or-settings (macro-absent-obj))
7068 ((##string? path-or-settings)
7069 (##list 'path: path-or-settings))
7075 (or (macro-psettings-path psettings)
7076 (##current-directory))))
7077 (if (##not (##string? path))
7079 (let* ((resolved-path
7080 (##path-resolve path))
7082 (##os-device-directory-open-path
7084 (macro-psettings-ignore-hidden psettings))))
7085 (if (##fixnum? rdevice)
7086 (if raise-os-exception?
7087 (##raise-os-exception #f rdevice open-directory path)
7089 (cont (##make-directory-port rdevice path)))))))))
7091 (define-prim (open-directory
7093 (path-or-settings (macro-absent-obj)))
7094 (macro-force-vars (path-or-settings)
7097 (lambda (port) port)
7101 ;;;----------------------------------------------------------------------------
7103 ;;; Implementation of event-queue ports.
7105 (implement-check-type-event-queue-port)
7107 (define-prim (##make-event-queue-port rdevice index)
7109 (macro-make-port-mutex))
7111 (macro-event-queue-kind))
7127 (##make-rdevice-condvar rdevice)))
7131 ;; It is assumed that the thread **does not** have exclusive
7132 ;; access to the port.
7134 (##declare (not interrupts-enabled))
7136 (##list 'event-queue (macro-event-queue-port-index port)))
7138 (define (read-datum port re)
7140 ;; It is assumed that the thread **does not** have exclusive
7141 ;; access to the port.
7143 (##declare (not interrupts-enabled))
7145 (macro-port-mutex-lock! port) ;; get exclusive access to port
7149 (##os-device-event-queue-read
7151 (macro-event-queue-port-rdevice-condvar port)))))
7152 (if (##fixnum? datum)
7154 (cond ((##fixnum.= datum ##err-code-EINTR)
7156 ;; the read was interrupted, so try again
7160 ((##fixnum.= datum ##err-code-EAGAIN)
7162 ;; the read would block, so wait and then try again
7164 (macro-port-mutex-unlock! port)
7167 (macro-event-queue-port-rdevice-condvar port)
7168 (macro-port-rtimeout port))
7169 ((macro-port-rtimeout-thunk port)))))
7172 (macro-port-mutex-lock! port) ;; regain access to port
7180 (macro-port-mutex-unlock! port)
7181 (##raise-os-exception #f datum read port)))
7184 (macro-port-mutex-unlock! port)
7187 (define write-datum #f)
7191 (define force-output #f)
7193 (define (set-rtimeout port timeout thunk)
7195 ;; It is assumed that the thread **does not** have exclusive
7196 ;; access to the port.
7198 (##declare (not interrupts-enabled))
7200 (macro-port-mutex-lock! port) ;; get exclusive access to port
7202 (macro-port-rtimeout-set! port timeout)
7203 (macro-port-rtimeout-thunk-set! port thunk)
7204 (##condvar-signal-no-reschedule!
7205 (macro-event-queue-port-rdevice-condvar port)
7207 (macro-port-mutex-unlock! port)
7210 (define set-wtimeout #f)
7212 (define (close port prim arg1)
7214 ;; It is assumed that the thread **does not** have exclusive
7215 ;; access to the port.
7217 (##declare (not interrupts-enabled))
7219 (macro-port-mutex-lock! port) ;; get exclusive access to port
7224 (macro-event-queue-port-rdevice-condvar port)
7227 (macro-port-mutex-unlock! port)
7228 (if (##fixnum? result)
7229 (##raise-os-exception #f result prim arg1)
7233 (macro-make-event-queue-port
7253 (##io-condvar-port-set! rdevice-condvar port)
7256 (define-prim (##open-event-queue
7263 (##fail-check-fixnum 1 prim index))
7265 (if (##not (##fixnum? index))
7268 (##os-device-event-queue-open index)))
7269 (if (##fixnum? rdevice)
7270 (if raise-os-exception?
7271 (##raise-os-exception #f rdevice open-event-queue index)
7273 (cont (##make-event-queue-port rdevice index))))))
7275 (define-prim (open-event-queue index)
7276 (macro-force-vars (index)
7279 (lambda (port) port)
7283 ;;;----------------------------------------------------------------------------
7285 (define-prim (##make-path-psettings
7298 input-char-encoding:
7299 output-char-encoding:
7301 input-char-encoding-errors:
7302 output-char-encoding-errors:
7303 char-encoding-errors:
7305 output-eol-encoding:
7318 (define-prim (##make-input-path-psettings
7323 (macro-direction-in)
7325 input-char-encoding:
7327 input-char-encoding-errors:
7328 char-encoding-errors:
7339 (define-prim (##open-file-generic
7346 (arg2 (macro-absent-obj)))
7349 (##fail-check-string-or-settings 1 prim path-or-settings arg2))
7351 (##make-path-psettings
7353 (if (##string? path-or-settings)
7354 (##list 'path: path-or-settings)
7358 (let ((path (macro-psettings-path psettings)))
7359 (if (##not (##string? path))
7361 (##open-file-generic-from-psettings
7369 (define-prim (##open-file-generic-from-psettings
7376 (arg2 (macro-absent-obj)))
7378 (macro-psettings-path psettings))
7380 (##path-resolve path))
7382 (##os-device-stream-open-path
7384 (##psettings->device-flags psettings)
7385 (##psettings->permissions psettings #o666))))
7386 (if (##fixnum? device)
7387 (if raise-os-exception?
7388 (##raise-os-exception #f device prim path-or-settings arg2)
7391 (##make-device-port-from-single-device
7396 (define-prim (##path-reference path relative-to-path)
7399 (if relative-to-path
7400 (##path-directory (##path-normalize relative-to-path))
7401 (##current-directory))))
7403 (define-prim (##open-file path-or-settings)
7404 (##open-file-generic
7405 (macro-direction-inout)
7407 (lambda (port) port)
7411 (define-prim (open-file path-or-settings)
7412 (macro-force-vars (path-or-settings)
7413 (##open-file path-or-settings)))
7415 (define-prim (##open-input-file path-or-settings)
7416 (##open-file-generic
7417 (macro-direction-in)
7419 (lambda (port) port)
7423 (define-prim (open-input-file path-or-settings)
7424 (macro-force-vars (path-or-settings)
7425 (##open-input-file path-or-settings)))
7427 (define-prim (##open-output-file path-or-settings)
7428 (##open-file-generic
7429 (macro-direction-out)
7431 (lambda (port) port)
7435 (define-prim (open-output-file path-or-settings)
7436 (macro-force-vars (path-or-settings)
7437 (##open-output-file path-or-settings)))
7439 (define-prim (call-with-input-file path-or-settings proc)
7440 (macro-force-vars (path-or-settings proc)
7441 (macro-check-procedure
7444 (call-with-input-file path-or-settings proc)
7445 (##open-file-generic
7446 (macro-direction-in)
7449 (let ((results ;; may get bound to a multiple-values object
7453 call-with-input-file
7457 (define-prim (call-with-output-file path-or-settings proc)
7458 (macro-force-vars (path-or-settings proc)
7459 (macro-check-procedure
7462 (call-with-output-file path-or-settings proc)
7463 (##open-file-generic
7464 (macro-direction-out)
7467 (let ((results ;; may get bound to a multiple-values object
7469 (##force-output port)
7472 call-with-output-file
7476 (define-prim (with-input-from-file path-or-settings thunk)
7477 (macro-force-vars (path-or-settings thunk)
7478 (macro-check-procedure
7481 (with-input-from-file path-or-settings thunk)
7482 (##open-file-generic
7483 (macro-direction-in)
7486 (let ((results ;; may get bound to a multiple-values object
7487 (macro-dynamic-bind input-port port thunk)))
7490 with-input-from-file
7494 (define-prim (with-output-to-file path-or-settings thunk)
7495 (macro-force-vars (path-or-settings thunk)
7496 (macro-check-procedure
7499 (with-output-to-file path-or-settings thunk)
7500 (##open-file-generic
7501 (macro-direction-out)
7504 (let ((results ;; may get bound to a multiple-values object
7505 (macro-dynamic-bind output-port port thunk)))
7506 (##force-output port)
7513 ;;;----------------------------------------------------------------------------
7515 (define-prim (with-input-from-port port thunk)
7516 (macro-force-vars (port thunk)
7517 (macro-check-input-port port 1 (with-input-from-port port thunk)
7518 (macro-check-procedure thunk 2 (with-input-from-port port thunk)
7519 (macro-dynamic-bind input-port port thunk)))))
7521 (define-prim (with-output-to-port port thunk)
7522 (macro-force-vars (port thunk)
7523 (macro-check-output-port port 1 (with-output-to-port port thunk)
7524 (macro-check-procedure thunk 2 (with-output-to-port port thunk)
7525 (macro-dynamic-bind output-port port thunk)))))
7527 ;;;----------------------------------------------------------------------------
7529 (define-prim (##open-predefined
7534 (settings (macro-absent-obj)))
7536 (##make-path-psettings
7538 (##list 'readtable: ##main-readtable)
7542 (##os-device-stream-open-predefined
7544 (##psettings->device-flags psettings))))
7545 (if (##fixnum? device)
7546 (##exit-with-err-code device)
7548 (##make-device-port-from-single-device
7553 (define ##stdin-port #f)
7554 (define ##stdout-port #f)
7555 (define ##stderr-port #f)
7556 (define ##console-port #f)
7558 (define-prim (console-port)
7561 (define-prim (##open-all-predefined)
7563 (##open-predefined (macro-direction-in) '(stdin) -1))
7565 (##open-predefined (macro-direction-out) '(stdout) -2))
7567 (##open-predefined (macro-direction-out) '(stderr) -3))
7568 (set! ##console-port
7569 (##open-predefined (macro-direction-inout) '(console) -4)))
7571 (define-prim (##force-output-on-predefined)
7572 (let ((port ##stdout-port)) (and port (##force-output port)))
7573 (let ((port ##stderr-port)) (and port (##force-output port)))
7574 (let ((port ##console-port)) (and port (##force-output port))))
7576 (##add-exit-job! ##force-output-on-predefined)
7578 ;;;----------------------------------------------------------------------------
7580 (##define-macro (macro-peek-next-char-or-eof re) ;; possibly returns end-of-file
7581 `(macro-peek-char (macro-readenv-port ,re)))
7583 (##define-macro (macro-read-next-char-or-eof re) ;; possibly returns end-of-file
7584 `(macro-read-char (macro-readenv-port ,re)))
7586 (define-prim (##make-filepos line col char-count)
7587 (if (and (##fixnum.< line (macro-max-lines))
7588 (##not (##fixnum.< (macro-max-fixnum32-div-max-lines) col)))
7589 (##fixnum.+ line (##fixnum.* col (macro-max-lines)))
7590 (##fixnum.- 0 char-count)))
7592 (define-prim (##filepos-line filepos)
7593 (if (##fixnum.< filepos 0)
7595 (##fixnum.modulo filepos (macro-max-lines))))
7597 (define-prim (##filepos-col filepos)
7598 (if (##fixnum.< filepos 0)
7599 (##fixnum.- 0 filepos)
7600 (##fixnum.quotient filepos (macro-max-lines))))
7602 ;;;----------------------------------------------------------------------------
7604 ;;; Implementation of readtables.
7606 (implement-check-type-readtable)
7608 (define-prim (##readtable? obj)
7609 (macro-readtable? obj))
7611 (define-prim (readtable? obj)
7612 (macro-force-vars (obj)
7613 (macro-readtable? obj)))
7615 (define-prim (##readtable-copy-shallow rt)
7616 (let ((copy (##vector-copy rt)))
7617 (##subtype-set! copy (macro-subtype-structure))
7620 (define-prim (##readtable-copy rt)
7621 (let ((copy (##readtable-copy-shallow rt)))
7622 (macro-readtable-char-delimiter?-table-set!
7624 (##chartable-copy (macro-readtable-char-delimiter?-table rt)))
7625 (macro-readtable-char-handler-table-set!
7627 (##chartable-copy (macro-readtable-char-handler-table rt)))
7628 (macro-readtable-char-sharp-handler-table-set!
7630 (##chartable-copy (macro-readtable-char-sharp-handler-table rt)))
7633 (define-prim (readtable-case-conversion? rt)
7634 (macro-force-vars (rt)
7635 (macro-check-readtable rt 1 (readtable-case-conversion? rt)
7636 (macro-readtable-case-conversion? rt))))
7638 (define-prim (readtable-case-conversion?-set rt conversion?)
7639 (macro-force-vars (rt conversion?)
7640 (macro-check-readtable rt 1 (readtable-case-conversion?-set rt conversion?)
7641 (let ((new-rt (##readtable-copy-shallow rt)))
7642 (macro-readtable-case-conversion?-set! new-rt conversion?)
7645 (define-prim (readtable-keywords-allowed? rt)
7646 (macro-force-vars (rt)
7647 (macro-check-readtable rt 1 (readtable-keywords-allowed? rt)
7648 (macro-readtable-keywords-allowed? rt))))
7650 (define-prim (readtable-keywords-allowed?-set rt allowed?)
7651 (macro-force-vars (rt allowed?)
7652 (macro-check-readtable rt 1 (readtable-keywords-allowed?-set rt allowed?)
7653 (let ((new-rt (##readtable-copy-shallow rt)))
7654 (macro-readtable-keywords-allowed?-set! new-rt allowed?)
7657 (define-prim (readtable-sharing-allowed? rt)
7658 (macro-force-vars (rt)
7659 (macro-check-readtable rt 1 (readtable-sharing-allowed? rt)
7660 (macro-readtable-sharing-allowed? rt))))
7662 (define-prim (readtable-sharing-allowed?-set rt allowed?)
7663 (macro-force-vars (rt allowed?)
7664 (macro-check-readtable rt 1 (readtable-sharing-allowed?-set rt allowed?)
7665 (let ((new-rt (##readtable-copy-shallow rt)))
7666 (macro-readtable-sharing-allowed?-set! new-rt allowed?)
7669 (define-prim (readtable-eval-allowed? rt)
7670 (macro-force-vars (rt)
7671 (macro-check-readtable rt 1 (readtable-eval-allowed? rt)
7672 (macro-readtable-eval-allowed? rt))))
7674 (define-prim (readtable-eval-allowed?-set rt allowed?)
7675 (macro-force-vars (rt allowed?)
7676 (macro-check-readtable rt 1 (readtable-eval-allowed?-set rt allowed?)
7677 (let ((new-rt (##readtable-copy-shallow rt)))
7678 (macro-readtable-eval-allowed?-set! new-rt allowed?)
7681 (define-prim (readtable-write-extended-read-macros? rt)
7682 (macro-force-vars (rt)
7683 (macro-check-readtable rt 1 (readtable-write-extended-read-macros? rt)
7684 (macro-readtable-write-extended-read-macros? rt))))
7686 (define-prim (readtable-write-extended-read-macros?-set rt allowed?)
7687 (macro-force-vars (rt allowed?)
7688 (macro-check-readtable rt 1 (readtable-write-extended-read-macros?-set rt allowed?)
7689 (let ((new-rt (##readtable-copy-shallow rt)))
7690 (macro-readtable-write-extended-read-macros?-set! new-rt allowed?)
7693 (define-prim (readtable-write-cdr-read-macros? rt)
7694 (macro-force-vars (rt)
7695 (macro-check-readtable rt 1 (readtable-write-cdr-read-macros? rt)
7696 (macro-readtable-write-cdr-read-macros? rt))))
7698 (define-prim (readtable-write-cdr-read-macros?-set rt allowed?)
7699 (macro-force-vars (rt allowed?)
7700 (macro-check-readtable rt 1 (readtable-write-cdr-read-macros?-set rt allowed?)
7701 (let ((new-rt (##readtable-copy-shallow rt)))
7702 (macro-readtable-write-cdr-read-macros?-set! new-rt allowed?)
7705 (define-prim (readtable-max-write-level rt)
7706 (macro-force-vars (rt)
7707 (macro-check-readtable rt 1 (readtable-max-write-level rt)
7708 (macro-readtable-max-write-level rt))))
7710 (define-prim (readtable-max-write-level-set rt level)
7711 (macro-force-vars (rt level)
7712 (macro-check-readtable rt 1 (readtable-max-write-level-set rt level)
7713 (macro-check-index level 2 (readtable-max-write-level-set rt level)
7714 (let ((new-rt (##readtable-copy-shallow rt)))
7715 (macro-readtable-max-write-level-set! new-rt level)
7718 (define-prim (readtable-max-write-length rt)
7719 (macro-force-vars (rt)
7720 (macro-check-readtable rt 1 (readtable-max-write-length rt)
7721 (macro-readtable-max-write-length rt))))
7723 (define-prim (readtable-max-write-length-set rt length)
7724 (macro-force-vars (rt length)
7725 (macro-check-readtable rt 1 (readtable-max-write-length-set rt length)
7726 (macro-check-index length 2 (readtable-max-write-length-set rt length)
7727 (let ((new-rt (##readtable-copy-shallow rt)))
7728 (macro-readtable-max-write-length-set! new-rt length)
7731 (define-prim (readtable-max-unescaped-char rt)
7732 (macro-force-vars (rt)
7733 (macro-check-readtable rt 1 (readtable-max-unescaped-char rt)
7734 (macro-readtable-max-unescaped-char rt))))
7736 (define-prim (readtable-max-unescaped-char-set rt char)
7737 (macro-force-vars (rt char)
7738 (macro-check-readtable rt 1 (readtable-max-unescaped-char-set rt char)
7739 (macro-check-char char 2 (readtable-max-unescaped-char-set rt char)
7740 (let ((new-rt (##readtable-copy-shallow rt)))
7741 (macro-readtable-max-unescaped-char-set! new-rt char)
7744 (define-prim (readtable-start-syntax rt)
7745 (macro-force-vars (rt)
7746 (macro-check-readtable rt 1 (readtable-start-syntax rt)
7747 (macro-readtable-start-syntax rt))))
7749 (define-prim (readtable-start-syntax-set rt start)
7750 (macro-force-vars (rt start)
7751 (macro-check-readtable rt 1 (readtable-start-syntax-set rt start)
7752 (let ((new-rt (##readtable-copy-shallow rt)))
7753 (macro-readtable-start-syntax-set! new-rt start)
7756 (define ##scheme-file-extensions #f)
7757 (set! ##scheme-file-extensions
7761 (define ##language-specs #f)
7762 (set! ##language-specs '(
7763 ;; name keywords-allowed? start-syntax
7764 ;; \ case-conversion? \ / srfi-22?
7766 #("gsi" #f #t scm #f)
7767 #("six" #f #t six #f)
7768 #("gsi-script" #f #t scm #f)
7769 #("six-script" #f #t six #f)
7770 #("scheme-srfi-0" #t #f scm #t)
7771 #("scheme-r5rs" #t #f scm #t)
7772 #("scheme-r4rs" #t #f scm #t)
7773 #("scheme-ieee-1178-1990" #t #f scm #t)
7776 (define-prim (##extract-language-and-tail script-line-or-program-path)
7778 (define (constituent? c)
7779 (or (##char-alphabetic? c)
7784 (and script-line-or-program-path
7785 (let loop1 ((start 0))
7786 (let loop2 ((end start))
7790 (##string-length script-line-or-program-path))
7791 (loop1 (##fixnum.+ end 1))
7794 (if (and (##fixnum.<
7796 (##string-length script-line-or-program-path))
7797 (let ((c (##string-ref script-line-or-program-path end)))
7799 (loop2 (##fixnum.+ end 1))
7800 (if (##fixnum.= start end)
7802 (let loop3 ((lst ##language-specs))
7804 (let* ((language (##car lst))
7805 (name (macro-language-name language))
7806 (len (##string-length name)))
7807 (if (##not (##fixnum.= (##fixnum.- end start) len))
7809 (let loop4 ((j start) (k 0))
7810 (if (##fixnum.< j end)
7811 (if (##char=? (##string-ref
7812 script-line-or-program-path
7814 (##string-ref name k))
7815 (loop4 (##fixnum.+ j 1)
7817 (loop3 (##cdr lst)))
7818 (let loop5 ((end end))
7819 (if (##fixnum.< (##fixnum.+ end 2)
7821 script-line-or-program-path))
7822 (if (and (##char=? (##string-ref
7823 script-line-or-program-path
7826 (##char=? (##string-ref
7827 script-line-or-program-path
7830 (##char=? (##string-ref
7831 script-line-or-program-path
7836 script-line-or-program-path
7839 script-line-or-program-path)))
7840 (loop5 (##fixnum.+ end 1)))
7845 (define-prim (##readtable-setup-for-language! rt language)
7846 (macro-readtable-case-conversion?-set!
7848 (macro-language-case-conversion? language))
7849 (macro-readtable-keywords-allowed?-set!
7851 (macro-language-keywords-allowed? language))
7852 (macro-readtable-start-syntax-set!
7854 (macro-language-start-syntax language))
7855 (##readtable-setup-for-standard-level! rt))
7857 (define-prim (##readtable-setup-for-standard-level! rt)
7858 (let ((standard-level (##get-standard-level)))
7859 (cond ((##fixnum.= 1 standard-level)
7860 (macro-readtable-case-conversion?-set! rt #f)
7861 (macro-readtable-keywords-allowed?-set! rt #t))
7862 ((##fixnum.< 1 standard-level)
7863 (macro-readtable-case-conversion?-set! rt #t)
7864 (macro-readtable-keywords-allowed?-set! rt #f)))))
7866 (define-prim (##make-readtable-parameter readtable)
7870 (macro-check-readtable val 1 (##make-readtable-parameter val)
7876 ;;(define-prim (main . args) ;; predefine main procedure so scripts don't have to
7879 (define-prim (##start-main language)
7880 (cond ((macro-language-srfi-22? language)
7882 (let ((status (##eval '(main (##cdr ##processed-command-line)))))
7883 (if (##fixnum? status)
7885 (##exit-abnormally)))))
7888 (##eval '(##apply main (##cdr ##processed-command-line)))
7891 (##define-macro (macro-ctrl-char? c)
7892 `(or (##char<? ,c #\space) (##char=? ,c #\delete)))
7894 (##define-macro (macro-gt-max-unescaped-char? rt c)
7895 `(##char<? (macro-readtable-max-unescaped-char ,rt) ,c))
7897 (##define-macro (macro-must-escape-char? rt c)
7898 `(or (macro-ctrl-char? ,c)
7899 (macro-gt-max-unescaped-char? ,rt ,c)))
7901 ;;;----------------------------------------------------------------------------
7905 (define-prim (##make-marktable)
7906 (##declare (not interrupts-enabled))
7909 (define-prim (##marktable-mark! table obj)
7910 (##declare (not interrupts-enabled))
7911 (let ((alist (##vector-ref table 1)))
7912 (let ((x (##assq obj alist)));;;;;;;;;;;;;
7918 (##vector-set! table 1 (##cons (##cons obj #f) alist))
7921 (define-prim (##marktable-lookup! table obj stamp?)
7922 (##declare (not interrupts-enabled))
7923 (let ((alist (##vector-ref table 1)))
7924 (let ((x (##assq obj alist)));;;;;;;;;;;;;;;;
7926 (let ((id (##cdr x)))
7927 (if (and stamp? (##eq? id #t))
7928 (let ((n (##fixnum.+ (##vector-ref table 0) 1)))
7929 (##vector-set! table 0 n)
7935 (define-prim (##marktable-save table)
7936 (##declare (not interrupts-enabled))
7937 (##vector-ref table 0))
7939 (define-prim (##marktable-restore! table n)
7940 (##declare (not interrupts-enabled))
7941 (##vector-set! table 0 n)
7942 (let ((alist (##vector-ref table 1)))
7943 (let loop ((lst alist))
7945 (let* ((x (##car lst))
7947 (if (and (##fixnum? id)
7950 (loop (##cdr lst)))))))
7953 ;;;----------------------------------------------------------------------------
7955 (define-prim (##might-write-differently? old-obj new-obj)
7956 (cond ((##eq? old-obj new-obj)
7957 (or (##pair? new-obj)
7958 (and (##subtyped? new-obj)
7959 (##not (or (##complex? new-obj)
7961 (##keyword? new-obj))))))
7962 ((##complex? old-obj)
7963 (##not (and (##complex? new-obj)
7964 (##= old-obj new-obj))))
7968 ;;;----------------------------------------------------------------------------
7970 (define-prim (##default-wr we obj)
7971 (let ((limit (macro-writeenv-limit we)))
7972 (if (##fixnum.< 0 limit)
7973 (cond ((##symbol? obj)
7974 (##wr-symbol we obj))
7976 (##wr-keyword we obj))
7980 (##wr-complex we obj))
7984 (##wr-string we obj))
7986 (##wr-vector we obj))
7988 (##wr-foreign we obj))
7990 (##wr-procedure we obj))
7994 (##wr-promise we obj))
7996 (##wr-s8vector we obj))
7998 (##wr-u8vector we obj))
8000 (##wr-s16vector we obj))
8002 (##wr-u16vector we obj))
8004 (##wr-s32vector we obj))
8006 (##wr-u32vector we obj))
8008 (##wr-s64vector we obj))
8010 (##wr-u64vector we obj))
8012 (##wr-f32vector we obj))
8014 (##wr-f64vector we obj))
8016 (##wr-structure we obj))
8017 ((##gc-hash-table? obj)
8018 (##wr-gc-hash-table we obj))
8019 ((##continuation? obj)
8020 (##wr-continuation we obj))
8022 (##wr-frame we obj))
8024 (##wr-return we obj))
8026 (##wr-meroon we obj))
8032 (##wr-other we obj))))))
8035 (set! ##wr ##default-wr)
8037 (define-prim (##wr-str we s)
8038 (##wr-substr we s 0 (##string-length s)))
8040 (define-prim (##wr-substr we s i j)
8041 (let ((limit (macro-writeenv-limit we)))
8042 (if (##fixnum.< 0 limit)
8043 (let ((len (##fixnum.- j i))
8044 (port (macro-writeenv-port we)))
8045 (if (##fixnum.< limit len)
8047 (##write-substring s i (##fixnum.+ i limit) port)
8048 (macro-writeenv-limit-set! we 0))
8050 (##write-substring s i j port)
8051 (macro-writeenv-limit-set! we (##fixnum.- limit len))))))))
8053 (define-prim (##wr-ch we c)
8054 (let ((limit (macro-writeenv-limit we)))
8055 (if (##fixnum.< 0 limit)
8057 (##write-char c (macro-writeenv-port we))
8058 (macro-writeenv-limit-set! we (##fixnum.- limit 1))))))
8060 (define-prim (##wr-filler we n str)
8061 (let ((len (##string-length str)))
8063 (if (##fixnum.< 0 i)
8064 (let ((x (if (##fixnum.< len i) len i)))
8065 (##wr-substr we str 0 x)
8066 (loop (##fixnum.- i x)))))))
8068 (define-prim (##wr-spaces we n)
8069 (##wr-filler we n " "))
8071 (define ##pretty-print-shifting-allowed? #f)
8072 (set! ##pretty-print-shifting-allowed? #t)
8074 (define-prim (##wr-indent we shifted-col)
8075 (##wr-ch we #\newline)
8077 (if ##pretty-print-shifting-allowed?
8079 (define margin-width 15)
8081 (macro-writeenv-shift we))
8083 (macro-writeenv-width we))
8085 (##fixnum.quotient width 2))
8089 (##fixnum.quotient width 5)))
8092 (##fixnum.- width margin-width)
8093 (##fixnum.quotient (##fixnum.* width 4) 5)))
8095 (##fixnum.- shifted-col shift)))
8096 (cond ((##fixnum.< col lo-lim)
8097 (if (##fixnum.= shift 0)
8099 (let ((s (##fixnum.min shift width/2)))
8100 (macro-writeenv-shift-set!
8102 (##fixnum.- shift s))
8104 (##wr-filler we s ">>>>>>>>")
8105 (##wr-ch we #\newline)
8107 ((##fixnum.> col hi-lim)
8109 (macro-writeenv-shift-set!
8111 (##fixnum.+ shift s))
8113 (##wr-filler we s "<<<<<<<<")
8114 (##wr-ch we #\newline)
8119 (##wr-spaces we (##fixnum.- col 1))))
8121 (define-prim (##shifted-column we)
8122 (##fixnum.+ (macro-writeenv-shift we)
8123 (##output-port-column (macro-writeenv-port we))))
8125 (define-prim (##wr-sn we obj type name)
8126 (case (macro-writeenv-style we)
8128 (if (##wr-mark we obj)
8130 (##wr-no-display we type)
8131 (if (##not (##eq? name (##void)))
8132 (##wr-no-display we name)))))
8134 (if (##wr-stamp we obj)
8137 (##wr-no-display we type)
8139 (##wr-str we (##number->string (##object->serial-number obj) 10))
8140 (if (##not (##eq? name (##void)))
8142 (##wr-ch we #\space)
8143 (##wr-no-display we name)))
8144 (##wr-ch we #\>))))))
8146 (define-prim (##wr-no-display we obj)
8147 (let ((style (macro-writeenv-style we)))
8150 (macro-writeenv-style-set! we 'write)
8152 (macro-writeenv-style-set! we style))
8156 (define-prim (##wr-mark we obj)
8157 (let ((mt (macro-writeenv-marktable we)))
8159 (##marktable-mark! mt obj)
8162 (define-prim (##wr-stamp we obj)
8163 (let ((mt (macro-writeenv-marktable we)))
8165 (let ((id (##marktable-lookup! mt obj #t)))
8171 (##wr-str we (##number->string id 10))
8175 (##wr-str we (##number->string (##cdr id) 10))
8181 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8183 ;;; Write methods for each object type
8185 (define-prim (##wr-symbol we obj)
8186 (let ((uninterned? (##uninterned-symbol? obj)))
8187 (case (macro-writeenv-style we)
8190 (##wr-mark we obj)))
8192 (if (or (##not uninterned?)
8193 (##wr-stamp we obj))
8197 (let ((str (##symbol->string obj)))
8198 (if (case (macro-writeenv-style we)
8199 ((display print) #t)
8200 (else (##not (##escape-symbol? we str))))
8202 (##wr-escaped-string we str #\|)))))))))
8204 (define-prim (##escape-symbol? we str)
8205 (let ((n (##string-length str)))
8206 (or (##fixnum.= n 0)
8207 (and (##fixnum.= n 1)
8208 (##char=? (##string-ref str 0) #\.))
8209 (and (##char=? (##string-ref str 0) #\#)
8210 (or (##fixnum.= n 1)
8211 (let ((next (##string-ref str 1)))
8212 (and (##not (##char=? next #\#))
8213 (##not (##char=? next #\%))))))
8214 (##string->number str 10 #t)
8215 (and (##fixnum.< 1 n)
8216 (let ((keywords-allowed?
8217 (macro-readtable-keywords-allowed?
8218 (macro-writeenv-readtable we))))
8219 (and keywords-allowed?
8220 (##char=? (##string-ref
8222 (if (##eq? keywords-allowed? 'prefix)
8226 (##escape-symkey? we str))))
8228 (define-prim (##escape-symkey? we str);;;;;;;;;;;;;;;;;;;;;;;;;;
8229 (let ((n (##string-length str)))
8230 (let loop ((i (##fixnum.- n 1)))
8231 (if (##fixnum.< i 0)
8233 (let ((c (##string-ref str i))
8234 (rt (macro-writeenv-readtable we)))
8235 (or (macro-must-escape-char? rt c)
8236 (##readtable-char-delimiter? rt c)
8237 (##not (##char=? c (##readtable-convert-case rt c)))
8238 (loop (##fixnum.- i 1))))))))
8240 (define-prim (##wr-keyword we obj)
8241 (let ((uninterned? (##uninterned-keyword? obj)))
8242 (case (macro-writeenv-style we)
8245 (##wr-mark we obj)))
8247 (if (or (##not uninterned?)
8248 (##wr-stamp we obj))
8253 (##keyword->string obj))
8255 (macro-readtable-keywords-allowed?
8256 (macro-writeenv-readtable we))))
8257 (if (##eq? keywords-allowed? 'prefix)
8259 (if (case (macro-writeenv-style we)
8261 (else (##not (##escape-keyword? we str))))
8263 (##wr-escaped-string we str #\|))
8264 (if (##not (##eq? keywords-allowed? 'prefix))
8265 (##wr-ch we #\:)))))))))
8267 (define-prim (##escape-keyword? we str)
8268 (let ((n (##string-length str)))
8269 (or (##fixnum.= n 0)
8270 (and (##char=? (##string-ref str 0) #\#)
8271 (or (##fixnum.= n 1)
8272 (let ((next (##string-ref str 1)))
8273 (and (##not (##char=? next #\#))
8274 (##not (##char=? next #\%)))))
8275 (let ((keywords-allowed?
8276 (macro-readtable-keywords-allowed?
8277 (macro-writeenv-readtable we))))
8278 (##not (##eq? keywords-allowed? 'prefix))))
8279 (##escape-symkey? we str))))
8281 (define-prim (##wr-pair we obj)
8283 (define (force-if-required we x)
8284 (if (macro-writeenv-force? we)
8288 (define (read-macro-prefix we head tail)
8290 (define (check-for-at-sign str1 str2)
8292 ;; We have to check that the next character written after the
8293 ;; comma won't be an "@" because the reader would interpret this
8294 ;; as a ",@" or "#,@" readmacro. The algorithm is slow but
8295 ;; correct and modular.
8297 (let ((limit (macro-writeenv-limit we)))
8298 (if (##fixnum.< 1 limit) ;; speed up ",,,,,,xxx" case
8300 (macro-writeenv-marktable we))
8302 (and mt (##marktable-save mt)))
8304 (##open-output-string))
8307 (macro-writeenv-style we)
8309 (macro-writeenv-readtable we)
8311 (macro-writeenv-force? we)
8312 (macro-writeenv-width we)
8313 (macro-writeenv-shift we)
8314 (macro-writeenv-close-parens we)
8315 (macro-writeenv-level we)
8317 (##wr we2 (##car tail))
8318 (if mt (##marktable-restore! mt state))
8319 (let ((str (##get-output-string port)))
8320 (if (or (##fixnum.< (##string-length str) 1)
8321 (##char=? (##string-ref str 0) #\@))
8322 str2 ;; force a space after the comma
8328 (##null? (force-if-required we (##cdr tail)))
8329 (let ((mt (macro-writeenv-marktable we)))
8331 (##marktable-lookup! mt tail #f))))
8333 (macro-readtable-quote-keyword
8334 (macro-writeenv-readtable we)))
8337 (macro-readtable-quasiquote-keyword
8338 (macro-writeenv-readtable we)))
8341 (macro-readtable-unquote-keyword
8342 (macro-writeenv-readtable we)))
8343 (check-for-at-sign "," ", "))
8345 (macro-readtable-unquote-splicing-keyword
8346 (macro-writeenv-readtable we)))
8349 (and (macro-readtable-write-extended-read-macros?
8350 (macro-writeenv-readtable we))
8352 (macro-readtable-sharp-quote-keyword
8353 (macro-writeenv-readtable we)))
8356 (macro-readtable-sharp-quasiquote-keyword
8357 (macro-writeenv-readtable we)))
8360 (macro-readtable-sharp-unquote-keyword
8361 (macro-writeenv-readtable we)))
8362 (check-for-at-sign "#," "#, "))
8364 (macro-readtable-sharp-unquote-splicing-keyword
8365 (macro-writeenv-readtable we)))
8370 (define (wr-list-possibly-with-read-macro-prefix we obj plain-pretty-print?)
8372 (force-if-required we (##car obj)))
8374 (force-if-required we (##cdr obj))))
8376 (define (parenthesized-normal)
8377 (wr-list-using-format
8380 (##reader->open-close we ##read-list '("(" . ")"))
8381 (case (macro-writeenv-style we)
8383 (if plain-pretty-print?
8385 (get-format we head tail)))
8389 (define (parenthesized-read-macro open-close)
8390 (wr-list-using-format
8394 (case (macro-writeenv-style we)
8395 ((pretty-print) plain-format)
8396 (else space-format))))
8401 (cond ((##head->open-close we head #f)
8403 (lambda (open-close)
8404 (parenthesized-read-macro open-close)))
8407 (read-macro-prefix we head tail)))
8410 (##wr-str we prefix)
8411 (##wr we (##car tail)))
8412 (parenthesized-normal)))))
8413 (parenthesized-normal))))
8415 (define space-format
8418 (define plain-format
8421 (define (get-format we head tail)
8422 (if (##symbol? head)
8425 (macro-readtable-pretty-print-formats
8426 (macro-writeenv-readtable we)))))
8428 (if (and (##eq? head 'let) ;; check for named let
8430 (##symbol? (force-if-required we (##car tail))))
8433 ((##fixnum.< (##string-length (##symbol->string head))
8440 (define (wr-list-using-format we obj open-close format)
8442 (##wr-str we (##car open-close))
8445 (macro-writeenv-level we)))
8446 (if (##not (##fixnum.< level
8447 (macro-readtable-max-write-level
8448 (macro-writeenv-readtable we))))
8450 (let* ((close-parens
8451 (macro-writeenv-close-parens we))
8453 (##fixnum.+ close-parens 1)))
8454 (macro-writeenv-level-set! we (##fixnum.+ level 1))
8455 (let ((start-col (##shifted-column we)))
8456 (let loop ((lst obj)
8460 (define (wr-elem elem)
8462 (cond ((##fixnum.= i 0)
8464 ((or (##fixnum.< (##vector-ref format 4) 0)
8465 (##fixnum.< i (##vector-ref format 0)))
8466 (##wr-ch we #\space)
8468 ((##fixnum.= i (##vector-ref format 0))
8469 (##wr-ch we #\space)
8470 (##shifted-column we))
8471 ((##fixnum.= i (##vector-ref format 2))
8473 (##fixnum.+ start-col
8474 (##vector-ref format 4))))
8475 (##wr-indent we new-col)
8478 (##wr-indent we col)
8484 (if (##fixnum.< i (##vector-ref format 2))
8485 (##vector-ref format 1)
8486 (##vector-ref format 3)))
8490 (define (wr-str str)
8491 (let ((style (macro-writeenv-style we)))
8492 (macro-writeenv-style-set! we 'print)
8494 (macro-writeenv-style-set! we style)))
8496 (if (##fixnum.< 0 (macro-writeenv-limit we))
8497 (cond ((##pair? lst)
8498 (if (##not (##fixnum.< i
8499 (macro-readtable-max-write-length
8500 (macro-writeenv-readtable we))))
8502 (let ((mt (macro-writeenv-marktable we)))
8503 (if (and (##fixnum.< 0 i)
8505 (##marktable-lookup! mt lst #f))
8508 (macro-writeenv-close-parens-set!
8513 (force-if-required we (##car lst)))
8515 (force-if-required we (##cdr lst)))
8517 (and (macro-readtable-write-cdr-read-macros?
8518 (macro-writeenv-readtable we))
8519 (read-macro-prefix we head tail))))
8524 (macro-writeenv-close-parens-set!
8527 (##wr we (##car tail)))
8529 (macro-writeenv-close-parens-set!
8536 (wr-elem head)))))))))
8537 ((##not (##null? lst))
8539 (macro-writeenv-close-parens-set! we new-close-parens)
8541 (macro-writeenv-level-set! we level)
8542 (macro-writeenv-close-parens-set! we close-parens))))
8544 (##wr-str we (##cdr open-close)))
8546 (define (wr-list we obj plain-pretty-print?)
8547 (if (##wr-stamp we obj)
8548 (if (case (macro-writeenv-style we)
8550 (##not (##wr-one-line-pretty-print
8554 (wr-list-possibly-with-read-macro-prefix
8557 plain-pretty-print?)))))
8560 (wr-list-possibly-with-read-macro-prefix
8563 plain-pretty-print?))))
8565 (case (macro-writeenv-style we)
8567 (if (##wr-mark we obj)
8568 (begin;;;;;;;;;;;;;;;;;;;;;;;check level and length?
8569 (##wr we (##car obj))
8570 (##wr we (##cdr obj)))))
8572 (##wr we (##car obj))
8573 (##wr we (##cdr obj)))
8575 (wr-list we obj #f))))
8577 (define-prim (##wr-one-line-pretty-print we obj wr-obj)
8579 (##shifted-column we))
8580 (available-space-for-obj
8584 (macro-writeenv-shift we)
8585 (macro-writeenv-width we))
8586 (macro-writeenv-close-parens we))
8593 available-space-for-obj)))
8599 (define-prim (##wr-fits-on-line we obj wr-obj available-space-for-obj)
8601 (macro-writeenv-marktable we))
8603 (and mt (##marktable-save mt)))
8605 (##open-output-string))
8610 (macro-writeenv-readtable we)
8612 (macro-writeenv-force? we)
8613 (macro-writeenv-width we)
8614 (macro-writeenv-shift we)
8615 (macro-writeenv-close-parens we)
8616 (macro-writeenv-level we)
8617 (##fixnum.+ available-space-for-obj 1))))
8619 (let ((str (##get-output-string port)))
8620 (if (##fixnum.< available-space-for-obj (##string-length str))
8622 (if mt (##marktable-restore! mt state))
8626 (define-prim (##wr-complex we obj)
8627 (case (macro-writeenv-style we)
8629 (if (##not (##fixnum? obj))
8630 (##wr-mark we obj)))
8632 (##wr-str we (##number->string obj 10)))))
8634 (define-prim (##wr-char we obj)
8635 (case (macro-writeenv-style we)
8641 (let ((x (##assq-cdr obj
8642 (macro-readtable-named-char-table
8643 (macro-writeenv-readtable we)))))
8646 (##wr-str we (##car x)))
8647 ((##not (macro-must-escape-char?
8648 (macro-writeenv-readtable we)
8652 (let ((n (##fixnum.<-char obj)))
8653 (cond ((##fixnum.< #xffff n)
8656 ((##fixnum.< #xff n)
8661 (##wr-hex we n 2))))))))))
8663 (define-prim (##wr-hex we n nb-digits)
8665 (##fixnum.< 1 nb-digits)
8668 (##fixnum.arithmetic-shift-right n 4)
8669 (and nb-digits (##fixnum.- nb-digits 1))))
8671 (##string-ref ##digit-to-char-table (##fixnum.bitwise-and n 15))))
8673 (define-prim (##wr-oct we n nb-digits)
8675 (##fixnum.< 1 nb-digits)
8678 (##fixnum.arithmetic-shift-right n 3)
8679 (and nb-digits (##fixnum.- nb-digits 1))))
8681 (##string-ref ##digit-to-char-table (##fixnum.bitwise-and n 7))))
8683 (define-prim (##wr-string we obj)
8684 (case (macro-writeenv-style we)
8690 (if (##wr-stamp we obj)
8691 (##wr-escaped-string we obj #\")))))
8693 (define-prim (##wr-escaped-string we s special-escape)
8694 (##wr-ch we special-escape)
8695 (let loop ((i 0) (j 0) (escape-digit-limit #f))
8696 (if (##fixnum.< j (##string-length s))
8700 (##fixnum.<-char c))
8702 (macro-ctrl-char? c))
8704 (cond ((or (##char=? c #\\)
8705 (##char=? c special-escape))
8709 (macro-readtable-escaped-char-table
8710 (macro-writeenv-readtable we))))
8718 (macro-readtable-escape-ctrl-chars?
8719 (macro-writeenv-readtable we))
8721 (macro-gt-max-unescaped-char? (macro-writeenv-readtable we) c)
8722 (and escape-digit-limit
8724 (##not (##char=? c #\#)) ;; avoid treating "#" like "0"
8725 (##fixnum.< (##u8vector-ref ##char-to-digit-table n)
8726 escape-digit-limit))))
8728 (##wr-substr we s i j)
8733 ((##fixnum.< #xffff n)
8737 ((##fixnum.< #xff n)
8741 #; ;; disable \x... escapes on output
8748 (loop j+1 j+1 (if (##fixnum.< n 32) 8 #f)))))
8751 (##wr-substr we s i j)
8752 (##wr-ch we special-escape)))))
8754 (define-prim (##reader->open-close we reader default)
8755 (let ((rt (macro-writeenv-readtable we)))
8756 (cond ((##eq? (##readtable-char-handler rt #\() reader) '("(" . ")"))
8757 ((##eq? (##readtable-char-handler rt #\[) reader) '("[" . "]"))
8758 ((##eq? (##readtable-char-handler rt #\{) reader) '("{" . "}"))
8759 ((##eq? (##readtable-char-handler rt #\<) reader) '("<" . ">"))
8762 (define-prim (##head->open-close we head default)
8763 (let ((rt (macro-writeenv-readtable we)))
8764 (cond ((##eq? head (macro-readtable-paren-keyword rt)) '("(" . ")"))
8765 ((##eq? head (macro-readtable-bracket-keyword rt)) '("[" . "]"))
8766 ((##eq? head (macro-readtable-brace-keyword rt)) '("{" . "}"))
8767 ((##eq? head (macro-readtable-angle-keyword rt)) '("<" . ">"))
8770 (define-prim (##wr-vector we obj)
8771 (let* ((std-open-close
8774 (if (macro-readtable-r6rs-compatible-write?
8775 (macro-writeenv-readtable we))
8777 (##reader->open-close we ##read-vector-or-list std-open-close))))
8778 (##wr-vector-aux1 we obj (##vector-length obj) ##vector-ref open-close)))
8780 (define-prim (##wr-vector-aux1 we obj len vect-ref open-close)
8781 (case (macro-writeenv-style we)
8783 (if (##wr-mark we obj)
8784 (##wr-vector-aux2 we obj len vect-ref)))
8786 (##wr-vector-aux2 we obj len vect-ref))
8788 (if (##wr-stamp we obj)
8789 (##wr-vector-aux3 we obj len vect-ref open-close)))))
8791 (define-prim (##wr-vector-aux2 we obj len vect-ref)
8793 (macro-writeenv-level we)))
8794 (if (##fixnum.< level
8795 (macro-readtable-max-write-level
8796 (macro-writeenv-readtable we)))
8798 (macro-writeenv-level-set! we (##fixnum.+ level 1))
8800 (if (##fixnum.< i len)
8802 (macro-readtable-max-write-length
8803 (macro-writeenv-readtable we)))
8805 (##wr we (vect-ref obj i))
8806 (loop (##fixnum.+ i 1))))))
8807 (macro-writeenv-level-set! we level)))))
8809 (define-prim (##wr-vector-aux3 we obj len vect-ref open-close)
8811 (define (wr-vect we obj len vect-ref open-close)
8813 (##wr-str we (##car open-close))
8816 (macro-writeenv-level we)))
8817 (if (##not (##fixnum.< level
8818 (macro-readtable-max-write-level
8819 (macro-writeenv-readtable we))))
8821 (let* ((close-parens
8822 (macro-writeenv-close-parens we))
8824 (##fixnum.+ close-parens 1)))
8825 (macro-writeenv-level-set! we (##fixnum.+ level 1))
8827 (##shifted-column we)))
8829 (if (##fixnum.< 0 (macro-writeenv-limit we))
8830 (if (##fixnum.< i len)
8832 (if (##fixnum.< 0 i)
8833 (case (macro-writeenv-style we)
8834 ((pretty-print) (##wr-indent we start-col))
8835 (else (##wr-ch we #\space))))
8836 (if (##not (##fixnum.< i
8837 (macro-readtable-max-write-length
8838 (macro-writeenv-readtable we))))
8844 (macro-writeenv-close-parens-set!
8846 (if (##fixnum.= new-i len)
8851 (macro-writeenv-level-set! we level)
8852 (macro-writeenv-close-parens-set! we close-parens))))
8854 (##wr-str we (##cdr open-close)))
8856 (if (case (macro-writeenv-style we)
8858 (##not (##wr-one-line-pretty-print
8862 (wr-vect we obj len vect-ref open-close)))))
8865 (wr-vect we obj len vect-ref open-close)))
8867 (define-prim (##wr-foreign we obj)
8868 (case (macro-writeenv-style we)
8872 (let ((tags (##foreign-tags obj)))
8875 (##wr-no-display we (##car tags))
8876 (##wr-str we "foreign"))
8878 (##wr-str we (##number->string (##object->serial-number obj) 10))
8880 (##wr-str we (##number->string (##foreign-address obj) 16))
8881 (##wr-ch we #\>)))))
8883 (define-prim (##explode-object obj)
8884 (##vector-copy obj))
8886 (define-prim (##implode-object re fields subtype)
8887 (let* ((n (##vector-length fields))
8888 (v (##make-vector n)))
8889 (##subtype-set! v subtype)
8890 (let loop ((i (##fixnum.- n 1)))
8891 (if (##fixnum.< i 0)
8893 (let ((obj (##vector-ref fields i)))
8894 (if (##label-marker? obj)
8895 (##label-marker-fixup-handler-add!
8898 (lambda (resolved-obj)
8899 (##vector-set! v i resolved-obj)))
8900 (##vector-set! v i obj))
8901 (loop (##fixnum.- i 1)))))))
8903 (define-prim (##explode-structure obj)
8904 (##explode-object obj))
8906 (define-prim (##implode-structure re fields)
8907 (##implode-object re fields (macro-subtype-structure)))
8909 ';old version... more type checks but incomplete type checks so why bother?
8910 (define-prim (##implode-structure re fields)
8911 (let ((nb-fields (##vector-length fields)))
8912 (if (##fixnum.< 0 nb-fields)
8913 (let ((n (##vector-length fields)))
8914 (let ((s (##make-vector n)))
8916 (define (set-element! i obj)
8917 (##vector-set! s i obj)
8918 (if (##fixnum.= i 0)
8919 (let ((n (##vector-length s)))
8920 (##subtype-set! s (macro-subtype-structure))
8921 (if (##not (and (##type? obj)
8922 (##fixnum.= (##type-field-count obj)
8924 (##subtype-set! s (macro-subtype-vector))))))
8926 (let loop ((i (##fixnum.- n 1)))
8927 (if (##fixnum.< i 0)
8929 (let ((obj (##vector-ref fields i)))
8930 (if (##label-marker? obj)
8931 (##label-marker-fixup-handler-add!
8934 (lambda (resolved-obj)
8935 (set-element! i resolved-obj)))
8936 (set-element! i obj))
8937 (loop (##fixnum.- i 1)))))))
8940 (define-prim (##implode-frame re fields)
8941 (##implode-object re fields (macro-subtype-frame)))
8943 (define-prim (##implode-continuation re fields)
8944 (##implode-object re fields (macro-subtype-continuation)))
8946 (define-prim (##explode-procedure proc)
8947 (cond ((##closure? proc)
8948 (##explode-closure proc))
8950 (##explode-subprocedure proc '()))))
8952 (define-prim (##explode-closure closure)
8953 (let loop ((i (##fixnum.- (##closure-length closure) 1))
8955 (if (##fixnum.< i 1)
8956 (##explode-subprocedure (##closure-code closure) lst)
8957 (loop (##fixnum.- i 1)
8958 (##cons (##closure-ref closure i) lst)))))
8960 (define-prim (##explode-subprocedure subproc lst)
8962 (##subprocedure-parent-name subproc)))
8966 (let ((id (##subprocedure-id subproc)))
8967 (if (and (##fixnum.= id 0) (##null? lst))
8972 (define-prim (##implode-procedure re fields)
8973 (let ((x (##implode-procedure-or-return re fields)))
8974 (if (##procedure? x)
8978 (define-prim (##implode-procedure-or-return re fields)
8979 ;;;;; why bother with all these checks if they are incomplete?
8980 (let ((nb-fields (##vector-length fields)))
8981 (if (##fixnum.= nb-fields 0)
8983 (let ((proc-identifier (##vector-ref fields 0)))
8984 (if (##symbol? proc-identifier)
8985 (let* ((var (##make-global-var proc-identifier))
8986 (proc (##global-var-primitive-ref var)))
8987 (if (and (##procedure? proc)
8988 (##not (##subprocedure? proc))
8989 (##not (##closure? proc)))
8990 (if (##fixnum.= nb-fields 1)
8992 (let ((subproc-id (##vector-ref fields 1)))
8993 (if (and (##fixnum? subproc-id)
8994 (##fixnum.< 0 subproc-id))
8995 (let ((subproc (##make-subprocedure proc subproc-id)))
8997 (let* ((nb-closed (##subprocedure-nb-closed subproc))
8998 (n (##fixnum.- (##vector-length fields) 1)))
8999 (if (##fixnum.= (##fixnum.+ nb-closed 1) n)
9000 (if (##fixnum.= nb-closed 0)
9002 (let ((c (##make-vector n subproc)))
9003 (##subtype-set! c (macro-subtype-procedure))
9004 (let loop ((i (##fixnum.- n 1)))
9005 (if (##fixnum.< i 1)
9008 (##vector-ref fields
9010 (if (##label-marker? obj)
9011 (##label-marker-fixup-handler-add!
9014 (lambda (resolved-obj)
9015 (##closure-set! c i resolved-obj)))
9016 (##closure-set! c i obj))
9017 (loop (##fixnum.- i 1)))))))
9024 ;;;;;;;;;;;;;;;;;; FIX THIS:
9025 ;;;;> '#0=#procedure(##make-default-entry-hook 2 #0#)
9026 ;;;;#0=#procedure(##make-default-entry-hook 2 #(#(source1) #0# (stdin) 262149))
9028 (define-prim (##explode-return ret)
9029 (##explode-subprocedure ret '()))
9031 (define-prim (##implode-return re fields)
9032 (let ((x (##implode-procedure-or-return re fields)))
9037 (define-prim (##wr-opaque we obj explode open-close type name)
9038 (if (##eq? (macro-readtable-sharing-allowed?
9039 (macro-writeenv-readtable we))
9041 (##wr-serialize we obj explode open-close)
9042 (##wr-sn we obj type name)))
9044 (define-prim (##wr-serialize we obj explode open-close)
9045 (case (macro-writeenv-style we)
9047 (if (##wr-mark we obj)
9048 (let ((vect (explode obj)))
9052 (##vector-length vect)
9055 (if (##wr-stamp we obj)
9056 (let ((vect (explode obj)))
9060 (##vector-length vect)
9064 (define-prim (##wr-s8vector we obj)
9065 (##wr-vector-aux1 we obj (##s8vector-length obj) ##s8vector-ref '("#s8(" . ")")))
9067 (define-prim (##wr-u8vector we obj)
9068 (##wr-vector-aux1 we obj (##u8vector-length obj) ##u8vector-ref '("#u8(" . ")")))
9070 (define-prim (##wr-s16vector we obj)
9071 (##wr-vector-aux1 we obj (##s16vector-length obj) ##s16vector-ref '("#s16(" . ")")))
9073 (define-prim (##wr-u16vector we obj)
9074 (##wr-vector-aux1 we obj (##u16vector-length obj) ##u16vector-ref '("#u16(" . ")")))
9076 (define-prim (##wr-s32vector we obj)
9077 (##wr-vector-aux1 we obj (##s32vector-length obj) ##s32vector-ref '("#s32(" . ")")))
9079 (define-prim (##wr-u32vector we obj)
9080 (##wr-vector-aux1 we obj (##u32vector-length obj) ##u32vector-ref '("#u32(" . ")")))
9082 (define-prim (##wr-s64vector we obj)
9083 (##wr-vector-aux1 we obj (##s64vector-length obj) ##s64vector-ref '("#s64(" . ")")))
9085 (define-prim (##wr-u64vector we obj)
9086 (##wr-vector-aux1 we obj (##u64vector-length obj) ##u64vector-ref '("#u64(" . ")")))
9088 (define-prim (##wr-f32vector we obj)
9089 (##wr-vector-aux1 we obj (##f32vector-length obj) ##f32vector-ref '("#f32(" . ")")))
9091 (define-prim (##wr-f64vector we obj)
9092 (##wr-vector-aux1 we obj (##f64vector-length obj) ##f64vector-ref '("#f64(" . ")")))
9094 (define-prim (##wr-structure we obj)
9096 (define (for-each-visible-field proc obj type last?)
9097 (if (##not type) ;; have we reached root of inheritance chain?
9099 (let ((fields (##type-fields type)))
9103 (let ((i*3 (##fixnum.* i 3)))
9104 (if (##fixnum.< i*3 (##vector-length fields))
9105 (let ((field-attributes
9106 (##vector-ref fields (##fixnum.+ i*3 1))))
9108 (##fixnum.bitwise-and field-attributes 1)
9110 (loop1 (##fixnum.+ i 1)
9113 (loop1 (##fixnum.+ i 1)
9117 (for-each-visible-field
9121 (if first #f last?))))
9122 (let loop2 ((i (or first 0)))
9123 (if (##not (##fixnum.< last i))
9127 (##vector-ref fields (##fixnum.+ i*3 1))))
9129 (##fixnum.bitwise-and field-attributes 1)
9132 (##vector-ref fields i*3)))
9133 (proc (##string->keyword
9134 (##symbol->string field-name))
9135 (##unchecked-structure-ref
9137 (##fixnum.+ start i)
9141 (##fixnum.= i last)))))
9142 (loop2 (##fixnum.+ i 1)))))
9145 (##vector-length fields)
9148 (define (wr-structure we obj)
9151 (macro-writeenv-level we)))
9152 (if (##not (##fixnum.< level
9153 (macro-readtable-max-write-level
9154 (macro-writeenv-readtable we))))
9157 (##shifted-column we))
9159 (##structure-type obj))
9161 (macro-writeenv-close-parens we))
9163 (##fixnum.+ close-parens 1)))
9164 (macro-writeenv-level-set! we (##fixnum.+ level 1))
9165 (##wr-no-display we (##type-name type))
9168 (##shifted-column we))
9170 (if (##fixnum.< ##structure-max-head
9171 (##fixnum.- col type-col))
9172 (##fixnum.+ type-col ##structure-indent)
9175 (##wr-str we (##number->string (##object->serial-number obj) 10))
9176 (for-each-visible-field
9177 (lambda (field-name value last?)
9178 (macro-writeenv-close-parens-set!
9183 (case (macro-writeenv-style we)
9185 (##wr-indent we start-col)
9186 (##wr-no-display we field-name)
9187 (let ((col (##shifted-column we)))
9188 (if (##fixnum.< (##fixnum.- col start-col)
9189 ##structure-max-field)
9191 (##wr-ch we #\space)
9192 (##wr-no-display we value))
9193 (let* ((available-space-for-obj
9198 (macro-writeenv-shift we)
9199 (macro-writeenv-width we))
9200 (macro-writeenv-close-parens we))
9208 available-space-for-obj)))
9211 (##wr-ch we #\space)
9216 (##fixnum.+ start-col ##structure-indent))
9217 (##wr-no-display we value)))))))
9219 (##wr-ch we #\space)
9220 (##wr-no-display we field-name)
9221 (##wr-ch we #\space)
9222 (##wr-no-display we value))))
9226 (macro-writeenv-level-set! we level)))))
9229 (cond ((##eq? (macro-readtable-sharing-allowed?
9230 (macro-writeenv-readtable we))
9232 (##wr-serialize we obj ##explode-structure '("#structure(" . ")")))
9237 (if (##input-port? obj)
9238 (if (##output-port? obj) 'input-output-port 'input-port)
9241 ((macro-thread? obj)
9246 (macro-thread-name obj)))
9252 (macro-mutex-name obj)))
9253 ((macro-condvar? obj)
9258 (macro-condvar-name obj)))
9259 ((macro-tgroup? obj)
9264 (macro-tgroup-name obj)))
9265 ((##type? obj);;;;;;;;;;;;;;;
9272 (case (macro-writeenv-style we)
9274 (if (##wr-mark we obj)
9275 (for-each-visible-field
9276 (lambda (field-name value last?)
9277 (##wr-no-display we field-name)
9278 (##wr-no-display we value))
9280 (##structure-type obj)
9283 (if (##wr-stamp we obj)
9284 (if (case (macro-writeenv-style we)
9286 (##not (##wr-one-line-pretty-print
9290 (wr-structure we obj)))))
9293 (wr-structure we obj))))))))
9295 (define-prim (##wr-gc-hash-table we obj)
9296 (if (##eq? (macro-readtable-sharing-allowed?
9297 (macro-writeenv-readtable we))
9299 (##wr-serialize we obj ##explode-gc-hash-table '("#gc-hash-table(" . ")"))
9306 (define-prim (##explode-gc-hash-table gcht)
9307 (##declare (not interrupts-enabled))
9308 (let loop ((i (macro-gc-hash-table-key0))
9310 (let ((len (##vector-length gcht)))
9311 (if (##fixnum.< i len)
9312 (let ((key (##vector-ref gcht i)))
9313 (if (and (##not (##eq? key (macro-unused-obj)))
9314 (##not (##eq? key (macro-deleted-obj))))
9315 (let ((val (##vector-ref gcht (##fixnum.+ i 1))))
9316 (let ((new-key-vals (##cons (##cons key val) key-vals)))
9317 (##declare (interrupts-enabled))
9318 (loop (##fixnum.+ i 2) new-key-vals)))
9320 (##declare (interrupts-enabled))
9321 (loop (##fixnum.+ i 2) key-vals))))
9323 (macro-gc-hash-table-flags gcht))
9325 (macro-gc-hash-table-count gcht))
9327 (macro-gc-hash-table-min-count gcht))
9329 (macro-gc-hash-table-free gcht)))
9330 (##declare (interrupts-enabled))
9331 (##vector len flags count min-count free key-vals))))))
9333 (define-prim (##implode-gc-hash-table re fields)
9334 (let ((len (##vector-ref fields 0))
9335 (flags (##vector-ref fields 1))
9336 (count (##vector-ref fields 2))
9337 (min-count (##vector-ref fields 3))
9338 (free (##vector-ref fields 4))
9339 (key-vals (##vector-ref fields 5)))
9340 (let ((gcht (##make-vector len (macro-unused-obj))))
9341 (macro-gc-hash-table-flags-set!
9343 (##fixnum.bitwise-ior ;; force rehash at next access!
9345 (##fixnum.+ (macro-gc-hash-table-flag-key-moved)
9346 (macro-gc-hash-table-flag-need-rehash))))
9347 (macro-gc-hash-table-count-set! gcht count)
9348 (macro-gc-hash-table-min-count-set! gcht min-count)
9349 (macro-gc-hash-table-free-set! gcht free)
9350 (let loop ((i (macro-gc-hash-table-key0))
9351 (key-vals key-vals))
9352 (if (##pair? key-vals)
9353 (if (##fixnum.< i (##vector-length gcht))
9354 (let ((key-val (##car key-vals)))
9355 (let ((key (##car key-val))
9356 (val (##cdr key-val)))
9357 (##vector-set! gcht i key)
9358 (##vector-set! gcht (##fixnum.+ i 1) val)
9359 (loop (##fixnum.+ i 2) (##cdr key-vals))))
9364 (macro-subtype-weak))
9367 (define-prim (##wr-meroon we obj)
9374 (define-prim (##wr-jazz we obj)
9381 (define-prim (##wr-frame we obj)
9382 (if (##eq? (macro-readtable-sharing-allowed?
9383 (macro-writeenv-readtable we))
9385 (##wr-serialize we obj ##explode-frame '("#frame(" . ")"))
9392 (define-prim (##wr-continuation we obj)
9393 (if (##eq? (macro-readtable-sharing-allowed?
9394 (macro-writeenv-readtable we))
9396 (##wr-serialize we obj ##explode-continuation '("#continuation(" . ")"))
9403 (define-prim (##wr-promise we obj)
9404 (if (##eq? (macro-readtable-sharing-allowed?
9405 (macro-writeenv-readtable we))
9407 (##wr-serialize we obj ##explode-promise '("#promise(" . ")"))
9408 (if (macro-writeenv-force? we)
9409 (##wr we (##force obj))
9416 (define-prim (##explode-promise obj)
9417 (##explode-object obj))
9419 (define-prim (##implode-promise re fields)
9420 (##implode-object re fields (macro-subtype-promise)))
9422 (define-prim (##wr-will we obj)
9429 (define-prim (##wr-procedure we obj)
9430 (if (##eq? (macro-readtable-sharing-allowed?
9431 (macro-writeenv-readtable we))
9433 (##wr-serialize we obj ##explode-procedure '("#procedure(" . ")"))
9438 (or (##procedure-name obj) (##void)))))
9440 (define-prim (##wr-return we obj)
9449 (define-prim (##wr-box we obj)
9450 (case (macro-writeenv-style we)
9452 (if (##wr-mark we obj)
9453 (##wr we (##unbox obj))))
9455 (if (case (macro-writeenv-style we)
9457 (else (##wr-stamp we obj)))
9460 (##wr we (##unbox obj)))))))
9462 (define-prim (##wr-other we obj)
9463 (case (macro-writeenv-style we)
9467 (cond ((##eq? obj #t)
9472 (case (macro-writeenv-style we)
9476 (##wr-str we "()"))))
9477 ((##eq? obj (macro-absent-obj))
9479 (if (##eq? (macro-readtable-sharing-allowed?
9480 (macro-writeenv-readtable we))
9487 (macro-readtable-sharp-bang-table
9488 (macro-writeenv-readtable we)))))
9492 (##wr-str we (##car x)))
9493 (##wr-str we "#<unknown>"))))))))
9495 ;;;----------------------------------------------------------------------------
9497 (define ##main-readtable #f)
9499 ;;;----------------------------------------------------------------------------
9501 ;;; IEEE Scheme procedures:
9503 (define-prim (##eof-object? x)
9506 (define-prim (eof-object? x)
9507 (macro-force-vars (x)
9510 ;;;----------------------------------------------------------------------------
9512 ;;; R4RS Scheme procedures:
9514 (define-prim (transcript-on path)
9515 (macro-check-string path 1 (transcript-on path)
9518 (define-prim (transcript-off)
9521 ;;;----------------------------------------------------------------------------
9525 (##declare (inlining-limit 300))
9527 (##define-macro (* . args) `(##fixnum.* ,@args))
9528 (##define-macro (+ . args) `(##fixnum.+ ,@args))
9529 (##define-macro (- . args) `(##fixnum.- ,@args))
9530 (##define-macro (< . args) `(##fixnum.< ,@args))
9531 (##define-macro (= . args) `(##fixnum.= ,@args))
9532 (##define-macro (assoc . args) `(##assoc ,@args))
9533 (##define-macro (assq . args) `(##assq ,@args))
9534 (##define-macro (car . args) `(##car ,@args))
9535 (##define-macro (cdr . args) `(##cdr ,@args))
9536 (##define-macro (char-downcase . args) `(##char-downcase ,@args))
9537 (##define-macro (char-upcase . args) `(##char-upcase ,@args))
9538 (##define-macro (char<? . args) `(##char<? ,@args))
9539 (##define-macro (char=? . args) `(##char=? ,@args))
9540 (##define-macro (char? . args) `(##char? ,@args))
9541 (##define-macro (cons . args) `(##cons ,@args))
9542 (##define-macro (eq? . args) `(##eq? ,@args))
9543 (##define-macro (complex? . args) `(##complex? ,@args))
9544 (##define-macro (exact? . args) `(##exact? ,@args))
9545 (##define-macro (for-each . args) `(##for-each ,@args))
9546 (##define-macro (integer? . args) `(##integer? ,@args))
9547 (##define-macro (list . args) `(##list ,@args))
9548 (##define-macro (make-string . args) `(##make-string ,@args))
9549 (##define-macro (make-vector . args) `(##make-vector ,@args))
9550 (##define-macro (map . args) `(##map ,@args))
9551 (##define-macro (modulo . args) `(##modulo ,@args))
9552 (##define-macro (not . args) `(##not ,@args))
9553 (##define-macro (null? . args) `(##null? ,@args))
9554 (##define-macro (pair? . args) `(##pair? ,@args))
9555 (##define-macro (quotient . args) `(##quotient ,@args))
9556 (##define-macro (real? . args) `(##real? ,@args))
9557 (##define-macro (reverse . args) `(##reverse ,@args))
9558 (##define-macro (box . args) `(##box ,@args))
9559 (##define-macro (set-box! . args) `(##set-box! ,@args))
9560 (##define-macro (set-car! . args) `(##set-car! ,@args))
9561 (##define-macro (set-cdr! . args) `(##set-cdr! ,@args))
9562 (##define-macro (string->number . args) `(##string->number ,@args))
9563 (##define-macro (string->symbol-object . args) `(##make-interned-symkey ,@args #t))
9564 (##define-macro (string->uninterned-symbol-object . args) `(##make-uninterned-symbol ,@args))
9565 (##define-macro (string? . args) `(##string? ,@args))
9566 (##define-macro (string-length . args) `(##string-length ,@args))
9567 (##define-macro (string-append . args) `(##string-append ,@args))
9568 (##define-macro (string-ref . args) `(##string-ref ,@args))
9569 (##define-macro (string-set! . args) `(##string-set! ,@args))
9570 (##define-macro (string=? . args) `(##string=? ,@args))
9571 (##define-macro (string-ci=? . args) `(##string-ci=? ,@args))
9572 (##define-macro (substring . args) `(##substring ,@args))
9573 (##define-macro (symbol? . args) `(##symbol? ,@args))
9574 (##define-macro (symbol->string . args) `(##symbol->string ,@args))
9575 (##define-macro (vector . args) `(##vector ,@args))
9576 (##define-macro (vector-copy . args) `(##vector-copy ,@args))
9577 (##define-macro (vector-length . args) `(##vector-length ,@args))
9578 (##define-macro (vector-ref . args) `(##vector-ref ,@args))
9579 (##define-macro (vector-set! . args) `(##vector-set! ,@args))
9580 (##define-macro (vector? . args) `(##vector? ,@args))
9582 (##define-macro (make-s8vect n) `(##make-s8vector ,n))
9583 (##define-macro (s8vect-set! . args) `(##s8vector-set! ,@args))
9584 (##define-macro (make-u8vect n) `(##make-u8vector ,n))
9585 (##define-macro (u8vect-set! . args) `(##u8vector-set! ,@args))
9586 (##define-macro (make-s16vect n) `(##make-s16vector ,n))
9587 (##define-macro (s16vect-set! . args) `(##s16vector-set! ,@args))
9588 (##define-macro (make-u16vect n) `(##make-u16vector ,n))
9589 (##define-macro (u16vect-set! . args) `(##u16vector-set! ,@args))
9590 (##define-macro (make-s32vect n) `(##make-s32vector ,n))
9591 (##define-macro (s32vect-set! . args) `(##s32vector-set! ,@args))
9592 (##define-macro (make-u32vect n) `(##make-u32vector ,n))
9593 (##define-macro (u32vect-set! . args) `(##u32vector-set! ,@args))
9594 (##define-macro (make-s64vect n) `(##make-s64vector ,n))
9595 (##define-macro (s64vect-set! . args) `(##s64vector-set! ,@args))
9596 (##define-macro (make-u64vect n) `(##make-u64vector ,n))
9597 (##define-macro (u64vect-set! . args) `(##u64vector-set! ,@args))
9598 (##define-macro (make-f32vect n) `(##make-f32vector ,n))
9599 (##define-macro (f32vect-set! . args) `(##f32vector-set! ,@args))
9600 (##define-macro (make-f64vect n) `(##make-f64vector ,n))
9601 (##define-macro (f64vect-set! . args) `(##f64vector-set! ,@args))
9603 (##define-macro (UCS-4->character . args) `(##fixnum.->char ,@args))
9604 (##define-macro (character->UCS-4 . args) `(##fixnum.<-char ,@args))
9605 (##define-macro (in-char-range? n)
9606 `(and (##not (##< ##max-char ,n))
9607 (or (##fixnum.< ,n #xd800)
9608 (##fixnum.< #xdfff ,n))))
9610 (##define-macro (string->keyword-object . args) `(##make-interned-symkey ,@args #f))
9611 (##define-macro (string->uninterned-keyword-object . args) `(##make-uninterned-keyword ,@args))
9613 (##define-macro (in-integer-range? n lo hi)
9614 `(and (##not (##< ,n ,lo)) (##not (##< ,hi ,n))))
9616 (##define-macro (false-obj) #f)
9618 ;;; Tables for reader and writer.
9620 (define ##standard-pretty-print-formats '(
9621 (lambda . #(1 #t 2 #f 1))
9622 (if . #(1 #f 0 #f 1))
9623 (set! . #(1 #f 0 #f 1))
9624 (cond . #(1 #t 0 #t 1))
9625 (case . #(1 #f 2 #t 1))
9626 (and . #(1 #f 0 #f 1))
9627 (or . #(1 #f 0 #f 1))
9628 (let . #(1 #t 2 #f 1)) ;; named let is handled in pretty printer
9629 (let* . #(1 #t 2 #f 1))
9630 (letrec . #(1 #t 2 #f 1))
9631 (begin . #(0 #f 1 #f 1))
9632 (do . #(1 #t 3 #f 1))
9633 (define . #(1 #f 2 #f 1))
9634 (##define-macro . #(1 #f 2 #f 1))
9635 (define-macro . #(1 #f 2 #f 1))
9636 (##declare . #(0 #f 1 #f 1))
9637 (declare . #(0 #f 1 #f 1))
9640 (define ##list-max-head 8)
9641 (set! ##list-max-head ##list-max-head)
9643 (define ##structure-max-head 8)
9644 (set! ##structure-max-head ##structure-max-head)
9646 (define ##structure-max-field 8)
9647 (set! ##structure-max-field ##structure-max-field)
9649 (define ##structure-indent 1)
9650 (set! ##structure-indent ##structure-indent)
9652 (define ##standard-escaped-char-table '(
9668 (define ##standard-named-char-table '(
9669 ("newline" . #\newline) ;; here to take precedence over linefeed
9673 ("backspace" . #\x08)
9675 ("linefeed" . #\x0A)
9683 (define ##standard-sharp-bang-table '(
9686 ("unbound" . #!unbound)
9687 ("unbound2" . #!unbound2)
9688 ("optional" . #!optional)
9691 ;; ("body" . #!body)
9694 ;;;============================================================================
9696 ;; For compatibility between the interpreter and compiler, this section
9697 ;; must be the same as the corresponding section in the file
9698 ;; "gsc/_source.scm" (except that ## and ** are exchanged).
9700 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9702 ;; A chartable structure is a vector-like data structure which is
9703 ;; indexed using a character.
9705 (define (##make-chartable default)
9706 (vector (make-vector 128 default) default '()))
9708 (define (##chartable-copy ct)
9709 (vector (vector-copy (vector-ref ct 0))
9711 (map (lambda (x) (cons (car x) (cdr x))) (vector-ref ct 2))))
9713 (define (##chartable-ref ct c)
9714 (let ((i (character->UCS-4 c)))
9716 (vector-ref (vector-ref ct 0) i)
9717 (let ((x (assq i (vector-ref ct 2))))
9720 (vector-ref ct 1))))))
9722 (define (##chartable-set! ct c val)
9723 (let ((i (character->UCS-4 c)))
9725 (vector-set! (vector-ref ct 0) i val)
9726 (let ((x (assq i (vector-ref ct 2))))
9729 (vector-set! ct 2 (cons (cons i val) (vector-ref ct 2))))))))
9731 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9733 ;; A readtable structure contains parsing information for the reader.
9734 ;; It indicates what action must be taken when a given character is
9737 (define (##readtable-char-delimiter? rt c)
9738 (##chartable-ref (macro-readtable-char-delimiter?-table rt) c))
9740 (define (##readtable-char-delimiter?-set! rt c delimiter?)
9741 (##chartable-set! (macro-readtable-char-delimiter?-table rt) c delimiter?))
9743 (define (##readtable-char-handler rt c)
9744 (##chartable-ref (macro-readtable-char-handler-table rt) c))
9746 (define (##readtable-char-handler-set! rt c handler)
9747 (##chartable-set! (macro-readtable-char-handler-table rt) c handler))
9749 (define (##readtable-char-sharp-handler rt c)
9750 (##chartable-ref (macro-readtable-char-sharp-handler-table rt) c))
9752 (define (##readtable-char-sharp-handler-set! rt c handler)
9753 (##chartable-set! (macro-readtable-char-sharp-handler-table rt) c handler))
9755 (define (##readtable-char-class-set! rt c delimiter? handler)
9756 (##readtable-char-delimiter?-set! rt c delimiter?)
9757 (##readtable-char-handler-set! rt c handler))
9759 (define (##readtable-convert-case rt c)
9760 (let ((case-conversion? (macro-readtable-case-conversion? rt)))
9761 (if case-conversion?
9762 (if (eq? case-conversion? 'upcase)
9767 (define (##readtable-string-convert-case! rt s)
9768 (let ((case-conversion? (macro-readtable-case-conversion? rt)))
9769 (if case-conversion?
9770 (if (eq? case-conversion? 'upcase)
9771 (let loop ((i (- (string-length s) 1)))
9774 (string-set! s i (char-upcase (string-ref s i)))
9776 (let loop ((i (- (string-length s) 1)))
9779 (string-set! s i (char-downcase (string-ref s i)))
9780 (loop (- i 1)))))))))
9782 (define (##readtable-parse-keyword rt s intern? create?)
9783 (let ((keywords-allowed? (macro-readtable-keywords-allowed? rt)))
9784 (and keywords-allowed?
9785 (let ((len (string-length s)))
9787 (if (eq? keywords-allowed? 'prefix)
9788 (and (char=? (string-ref s 0) #\:)
9790 (let ((key-str (substring s 1 len)))
9792 (string->keyword-object key-str)
9793 (string->uninterned-keyword-object key-str)))
9795 (and (char=? (string-ref s (- len 1)) #\:)
9797 (let ((key-str (substring s 0 (- len 1))))
9799 (string->keyword-object key-str)
9800 (string->uninterned-keyword-object key-str)))
9803 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9805 ;;; Procedures to read datums.
9807 ;; (##read-datum-or-eof re) attempts to read a datum in the read
9808 ;; environment "re", skipping all whitespace and comments in the
9809 ;; process. The "filepos" field of the read environment indicates the
9810 ;; position where the enclosing datum starts (e.g. list or vector). If
9811 ;; a datum is read it is returned (wrapped if the read environment asks
9812 ;; for it); if the end-of-file is reached the end-of-file object is
9813 ;; returned (never wrapped); otherwise an error is signaled. The read
9814 ;; environment's "pos" field is only modified if a datum was read, in
9815 ;; which case it is the position where the datum starts.
9817 (define (##read-datum-or-eof re)
9818 (case (macro-readtable-start-syntax (macro-readenv-readtable re))
9820 (##read-six-datum-or-eof re #t))
9823 (let* ((old-pos (macro-readenv-filepos re))
9824 (obj (##read-datum-or-label-or-none re)))
9825 (if (eq? obj (##none-marker))
9826 (let ((c (macro-peek-next-char-or-eof re)))
9829 (macro-readenv-filepos-set! re (##readenv-current-filepos re))
9830 (macro-read-next-char-or-eof re) ;; make sure reader progresses
9831 (##raise-datum-parsing-exception 'datum-or-eof-expected re)
9832 (macro-readenv-filepos-set! re old-pos) ;; restore pos
9833 (loop)) ;; skip error
9835 (macro-read-next-char-or-eof re) ;; make sure reader progresses
9836 #!eof))) ;; end-of-file was reached so return end-of-file object
9838 (##read-check-labels! re)
9841 ;; (##read-datum-or-label re) attempts to read a datum in the read
9842 ;; environment "re", skipping all whitespace and comments in the
9843 ;; process. The "filepos" field of the read environment indicates the
9844 ;; position where the enclosing datum starts (e.g. list or vector). If
9845 ;; a datum is read it is returned (wrapped if the read environment asks
9846 ;; for it); if a label reference is read (i.e. "#n#") a "label-marker"
9847 ;; is returned; if the end-of-file is reached or no datum can be read
9848 ;; an error is signaled. The read environment's "filepos" field is
9849 ;; only modified if a datum was read, in which case it is the position
9850 ;; where the datum starts.
9852 (define (##read-datum-or-label re)
9853 (let* ((old-pos (macro-readenv-filepos re))
9854 (obj (##read-datum-or-label-or-none re)))
9855 (if (eq? obj (##none-marker))
9857 (macro-readenv-filepos-set! re (##readenv-current-filepos re))
9858 (let ((c (macro-read-next-char-or-eof re))) ;; force progress
9859 (##raise-datum-parsing-exception 'datum-expected re)
9861 (macro-readenv-wrap re #f) ;; return something
9863 (macro-readenv-filepos-set! re old-pos) ;; restore pos
9864 (##read-datum-or-label re))))) ;; skip error
9867 ;; (##read-datum-or-label-or-none re) attempts to read a datum in the
9868 ;; read environment "re", skipping all whitespace and comments in the
9869 ;; process. The "filepos" field of the read environment indicates the
9870 ;; position where the enclosing datum starts (e.g. list or vector). If
9871 ;; a datum is read it is returned (wrapped if the read environment asks
9872 ;; for it); if a label reference is read (i.e. "#n#") a "label-marker"
9873 ;; is returned; if the end-of-file is reached or no datum can be read
9874 ;; the "none-marker" is returned. The read environment's "filepos"
9875 ;; field is only modified if a datum was read, in which case it is the
9876 ;; position where the datum starts.
9878 (define (##read-datum-or-label-or-none re)
9879 (let* ((old-pos (macro-readenv-filepos re))
9880 (obj (##read-datum-or-label-or-none-or-dot re)))
9881 (if (eq? obj (##dot-marker))
9883 (macro-readenv-filepos-set! re (##readenv-relative-filepos re 1))
9884 (##raise-datum-parsing-exception 'improperly-placed-dot re)
9885 (macro-readenv-filepos-set! re old-pos) ;; restore pos
9886 (##read-datum-or-label-or-none re)) ;; skip error
9889 ;; (##read-datum-or-label-or-none-or-dot re) attempts to read a datum
9890 ;; in the read environment "re", skipping all whitespace and comments
9891 ;; in the process. The "filepos" field of the read environment
9892 ;; indicates the position where the enclosing datum starts (e.g. list
9893 ;; or vector). If a datum is read it is returned (wrapped if the read
9894 ;; environment asks for it); if a label reference is read (i.e. "#n#")
9895 ;; a "label-marker" is returned; if a lone dot is read the "dot-marker"
9896 ;; is returned; if the end-of-file is reached or no datum can be read
9897 ;; the "none-marker" is returned. The read environment's "filepos"
9898 ;; field is only modified if a datum was read, in which case it is the
9899 ;; position where the datum starts.
9901 (define (##read-datum-or-label-or-none-or-dot re)
9902 (macro-readenv-allow-script?-set!
9904 (eq? (macro-readenv-allow-script? re) 'script))
9905 (let ((next (macro-peek-next-char-or-eof re)))
9907 ((##readtable-char-handler (macro-readenv-readtable re) next) re next)
9910 ;; Special objects returned by ##read-datum-or-label-or-none-or-dot.
9912 (define (##script-marker) '#(script)) ;; indicates a script
9913 (define (##none-marker) '#(none)) ;; indicates no following datum
9914 (define (##dot-marker) '#(dot)) ;; indicates an isolated dot
9915 (define ##label-marker-tag '#(label)) ;; indicates a label of the form "#n#"
9917 (define (##label-marker? obj)
9919 (< 0 (vector-length obj))
9920 (eq? (vector-ref obj 0) ##label-marker-tag)))
9922 (define (##label-marker-enter! re n)
9923 (let* ((labels (macro-readenv-labels re))
9924 (x (assoc n labels)))
9927 (let ((lm (vector ##label-marker-tag #f '())))
9928 (macro-readenv-labels-set! re (cons (cons n lm) labels))
9931 (define (##label-marker-reference re n)
9932 (let* ((lm (##label-marker-enter! re n))
9933 (handlers (vector-ref lm 2)))
9936 (vector-ref lm 1))))
9938 (define (##label-marker-fixup-handler-add! re lm handler)
9939 (let ((handlers (vector-ref lm 2)))
9945 (macro-readenv-wrapper re)
9946 (macro-readenv-filepos re)
9948 (handler (macro-readenv-wrap re (vector-ref lm 1))))))
9950 (define (##label-marker-define re n obj)
9951 (let* ((lm (##label-marker-enter! re n))
9952 (handlers (vector-ref lm 2)))
9955 (vector-set! lm 1 obj)
9956 (vector-set! lm 2 #f)
9957 (##label-marker-fixup! re handlers obj))
9958 (##raise-datum-parsing-exception 'duplicate-label-definition re n))))
9960 (define (##label-marker-fixup! re handlers obj)
9961 (let loop ((lst handlers))
9963 (let* ((handler (vector-ref lst 0))
9964 (wrapper (vector-ref lst 1))
9965 (filepos (vector-ref lst 2))
9966 (old-wrapper (macro-readenv-wrapper re))
9967 (old-filepos (macro-readenv-filepos re)))
9968 (macro-readenv-wrapper-set! re wrapper)
9969 (macro-readenv-filepos-set! re filepos)
9970 (handler (macro-readenv-wrap re obj))
9971 (macro-readenv-wrapper-set! re old-wrapper)
9972 (macro-readenv-filepos-set! re old-filepos)
9973 (loop (vector-ref lst 3))))))
9975 (define (##read-check-labels! re)
9976 (let loop1 ((lst (macro-readenv-labels re)))
9978 (let* ((x (car lst))
9980 (let ((handlers (vector-ref lm 2)))
9983 (##label-marker-fixup! re handlers (##void))
9984 (##raise-datum-parsing-exception
9985 'missing-label-definition
9988 (loop1 (cdr lst))))))
9990 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9992 ;;; Procedure to read a list of datums (possibly an improper list).
9994 (define (##build-list re allow-improper? start-pos close)
9995 (let ((obj (##read-datum-or-label-or-none re)))
9996 (if (eq? obj (##none-marker))
9998 (##read-next-char-expecting re close)
10001 (macro-readenv-filepos-set! re start-pos) ;; restore pos
10002 (let ((lst (cons obj '())))
10003 (if (##label-marker? obj)
10004 (##label-marker-fixup-handler-add!
10007 (lambda (resolved-obj)
10008 (set-car! lst resolved-obj))))
10009 (let loop ((end lst))
10011 (if allow-improper?
10012 (##read-datum-or-label-or-none-or-dot re)
10013 (##read-datum-or-label-or-none re))))
10014 (cond ((eq? obj (##none-marker))
10015 (##read-next-char-expecting re close)
10017 ((eq? obj (##dot-marker))
10018 (let ((obj (##read-datum-or-label re)))
10019 (macro-readenv-filepos-set! re start-pos) ;; restore pos
10021 (if (##label-marker? obj)
10022 (##label-marker-fixup-handler-add!
10025 (lambda (resolved-obj)
10026 (set-cdr! end resolved-obj))))
10027 (let ((x (##read-datum-or-label-or-none re))) ;; skip whitespace!
10028 (if (eq? x (##none-marker))
10029 (##read-next-char-expecting re close)
10031 (macro-readenv-filepos-set! re start-pos) ;; restore pos
10032 (##raise-datum-parsing-exception 'incomplete-form re)))
10035 (macro-readenv-filepos-set! re start-pos) ;; restore pos
10036 (let ((tail (cons obj '())))
10037 (if (##label-marker? obj)
10038 (##label-marker-fixup-handler-add!
10041 (lambda (resolved-obj)
10042 (set-car! tail resolved-obj))))
10043 (set-cdr! end tail)
10044 (loop tail)))))))))))
10046 (define (##read-next-char-expecting re c) ;; only accepts c as the next char
10047 (let ((next (macro-peek-next-char-or-eof re)))
10049 (if (char=? next c)
10050 (macro-read-next-char-or-eof re)
10051 (##raise-datum-parsing-exception 'incomplete-form re))
10052 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re))))
10054 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10056 ;;; Procedure to read a vector or byte vector.
10058 (define (##build-vector re kind start-pos close)
10060 (define (exact-integer-check n lo hi)
10063 (in-integer-range? n lo hi)))
10065 (define (inexact-real-check n)
10070 (macro-readenv-filepos-set! re start-pos) ;; restore pos
10071 (let ((x (##read-datum-or-label-or-none re)))
10072 (if (eq? x (##none-marker))
10074 (##read-next-char-expecting re close)
10076 ((s8vector) (make-s8vect i))
10077 ((u8vector) (make-u8vect i))
10078 ((s16vector) (make-s16vect i))
10079 ((u16vector) (make-u16vect i))
10080 ((s32vector) (make-s32vect i))
10081 ((u32vector) (make-u32vect i))
10082 ((s64vector) (make-s64vect i))
10083 ((u64vector) (make-u64vect i))
10084 ((f32vector) (make-f32vect i))
10085 ((f64vector) (make-f64vect i))
10086 (else (make-vector i))))
10087 (if (or (eq? kind 'deserialize)
10088 (eq? kind 'vector))
10089 (let ((vect (loop (+ i 1))))
10090 (vector-set! vect i x)
10091 (if (and (##not (eq? kind 'deserialize))
10092 (##label-marker? x))
10093 (##label-marker-fixup-handler-add!
10094 re;;;;;;;;;;;;;;;;;;;;;;;;
10096 (lambda (resolved-obj)
10097 (vector-set! vect i resolved-obj))))
10100 (and (not (##label-marker? x))
10101 (macro-readenv-unwrap re x))))
10104 (if (exact-integer-check ux -128 127)
10105 (let ((vect (loop (+ i 1))))
10106 (s8vect-set! vect i ux)
10109 (##raise-datum-parsing-exception 's8-expected re)
10112 (if (exact-integer-check ux 0 255)
10113 (let ((vect (loop (+ i 1))))
10114 (u8vect-set! vect i ux)
10117 (##raise-datum-parsing-exception 'u8-expected re)
10120 (if (exact-integer-check ux -32768 32767)
10121 (let ((vect (loop (+ i 1))))
10122 (s16vect-set! vect i ux)
10125 (##raise-datum-parsing-exception 's16-expected re)
10128 (if (exact-integer-check ux 0 65535)
10129 (let ((vect (loop (+ i 1))))
10130 (u16vect-set! vect i ux)
10133 (##raise-datum-parsing-exception 'u16-expected re)
10136 (if (exact-integer-check ux -2147483648 2147483647)
10137 (let ((vect (loop (+ i 1))))
10138 (s32vect-set! vect i ux)
10141 (##raise-datum-parsing-exception 's32-expected re)
10144 (if (exact-integer-check ux 0 4294967295)
10145 (let ((vect (loop (+ i 1))))
10146 (u32vect-set! vect i ux)
10149 (##raise-datum-parsing-exception 'u32-expected re)
10152 (if (exact-integer-check ux -9223372036854775808 9223372036854775807)
10153 (let ((vect (loop (+ i 1))))
10154 (s64vect-set! vect i ux)
10157 (##raise-datum-parsing-exception 's64-expected re)
10160 (if (exact-integer-check ux 0 18446744073709551615)
10161 (let ((vect (loop (+ i 1))))
10162 (u64vect-set! vect i ux)
10165 (##raise-datum-parsing-exception 'u64-expected re)
10168 (if (inexact-real-check ux)
10169 (let ((vect (loop (+ i 1))))
10170 (f32vect-set! vect i ux)
10173 (##raise-datum-parsing-exception 'inexact-real-expected re)
10176 (if (inexact-real-check ux)
10177 (let ((vect (loop (+ i 1))))
10178 (f64vect-set! vect i ux)
10181 (##raise-datum-parsing-exception 'inexact-real-expected re)
10184 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10186 ;;; Procedures to read delimited tokens.
10188 (define (##build-delimited-string re c i)
10190 (let ((next (macro-peek-next-char-or-eof re)))
10191 (if (or (not (char? next))
10192 (##readtable-char-delimiter? (macro-readenv-readtable re) next))
10195 (macro-read-next-char-or-eof re) ;; skip "next"
10196 (let ((s (loop (+ i 1))))
10197 (string-set! s i next)
10200 (define (##build-delimited-number/keyword/symbol re c intern?)
10202 (define (string->sym str)
10204 (string->symbol-object str)
10205 (string->uninterned-symbol-object str)))
10207 (define (string->key str)
10209 (string->keyword-object str)
10210 (string->uninterned-keyword-object str)))
10212 (cond ((char=? c #\|)
10214 (##build-escaped-string-up-to re #\|))
10216 (macro-readtable-keywords-allowed?
10217 (macro-readenv-readtable re))))
10218 (if (and keywords-allowed?
10219 (not (eq? keywords-allowed? 'prefix))
10220 (eq? (macro-peek-next-char-or-eof re) #\:))
10222 (macro-read-next-char-or-eof re) ;; skip #\:
10224 (string->sym str))))
10225 ((and (char=? c #\:)
10226 (let ((keywords-allowed?
10227 (macro-readtable-keywords-allowed?
10228 (macro-readenv-readtable re))))
10229 (eq? keywords-allowed? 'prefix))
10230 (eq? (macro-peek-next-char-or-eof re) #\|))
10231 (macro-read-next-char-or-eof re) ;; skip #\|
10233 (##build-escaped-string-up-to re #\|)))
10234 (string->key str)))
10236 (##string->number/keyword/symbol
10238 (##build-delimited-string re c 1)
10241 (define (##string->number/keyword/symbol re str intern?)
10243 (define (string->sym str)
10245 (string->symbol-object str)
10246 (string->uninterned-symbol-object str)))
10248 (or (and intern? (string->number str 10))
10250 (##readtable-string-convert-case!
10251 (macro-readenv-readtable re)
10253 (or (##readtable-parse-keyword
10254 (macro-readenv-readtable re)
10258 (string->sym str)))))
10260 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10262 (define (##char-octal? c)
10263 (if (and (not (char<? c #\0)) (not (char<? #\7 c)))
10264 (- (character->UCS-4 c) (character->UCS-4 #\0))
10267 (define (##char-hexadecimal? c)
10268 (cond ((and (not (char<? c #\0)) (not (char<? #\9 c)))
10269 (- (character->UCS-4 c) (character->UCS-4 #\0)))
10270 ((and (not (char<? c #\a)) (not (char<? #\f c)))
10271 (- (character->UCS-4 c) (- (character->UCS-4 #\a) 10)))
10272 ((and (not (char<? c #\A)) (not (char<? #\F c)))
10273 (- (character->UCS-4 c) (- (character->UCS-4 #\A) 10)))
10277 (define (##build-escaped-string-up-to re close)
10280 (if (in-char-range? n)
10281 (UCS-4->character n)
10283 (##raise-datum-parsing-exception 'character-out-of-range re)
10286 (define (read-escape-octal first-digit)
10289 (let ((next (macro-peek-next-char-or-eof re)))
10290 (cond ((and (or (< i 2)
10291 (and (= i 2) (< first-digit 4)))
10293 (##char-octal? next))
10295 (lambda (next-digit)
10296 (macro-read-next-char-or-eof re) ;; skip "next"
10298 (+ (* n 8) next-digit))))
10302 (define (read-escape-hexadecimal nb-digits)
10305 (if (or (not nb-digits)
10307 (let ((next (macro-peek-next-char-or-eof re)))
10308 (cond ((and (char? next)
10309 (##char-hexadecimal? next))
10311 (lambda (next-digit)
10312 (macro-read-next-char-or-eof re) ;; skip "next"
10314 (if (< n ##max-char)
10315 (+ (* n 16) next-digit)
10320 (##raise-datum-parsing-exception 'invalid-hex-escape re)
10325 (define (read-escape next)
10326 (cond ((not (char? next))
10327 ;; read-chunk will report the end-of-file error
10329 ((##char-octal? next)
10333 (read-escape-hexadecimal #f))
10335 (read-escape-hexadecimal 4))
10337 (read-escape-hexadecimal 8))
10339 (let ((x (assq next
10340 (macro-readtable-escaped-char-table
10341 (macro-readenv-readtable re)))))
10345 (##raise-datum-parsing-exception 'invalid-escaped-character re next)
10348 (define max-chunk-length 512)
10350 (define (read-chunk)
10352 (if (< i max-chunk-length)
10353 (let loop2 ((c (macro-read-next-char-or-eof re)))
10354 (cond ((not (char? c))
10355 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re)
10360 (let ((next (macro-read-next-char-or-eof re)))
10361 (if (eq? next #\newline)
10363 (let ((c (macro-read-next-char-or-eof re)))
10365 (not (eq? c #\newline))
10366 (eq? (##readtable-char-handler
10367 (macro-readenv-readtable re)
10369 ##read-whitespace))
10372 (let* ((c (read-escape next))
10373 (s (loop1 (+ i 1))))
10374 (string-set! s i c)
10377 (let ((s (loop1 (+ i 1))))
10378 (string-set! s i c)
10382 (let ((chunk1 (read-chunk)))
10383 (if (< (string-length chunk1) max-chunk-length)
10385 (let loop ((chunks (list chunk1)))
10386 (let* ((new-chunk (read-chunk))
10387 (new-chunks (cons new-chunk chunks)))
10388 (if (< (string-length new-chunk) max-chunk-length)
10389 (##append-strings (reverse new-chunks))
10390 (loop new-chunks)))))))
10392 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10394 (define (##build-decimal-integer re c i)
10396 (let ((next (macro-peek-next-char-or-eof re)))
10397 (if (or (not (char? next))
10398 (let ((n (character->UCS-4 next)))
10399 (not (and (< 47 n) (< n 58)))))
10402 (macro-read-next-char-or-eof re) ;; skip "next"
10403 (let ((s (loop (+ i 1))))
10404 (string-set! s i next)
10407 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10409 (define (##build-read-macro re start-pos old-pos kind)
10411 (let ((obj (##read-datum-or-label re)))
10412 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10413 (let* ((cell2 (cons obj '()))
10414 (cell1 (cons (macro-readenv-wrap re kind) cell2)))
10415 (if (##label-marker? obj)
10416 (##label-marker-fixup-handler-add!
10419 (lambda (resolved-obj)
10420 (set-car! cell2 resolved-obj))))
10421 (macro-readenv-wrap re cell1)))
10423 (##raise-datum-parsing-exception 'invalid-token re)
10424 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10425 (##read-datum-or-label-or-none-or-dot re)))) ;; skip error
10427 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10429 ;;; Procedures to handle comments.
10431 (define (##skip-extended-comment re open1 open2 close1 close2)
10432 (let loop1 ((level 0))
10433 (let ((c (macro-read-next-char-or-eof re)))
10434 (if (not (char? c))
10435 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re)
10436 (let loop2 ((level level) (c c))
10437 (if (or (char=? c open1) (char=? c close1))
10438 (let ((x (macro-read-next-char-or-eof re)))
10439 (if (not (char? x))
10440 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re)
10441 (if (char=? c open1)
10442 (if (char=? x open2)
10443 (loop1 (+ level 1))
10445 (if (char=? x close2)
10447 (loop1 (- level 1))
10448 #f) ;; comment has ended
10449 (loop2 level x)))))
10450 (loop1 level)))))))
10452 (define (##skip-single-line-comment re)
10454 (let ((next (macro-peek-next-char-or-eof re)))
10457 (macro-read-next-char-or-eof re) ;; skip "next"
10458 (if (not (char=? next #\newline))
10461 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10463 ;;; Procedure to read datums starting with '#'.
10465 (define (##read-sharp re c)
10466 (let ((start-pos (##readenv-current-filepos re)))
10467 (macro-read-next-char-or-eof re) ;; skip #\#
10468 (##read-sharp-aux re start-pos)))
10470 (define (##read-sharp-aux re start-pos)
10471 (let ((next (macro-peek-next-char-or-eof re)))
10473 ((##readtable-char-sharp-handler (macro-readenv-readtable re) next)
10477 (##read-sharp-other
10482 (define (##read-sharp-vector re next start-pos)
10483 (macro-read-next-char-or-eof re) ;; skip char after #\#
10484 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10485 (let ((vect (##build-vector re 'vector start-pos #\))))
10486 (macro-readenv-wrap re vect)))
10488 (define (##read-sharp-char re next start-pos)
10489 (let ((old-pos (macro-readenv-filepos re)))
10490 (macro-read-next-char-or-eof re) ;; skip char after #\#
10491 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10492 (let ((c (macro-read-next-char-or-eof re)))
10493 (cond ((not (char? c))
10494 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re)
10495 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10496 (##read-datum-or-label-or-none-or-dot re)) ;; skip error
10497 ((eq? (##readtable-char-handler (macro-readenv-readtable re) c)
10499 (macro-readenv-wrap re c))
10501 (let ((next (macro-peek-next-char-or-eof re)))
10502 (if (or (not (char? next))
10503 (##readtable-char-delimiter?
10504 (macro-readenv-readtable re)
10506 (macro-readenv-wrap re c)
10507 (let ((name (##build-delimited-string re c 1)))
10509 (define (read-hex nb-digits)
10510 (and (or (not nb-digits)
10511 (= (- (string-length name) 1) nb-digits))
10514 (cond ((= i (string-length name))
10516 ((##char-hexadecimal? (string-ref name i))
10518 (lambda (next-digit)
10520 (if (< n ##max-char)
10521 (+ (* n 16) next-digit)
10527 (if (not (in-char-range? n))
10529 (##raise-datum-parsing-exception
10530 'character-out-of-range
10532 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10533 (##read-datum-or-label-or-none-or-dot re)) ;; skip error
10534 (macro-readenv-wrap re (UCS-4->character n))))
10536 (define (invalid-character-name-error)
10537 (##raise-datum-parsing-exception
10538 'invalid-character-name
10541 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10542 (##read-datum-or-label-or-none-or-dot re)) ;; skip error
10544 (or (cond ((char=? c #\x)
10550 #; ;; disable old #\#x1234 character syntax
10552 (let ((n (string->number name 10)))
10560 (##read-assoc-string=?
10563 (macro-readtable-named-char-table
10564 (macro-readenv-readtable re)))))
10566 (macro-readenv-wrap re (cdr x))
10567 (invalid-character-name-error))))))))))))
10569 (define (##read-sharp-comment re next start-pos)
10570 (let ((old-pos (macro-readenv-filepos re)))
10571 (macro-readenv-filepos-set! re start-pos) ;; in case error in comment
10572 (macro-read-next-char-or-eof re) ;; skip char after #\#
10573 (##skip-extended-comment re #\# next next #\#)
10574 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10575 (##read-datum-or-label-or-none-or-dot re))) ;; read what follows comment
10577 (define (##read-sharp-bang re next start-pos)
10578 (let ((old-pos (macro-readenv-filepos re)))
10579 (macro-read-next-char-or-eof re) ;; skip char after #\#
10580 (if (macro-readenv-allow-script? re)
10583 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10584 (let ((name (##build-delimited-string re #\space 0)))
10586 (##read-assoc-string=?
10589 (macro-readtable-sharp-bang-table
10590 (macro-readenv-readtable re)))))
10592 (macro-readenv-wrap re (cdr x))
10594 (##raise-datum-parsing-exception 'invalid-sharp-bang-name re name)
10595 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10596 (##read-datum-or-label-or-none-or-dot re))))))))) ;; skip error
10598 (define (##read-sharp-keyword/symbol re next start-pos)
10599 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10600 (let ((str (##build-delimited-string re #\# 1)))
10601 (let ((n (string-length str)))
10602 (let loop ((i (- n 1)))
10606 (macro-readtable-sharp-seq-keyword
10607 (macro-readenv-readtable re))
10609 ((char=? #\# (string-ref str i))
10612 (let ((obj (##string->number/keyword/symbol re str #t)))
10613 (macro-readenv-wrap re obj))))))))
10615 (define (##read-sharp-colon re next start-pos)
10616 (let ((old-pos (macro-readenv-filepos re)))
10617 (macro-read-next-char-or-eof re) ;; skip char after #\#
10618 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10619 (let ((c (macro-read-next-char-or-eof re)))
10621 (let ((obj (##build-delimited-number/keyword/symbol re c #f)))
10622 (macro-readenv-wrap re obj))
10624 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re)
10625 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10626 (##read-datum-or-label-or-none-or-dot re)))))) ;; skip error
10628 (define (##read-sharp-semicolon re next start-pos)
10629 (let ((old-pos (macro-readenv-filepos re)))
10630 (macro-read-next-char-or-eof re) ;; skip char after #\#
10631 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10632 (let ((obj (##read-datum-or-label re)))
10633 (if (##label-marker? obj)
10634 (##label-marker-fixup-handler-add!
10637 (lambda (resolved-obj)
10639 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10640 (##read-datum-or-label-or-none-or-dot re)))) ;; read what follows comment
10642 (define (##read-sharp-quotation re next start-pos)
10643 (let ((old-pos (macro-readenv-filepos re)))
10644 (macro-read-next-char-or-eof re) ;; skip #\' or #\` or #\,
10645 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10647 (cond ((eq? next #\,)
10648 (let ((after-comma (macro-peek-next-char-or-eof re)))
10649 (if (eq? after-comma #\@)
10651 (macro-read-next-char-or-eof re) ;; skip #\@
10652 (macro-readtable-sharp-unquote-splicing-keyword
10653 (macro-readenv-readtable re)))
10654 (macro-readtable-sharp-unquote-keyword
10655 (macro-readenv-readtable re)))))
10657 (macro-readtable-sharp-quasiquote-keyword
10658 (macro-readenv-readtable re)))
10660 (macro-readtable-sharp-quote-keyword
10661 (macro-readenv-readtable re))))))
10662 (##build-read-macro re start-pos old-pos keyword))))
10664 (define (##read-sharp-ampersand re next start-pos)
10665 (macro-read-next-char-or-eof re) ;; skip char after #\#
10666 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10667 (let ((obj (##read-datum-or-label re)))
10668 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10669 (let ((b (box obj)))
10670 (if (##label-marker? obj)
10671 (##label-marker-fixup-handler-add!
10674 (lambda (resolved-obj)
10675 (set-box! b resolved-obj))))
10676 (macro-readenv-wrap re b))))
10678 (define (##read-sharp-dot re next start-pos)
10679 (if (not (macro-readtable-eval-allowed? (macro-readenv-readtable re)))
10681 (##raise-datum-parsing-exception 'invalid-token re)
10682 (##read-datum-or-label-or-none-or-dot re)) ;; skip error
10684 (macro-read-next-char-or-eof re) ;; skip char after #\#
10686 (##read-expr-from-port
10687 (macro-readenv-port re)))
10690 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10691 (macro-readenv-wrap re val)))))
10693 (define-prim (##read-sharp-less re next start-pos)
10696 (##raise-datum-parsing-exception 'incomplete-form-eof-reached re))
10698 (define (invalid-token)
10699 (##raise-datum-parsing-exception 'invalid-token re))
10701 (macro-read-next-char-or-eof re) ;; skip char after #\#
10702 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10703 (if (macro-readtable-here-strings-allowed?
10704 (macro-readenv-readtable re))
10705 (let ((separator (macro-read-next-char-or-eof re)))
10706 (cond ((not (char? separator))
10708 ((eq? separator #\<)
10709 ;; Multiline SCSH here string of the form
10714 (##read-line (macro-readenv-port re) #\newline #t ##max-fixnum)))
10715 (let loop ((lines-rev '()))
10717 (##read-line (macro-readenv-port re) #\newline #t ##max-fixnum)))
10719 (if (string=? line tag)
10721 (##append-strings (##reverse lines-rev)))
10723 (string-length str)))
10725 (##string-shrink! str (- len 1)))
10726 (macro-readenv-wrap re str))
10727 (loop (cons line lines-rev)))
10729 ((eq? (macro-readtable-here-strings-allowed?
10730 (macro-readenv-readtable re))
10732 ;; Delimited here string of the form #<|foo|
10734 (##read-line (macro-readenv-port re) separator #t ##max-fixnum)))
10736 (let ((len (string-length str)))
10738 (eq? (string-ref str (- len 1)) separator))
10740 (##string-shrink! str (- len 1))
10741 (macro-readenv-wrap re str))
10744 ((invalid-token))))
10747 (define (##read-sharp-digit re next start-pos)
10748 (let ((old-pos (macro-readenv-filepos re)))
10749 (macro-read-next-char-or-eof re) ;; skip char after #\#
10750 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10751 (let ((s (##build-decimal-integer re next 2)))
10752 (string-set! s 0 #\0)
10753 (let* ((n (string->number s 10))
10754 (c (macro-peek-next-char-or-eof re)))
10755 (cond ((or (and (not (eq? c #\#))
10757 (not (macro-readtable-sharing-allowed?
10758 (macro-readenv-readtable re))))
10761 (macro-readtable-sharp-num-keyword
10762 (macro-readenv-readtable re))
10765 (macro-read-next-char-or-eof re) ;; skip #\#
10766 (##label-marker-reference re n))
10768 (macro-read-next-char-or-eof re) ;; skip #\=
10769 (let ((obj (##read-datum-or-label re)))
10770 (if (##label-marker? obj)
10772 (##raise-datum-parsing-exception
10773 'illegal-label-definition
10777 (let ((uobj (macro-readenv-unwrap re obj)))
10778 (##label-marker-define re n uobj)
10781 (define (##wrap re pos datum)
10782 (let ((old-pos (macro-readenv-filepos re)))
10783 (macro-readenv-filepos-set! re pos)
10784 (let ((x (macro-readenv-wrap re datum)))
10785 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10788 (define (##wrap-op re pos op args)
10789 (##wrap re pos (cons (##wrap re pos op) args)))
10791 (define (##wrap-op0 re pos op)
10792 (##wrap-op re pos op '()))
10794 (define (##wrap-op1 re pos op arg1)
10795 (##wrap-op re pos op (list arg1)))
10797 (define (##wrap-op1* re pos op arg1)
10798 (##wrap-op re pos op (list (##wrap re pos arg1))))
10800 (define (##wrap-op2 re pos op arg1 arg2)
10801 (##wrap-op re pos op (list arg1 arg2)))
10803 (define (##wrap-op3 re pos op arg1 arg2 arg3)
10804 (##wrap-op re pos op (list arg1 arg2 arg3)))
10806 (define (##wrap-op4 re pos op arg1 arg2 arg3 arg4)
10807 (##wrap-op re pos op (list arg1 arg2 arg3 arg4)))
10809 (define (##read-sharp-other re next start-pos)
10810 (let ((old-pos (macro-readenv-filepos re)))
10811 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10813 (##build-delimited-string re #\# 1))
10815 (string->number s 10)))
10818 (macro-readenv-wrap re num)
10822 (define (build-vect re kind)
10823 (let ((c (macro-read-next-char-or-eof re)))
10825 (macro-readenv-wrap re (##build-vector re kind start-pos #\)))
10827 (##raise-datum-parsing-exception 'open-paren-expected re)
10828 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10829 (##read-datum-or-label-or-none-or-dot re))))) ;; skip error
10831 (define (deserialize re implode);;;;;;;;;;;;;;;;;;;;;;;;;;;;
10832 (let ((c (macro-read-next-char-or-eof re)))
10834 (let* ((old-wrapper (macro-readenv-wrapper re))
10835 (old-unwrapper (macro-readenv-unwrapper re)))
10836 (macro-readenv-wrapper-set! re (lambda (re x) x))
10837 (macro-readenv-unwrapper-set! re (lambda (re x) x))
10839 (##build-vector re 'deserialize start-pos #\)))
10841 (implode re fields)))
10842 (macro-readenv-wrapper-set! re old-wrapper)
10843 (macro-readenv-unwrapper-set! re old-unwrapper)
10845 (macro-readenv-wrap re obj)
10848 (##raise-datum-parsing-exception 'open-paren-expected re)
10849 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10850 (##read-datum-or-label-or-none-or-dot re))))) ;; skip error
10852 (##raise-datum-parsing-exception 'open-paren-expected re)
10853 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10854 (##read-datum-or-label-or-none-or-dot re))))) ;; skip error
10856 (cond ((##read-string=? re s "#f")
10857 (macro-readenv-wrap re (false-obj)))
10858 ((##read-string=? re s "#t")
10859 (macro-readenv-wrap re #t))
10860 ((##read-string=? re s "#s8")
10861 (build-vect re 's8vector))
10862 ((##read-string=? re s "#u8")
10863 (build-vect re 'u8vector))
10864 ((##read-string=? re s "#s16")
10865 (build-vect re 's16vector))
10866 ((##read-string=? re s "#u16")
10867 (build-vect re 'u16vector))
10868 ((##read-string=? re s "#s32")
10869 (build-vect re 's32vector))
10870 ((##read-string=? re s "#u32")
10871 (build-vect re 'u32vector))
10872 ((##read-string=? re s "#s64")
10873 (build-vect re 's64vector))
10874 ((##read-string=? re s "#u64")
10875 (build-vect re 'u64vector))
10876 ((##read-string=? re s "#f32")
10877 (build-vect re 'f32vector))
10878 ((##read-string=? re s "#f64")
10879 (build-vect re 'f64vector))
10880 ((##read-string=? re s "#structure")
10881 (deserialize re ##implode-structure))
10882 ((##read-string=? re s "#gc-hash-table")
10883 (deserialize re ##implode-gc-hash-table))
10884 ((##read-string=? re s "#frame")
10885 (deserialize re ##implode-frame))
10886 ((##read-string=? re s "#continuation")
10887 (deserialize re ##implode-continuation))
10888 ((##read-string=? re s "#procedure")
10889 (deserialize re ##implode-procedure))
10890 ((##read-string=? re s "#return")
10891 (deserialize re ##implode-return))
10892 ((##read-string=? re s "#promise")
10893 (deserialize re ##implode-promise))
10894 ((##read-string=? re s "#absent")
10897 (macro-absent-obj)))
10898 ((##read-string=? re s "#")
10901 (macro-readtable-sharp-seq-keyword
10902 (macro-readenv-readtable re))
10905 (##raise-datum-parsing-exception 'invalid-token re)
10906 (macro-readenv-filepos-set! re old-pos) ;; restore pos
10907 (##read-datum-or-label-or-none-or-dot re)))))))) ;; skip error
10909 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10911 (define (##read-whitespace re c)
10912 (macro-read-next-char-or-eof re) ;; skip whitespace character
10913 (##read-datum-or-label-or-none-or-dot re)) ;; read what follows whitespace
10915 (define (##read-single-line-comment re c)
10916 (##skip-single-line-comment re) ;; skip comment
10917 (##read-datum-or-label-or-none-or-dot re)) ;; read what follows comment
10919 (define (##read-escaped-string re c)
10920 (let ((start-pos (##readenv-current-filepos re)))
10921 (macro-read-next-char-or-eof re) ;; skip #\"
10922 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10923 (let ((str (##build-escaped-string-up-to re c)))
10924 (macro-readenv-wrap re str))))
10926 (define (##read-quotation re c)
10927 (let* ((old-pos (macro-readenv-filepos re))
10928 (start-pos (##readenv-current-filepos re)))
10929 (macro-read-next-char-or-eof re) ;; skip #\' or #\` or #\,
10930 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10933 (let ((after-comma (macro-peek-next-char-or-eof re)))
10934 (if (eq? after-comma #\@)
10936 (macro-read-next-char-or-eof re) ;; skip #\@
10937 (macro-readtable-unquote-splicing-keyword
10938 (macro-readenv-readtable re)))
10939 (macro-readtable-unquote-keyword
10940 (macro-readenv-readtable re)))))
10942 (macro-readtable-quasiquote-keyword
10943 (macro-readenv-readtable re)))
10945 (macro-readtable-quote-keyword
10946 (macro-readenv-readtable re))))))
10947 (##build-read-macro re start-pos old-pos keyword))))
10949 (define (##closing-parenthesis-for c)
10950 (cond ((char=? c #\[) #\])
10951 ((char=? c #\{) #\})
10952 ((char=? c #\<) #\>)
10955 (define (##read-vector-or-list re c)
10956 (if (macro-readtable-r6rs-compatible-read?
10957 (macro-readenv-readtable re))
10959 (##read-vector re c)))
10961 (define (##read-list re c)
10962 (let ((start-pos (##readenv-current-filepos re)))
10963 (macro-read-next-char-or-eof re) ;; skip #\( or #\[ or #\{ or #\<
10964 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10965 (let* ((close (##closing-parenthesis-for c))
10966 (lst (##build-list re #t start-pos close)))
10968 (define (prefix keyword)
10969 (macro-readenv-wrap
10971 (cons (macro-readenv-wrap re keyword) lst)))
10973 (cond ((and (char=? c #\[)
10974 (macro-readtable-bracket-keyword
10975 (macro-readenv-readtable re)))
10978 ((and (char=? c #\{)
10979 (macro-readtable-brace-keyword
10980 (macro-readenv-readtable re)))
10983 ((and (char=? c #\<)
10984 (macro-readtable-angle-keyword
10985 (macro-readenv-readtable re)))
10988 ((macro-readtable-paren-keyword
10989 (macro-readenv-readtable re))
10993 (macro-readenv-wrap re lst))))))
10995 (define (##read-vector re c)
10996 (let ((start-pos (##readenv-current-filepos re)))
10997 (macro-read-next-char-or-eof re) ;; skip #\( or #\[ or #\{ or #\<
10998 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
10999 (let* ((close (##closing-parenthesis-for c))
11000 (v (##build-vector re 'vector start-pos close)))
11001 (macro-readenv-wrap re v))))
11003 (define (##read-other re c)
11004 (##read-list re c))
11006 (define (##read-none re c)
11009 (define (##read-illegal re c)
11010 (let* ((old-pos (macro-readenv-filepos re))
11011 (start-pos (##readenv-current-filepos re)))
11012 (macro-read-next-char-or-eof re) ;; skip illegal character
11013 (macro-readenv-filepos-set! re start-pos) ;; set pos to illegal char
11014 (##raise-datum-parsing-exception 'illegal-character re c)
11015 (macro-readenv-filepos-set! re old-pos) ;; restore pos
11016 (##read-datum-or-label-or-none-or-dot re))) ;; skip error
11018 (define (##read-dot re c)
11019 (let ((start-pos (##readenv-current-filepos re)))
11020 (macro-read-next-char-or-eof re) ;; skip #\.
11021 (let ((next (macro-peek-next-char-or-eof re)))
11022 (if (or (not (char? next))
11023 (##readtable-char-delimiter? (macro-readenv-readtable re) next))
11026 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
11027 (let ((obj (##build-delimited-number/keyword/symbol re c #t)))
11028 (macro-readenv-wrap re obj)))))))
11030 (define (##read-number/keyword/symbol re c)
11031 (let ((start-pos (##readenv-current-filepos re)))
11032 (macro-read-next-char-or-eof re) ;; skip "c"
11033 (if (and (char=? c #\@)
11034 (macro-readenv-allow-script? re)
11035 (eq? (macro-peek-next-char-or-eof re) #\;))
11037 (macro-read-next-char-or-eof re) ;; skip #\;
11040 (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum
11041 (let ((obj (##build-delimited-number/keyword/symbol re c #t)))
11042 (macro-readenv-wrap re obj))))))
11044 (define (##read-assoc-string=? re x lst)
11045 (let loop ((lst lst))
11047 (let ((couple (car lst)))
11048 (let ((y (car couple)))
11049 (if (##read-string=? re x y)
11051 (loop (cdr lst)))))
11054 (define (##read-string=? re str1 str2)
11055 (let ((case-conversion?
11056 (macro-readtable-case-conversion?
11057 (macro-readenv-readtable re))))
11058 (if case-conversion?
11059 (string-ci=? str1 str2)
11060 (string=? str1 str2))))
11062 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11064 ;;; Scheme infix extension (SIX) parser.
11066 (define (##read-six re c)
11067 (macro-read-next-char-or-eof re) ;; skip backslash
11068 (##read-six-datum-or-eof re #f))
11070 (define (##read-six-datum-or-eof re allow-eof?)
11072 (##define-macro (define-six-token name . params)
11076 (##define-macro (define-six-op
11081 `(define-six-token ,name
11082 ,(+ (* precedence 2) (if (eq? associativity 'lr) 0 1))
11087 (< 1 (vector-length x))))
11089 (define (precedence op)
11090 (quotient (vector-ref op 0) 2))
11092 (define (left-to-right? op)
11093 (= (modulo (vector-ref op 0) 2) 0))
11095 (define (binary-or-ternary? op)
11098 (define (ternary? tok)
11099 (cond ((eq? tok op.?)
11104 (define (unary-prefix? op)
11105 (and (< 2 (vector-length op))
11106 (vector-ref op 2)))
11108 (define (unary-postfix? op)
11109 (and (< 3 (vector-length op))
11110 (vector-ref op 3)))
11112 (define-six-token |token.(| -1)
11113 (define-six-token |token.)| -2)
11114 (define-six-token |token.->| -3)
11115 (define-six-token |token..| -4)
11116 (define-six-token |token...| -5)
11117 (define-six-token |token.;| -6)
11118 (define-six-token |token.[| -7)
11119 (define-six-token |token.\\| -8)
11120 (define-six-token |token.]| -9)
11121 (define-six-token |token.{| -10)
11122 (define-six-token |token.}| -11)
11123 (define-six-token |token.`| -12)
11124 (define-six-token |token.#| -13)
11125 (define-six-token token.script -14)
11127 (define-six-op op.! 2 rl six.x!y six.!x )
11128 (define-six-op op.++ 2 rl #f six.++x six.x++ )
11129 (define-six-op op.-- 2 rl #f six.--x six.x-- )
11130 (define-six-op op.~ 2 rl #f six.~x )
11131 (define-six-op op.% 3 lr six.x%y )
11132 (define-six-op op.* 3 lr six.x*y six.*x )
11133 (define-six-op op./ 3 lr six.x/y )
11134 (define-six-op op.+ 4 lr six.x+y six.+x )
11135 (define-six-op op.- 4 lr six.x-y six.-x )
11136 (define-six-op op.<< 5 lr six.x<<y )
11137 (define-six-op op.>> 5 lr six.x>>y )
11138 (define-six-op op.< 6 lr six.x<y )
11139 (define-six-op op.<= 6 lr six.x<=y )
11140 (define-six-op op.> 6 lr six.x>y )
11141 (define-six-op op.>= 6 lr six.x>=y )
11142 (define-six-op op.!= 7 lr six.x!=y )
11143 (define-six-op op.== 7 lr six.x==y )
11144 (define-six-op op.& 8 lr six.x&y six.&x )
11145 (define-six-op op.^ 9 lr six.x^y )
11146 (define-six-op |op.\|| 10 lr |six.x\|y| )
11147 (define-six-op op.&& 11 lr six.x&&y )
11148 (define-six-op |op.\|\|| 12 lr |six.x\|\|y| )
11149 (define-six-op op.? 13 rl six.x?y:z )
11150 (define-six-op |op.:| 14 rl six.x:y )
11151 (define-six-op op.%= 15 rl six.x%=y )
11152 (define-six-op op.&= 15 rl six.x&=y )
11153 (define-six-op op.*= 15 rl six.x*=y )
11154 (define-six-op op.+= 15 rl six.x+=y )
11155 (define-six-op op.-= 15 rl six.x-=y )
11156 (define-six-op op./= 15 rl six.x/=y )
11157 (define-six-op op.<<= 15 rl six.x<<=y )
11158 (define-six-op op.= 15 rl six.x=y )
11159 (define-six-op op.>>= 15 rl six.x>>=y )
11160 (define-six-op op.^= 15 rl six.x^=y )
11161 (define-six-op |op.\|=| 15 rl |six.x\|=y| )
11162 (define-six-op op.:= 16 rl six.x:=y )
11163 (define-six-op |op.,| 17 lr |six.x,y| );;;;;;;;;;;;;;;; |six.,x| )
11164 (define-six-op op.:- 18 rl six.x:-y )
11166 (define max-precedence 18)
11168 (define (decimal-digit? c)
11169 (and (not (char<? c #\0)) (not (char<? #\9 c))))
11171 (define (alphabetic? c)
11172 (or (and (not (char<? c #\a)) (not (char<? #\z c)))
11173 (and (not (char<? c #\A)) (not (char<? #\Z c)))))
11175 (define (identifier-starter? c)
11180 (define (parse-number re c1 c2)
11182 (let loop ((i 2) (state (if (char=? c1 #\.) 1 0)))
11183 (let ((next (macro-peek-next-char-or-eof re)))
11184 (if (or (not (char? next))
11185 (not (or (decimal-digit? next)
11189 (or (char=? next #\e)
11190 (char=? next #\E)))
11192 (or (char=? next #\+)
11193 (char=? next #\-))))))
11196 (macro-read-next-char-or-eof re) ;; skip "next"
11199 (if (or (= state 2)
11200 (not (decimal-digit? next)))
11203 (string-set! s i next)
11205 (string-set! str 0 c1)
11206 (let ((last (string-ref str (- (string-length str) 1))))
11207 (if (or (char=? last #\.) (decimal-digit? last))
11208 (string->number str)
11210 (invalid-infix-syntax-number re)
11211 (macro-inexact-+0))))))
11213 (define (parse-character re c)
11215 (##build-escaped-string-up-to re c)))
11216 (if (= (string-length str) 1)
11219 (invalid-infix-syntax-character re)
11222 (define (parse-identifier re c)
11225 (let ((next (macro-peek-next-char-or-eof re)))
11226 (if (or (not (char? next))
11227 (and (not (alphabetic? next))
11228 (not (decimal-digit? next))
11229 (not (char=? next #\_))))
11232 (macro-read-next-char-or-eof re) ;; skip "next"
11233 (let ((s (loop (+ i 1))))
11234 (string-set! s i next)
11236 (string->symbol-object str)))
11238 (define (parse-token re)
11239 (parse-token-starting-with re (macro-peek-next-char-or-eof re)))
11241 (define (parse-token-starting-with re c)
11242 (macro-readenv-allow-script?-set!
11244 (eq? (macro-readenv-allow-script? re) 'script))
11245 (cond ((not (char? c))
11247 ((eq? (##readtable-char-handler (macro-readenv-readtable re) c)
11249 (macro-read-next-char-or-eof re) ;; skip whitespace character
11252 (let ((start-pos (##readenv-current-filepos re)))
11254 (macro-readenv-filepos-set! re start-pos) ;; restore pos
11255 (macro-read-next-char-or-eof re) ;; skip c
11257 (cond ((or (char=? c #\+)
11287 (identifier-starter? c))
11289 (let ((next (macro-peek-next-char-or-eof re)))
11290 (let ((x (if (char? next) next #\space)))
11292 (define (token tok)
11295 (define (one-char-token tok)
11298 (define (two-char-token tok)
11299 (macro-read-next-char-or-eof re) ;; skip last
11302 (cond ((char=? c #\+)
11303 (cond ((char=? x #\+)
11304 (two-char-token op.++))
11306 (two-char-token op.+=))
11308 (one-char-token op.+))))
11310 (cond ((char=? x #\-)
11311 (two-char-token op.--))
11313 (two-char-token op.-=))
11315 (two-char-token |token.->|))
11317 (one-char-token op.-))))
11319 (cond ((char=? x #\=)
11320 (two-char-token op.*=))
11322 (one-char-token op.*))))
11324 (cond ((char=? x #\/)
11325 (macro-read-next-char-or-eof re);;skip #\/
11326 (##skip-single-line-comment re)
11329 (macro-read-next-char-or-eof re);;skip #\*
11330 (##skip-extended-comment re #\/ x x #\/)
11333 (two-char-token op./=))
11335 (one-char-token op./))))
11337 (cond ((char=? x #\=)
11338 (two-char-token op.%=))
11340 (one-char-token op.%))))
11342 (cond ((char=? x #\=)
11343 (two-char-token op.!=))
11345 (one-char-token op.!))))
11347 (one-char-token op.~))
11349 (cond ((char=? x #\&)
11350 (two-char-token op.&&))
11352 (two-char-token op.&=))
11354 (one-char-token op.&))))
11356 (cond ((char=? x #\|)
11357 (two-char-token |op.\|\||))
11359 (two-char-token |op.\|=|))
11361 (one-char-token |op.\||))))
11363 (cond ((char=? x #\=)
11364 (two-char-token op.^=))
11366 (one-char-token op.^))))
11368 (cond ((char=? x #\<)
11369 (macro-read-next-char-or-eof re);;skip #\<
11371 (macro-peek-next-char-or-eof re)))
11372 (let ((x2 (if (char? next2)
11375 (cond ((char=? x2 #\=)
11376 (two-char-token op.<<=))
11378 (one-char-token op.<<))))))
11380 (two-char-token op.<=))
11382 (one-char-token op.<))))
11384 (cond ((char=? x #\>)
11385 (macro-read-next-char-or-eof re);;skip #\>
11387 (macro-peek-next-char-or-eof re)))
11388 (let ((x2 (if (char? next2)
11391 (cond ((char=? x2 #\=)
11392 (two-char-token op.>>=))
11394 (one-char-token op.>>))))))
11396 (two-char-token op.>=))
11398 (one-char-token op.>))))
11400 (cond ((char=? x #\=)
11401 (two-char-token op.==))
11403 (one-char-token op.=))))
11405 (one-char-token |token.{|))
11407 (one-char-token |token.}|))
11409 (one-char-token |token.(|))
11411 (one-char-token |token.)|))
11413 (one-char-token |token.[|))
11415 (one-char-token |token.]|))
11417 (one-char-token |token.;|))
11419 (one-char-token |op.,|))
11421 (cond ((char=? x #\=)
11422 (two-char-token op.:=))
11424 ;; In the C syntax "1?2:-3" is
11425 ;; parsed as "1 ? 2 : -3". In
11426 ;; order to support the ":-"
11427 ;; operator cleanly, the source
11428 ;; code must have whitespace
11429 ;; between the ":" and "-",
11430 ;; otherwise it will be parsed as
11431 ;; "1 ? 2 :- 3" (which is a
11433 (two-char-token op.:-))
11435 (one-char-token |op.:|))))
11437 (cond ((decimal-digit? x)
11438 (macro-read-next-char-or-eof re) ;; skip x
11439 (token (parse-number re c x)))
11441 (two-char-token |token...|))
11443 (one-char-token |token..|))))
11445 (one-char-token op.?))
11447 (one-char-token |token.\\|))
11449 (token (##build-escaped-string-up-to re c)))
11451 (token (parse-character re c)))
11453 (one-char-token |token.`|))
11455 (if (and (macro-readenv-allow-script? re)
11457 (two-char-token (##script-marker))
11458 (one-char-token |token.#|)))
11459 ((decimal-digit? c)
11460 (token (parse-number re #\0 c)))
11462 (token (parse-identifier re c)))))))
11465 (if (and (macro-readenv-allow-script? re)
11466 (eq? (macro-peek-next-char-or-eof re) #\;))
11468 (macro-read-next-char-or-eof re) ;; skip #\;
11473 (##none-marker)))))))
11475 (define (get-token re maybe-tok)
11476 (or maybe-tok (parse-token re)))
11478 (define (expect re maybe-tok expected)
11479 (let ((tok (get-token re maybe-tok)))
11480 (if (eq? tok expected)
11483 (invalid-infix-syntax re)
11486 (define (read-arguments-tail re maybe-tok cont)
11487 (let ((tok (get-token re maybe-tok)))
11488 (if (eq? tok |token.)|)
11492 (let loop ((re re) (tok tok) (args '()))
11493 (cond ((expression-starter? re tok)
11499 (lambda (re maybe-tok expr)
11500 (let ((new-args (cons expr args)))
11501 (let ((tok (get-token re maybe-tok)))
11502 (cond ((eq? tok |op.,|)
11508 (expect re tok |token.)|)
11509 (reverse new-args)))))))))
11511 (invalid-infix-syntax re)
11514 (reverse args))))))))
11516 (define (read-list re maybe-tok start-pos cont)
11517 (let loop ((re re) (maybe-tok maybe-tok) (first? #t) (cont cont))
11518 (let ((tok (get-token re maybe-tok)))
11519 (cond ((expression-starter? re tok)
11524 'no-comma-and-no-bar
11525 (lambda (re maybe-tok expr1)
11526 (let ((tok (get-token re maybe-tok)))
11527 (cond ((eq? tok |op.,|)
11531 (lambda (re maybe-tok expr2)
11545 (lambda (re maybe-tok expr2)
11547 (expect re maybe-tok |token.]|)
11555 (expect re tok |token.]|)
11565 (expect re tok |token.]|)
11570 (define (expression-starter? re tok)
11571 ;; this function must be kept in sync with "read-expression"
11576 (level2-starter? re tok)))
11578 (define (level2-starter? re tok)
11583 (primary-starter? re tok)))
11585 (define (primary-starter? re tok)
11586 (or (eq? tok |token.(|)
11587 (eq? tok |token.[|)
11588 (eq? tok |token.\\|)
11589 (eq? tok |token.`|)
11590 (eq? tok |token.#|)
11596 (six-type? re tok)))
11598 (define (read-expression re maybe-tok level restriction cont)
11600 (get-token re maybe-tok))
11602 (macro-readenv-filepos re)))
11603 (cond ((and (= level 2)
11605 (unary-prefix? tok))
11607 (lambda (scheme-name)
11608 (let ((tok2 (get-token re #f)))
11609 (if (and (eq? tok |op.!|)
11610 (not (level2-starter? re tok2)))
11621 (lambda (re maybe-tok expr)
11630 (read-identifier-or-prefix
11634 (lambda (re maybe-tok identifier)
11635 (read-arguments-tail
11637 (expect re #f |token.(|)
11638 (lambda (re maybe-tok args)
11652 (lambda (re maybe-tok expr1)
11653 (let ((tok (get-token re maybe-tok)))
11657 (last-expr1 expr1))
11658 (cond ((and (op? last-tok)
11659 (unary-postfix? last-tok))
11661 (lambda (scheme-name)
11668 ((eq? last-tok |token.(|)
11669 (read-arguments-tail
11672 (lambda (re maybe-tok args)
11674 (get-token re maybe-tok)
11680 ((eq? last-tok |token.[|)
11686 (lambda (re maybe-tok expr2)
11690 (expect re maybe-tok |token.]|))
11696 ((or (eq? last-tok |token.->|)
11697 (eq? last-tok |token..|))
11699 (macro-peek-next-char-or-eof re)))
11700 (if (or (not (eq? last-tok |token..|))
11702 (or (identifier-starter? next)
11703 (char=? next #\\))))
11706 (parse-token-starting-with re next)
11709 (lambda (re maybe-tok expr2)
11711 (get-token re maybe-tok)
11716 'six.arrow;;;;;;;;;;;;;;;
11728 (= level (precedence tok))
11730 (cond ((eq? restriction 'no-comma)
11732 ((eq? restriction 'no-comma-and-no-bar)
11733 (or (eq? tok |op.,|) (eq? tok |op.\||)))
11734 ((eq? restriction 'no-colon)
11738 (binary-or-ternary? tok))
11740 (lambda (scheme-name)
11741 (cond ((ternary? tok)
11748 'no-colon ;; assumes that end-tok = |op.:|
11749 (lambda (re maybe-tok expr2)
11752 (expect re maybe-tok end-tok)
11755 (lambda (re maybe-tok expr3)
11764 ((left-to-right? tok)
11766 (last-scheme-name scheme-name)
11767 (last-expr1 expr1))
11773 (lambda (re maybe-tok expr2)
11780 (let ((tok (get-token re maybe-tok)))
11781 (cond ((and (op? tok)
11784 (binary-or-ternary?
11787 (lambda (scheme-name)
11801 (lambda (re maybe-tok expr2)
11813 ((six-type? re tok)
11814 (let ((type (macro-readenv-wrap re tok)))
11817 (expect re #f |token.(|)
11821 ((pair? tok) ;; This special token represents two
11822 ;; consecutive tokens. This trick is used
11823 ;; because the parser needs a lookahead of 2
11824 ;; tokens to distinguish definitions from
11825 ;; anonymous procedures, and to distinguish
11826 ;; label definitions from expressions.
11828 (let ((expr (car tok)))
11832 (let ((type (car tok)))
11842 (let ((literal (macro-readenv-wrap re tok)))
11849 ((eq? tok |token.(|)
11850 (let ((tok (get-token re #f)))
11852 (define (check-closing re maybe-tok x)
11854 (expect re maybe-tok |token.)|)
11857 (if (eq? tok |token.{|)
11858 (let ((start-pos (macro-readenv-filepos re)))
11859 (read-compound-statement
11871 ((eq? tok |token.[|)
11877 ((eq? tok |token.`|)
11878 (read-quasiquotation
11882 ((eq? tok |token.#|);;;;;;;;;;;;;;;;;;;;;
11888 (read-identifier-or-prefix
11894 (define (read-paren-expression re maybe-tok cont)
11896 (get-token re (expect re maybe-tok |token.(|))))
11898 (define (check-closing re maybe-tok x)
11900 (expect re maybe-tok |token.)|)
11903 (let ((start-pos (macro-readenv-filepos re)))
11904 (if (six-type? re tok)
11905 (read-definition-or-expression-or-clause
11912 (read-expression-or-clause
11920 (define (read-expression-or-clause
11933 (lambda (re maybe-tok expr)
11935 (get-token re maybe-tok)))
11936 (if (eq? tok |token..|)
11944 (expect re tok |token.;|)
11948 (define (read-definition-or-expression-or-clause
11956 (macro-readenv-wrap re tok))
11958 (get-token re #f)))
11959 (if (eq? tok |token.(|)
11960 (read-expression-or-clause
11962 (cons type #f) ;; special combined token
11967 (read-identifier-or-prefix
11971 (lambda (re maybe-tok identifier)
11981 (define (read-identifier-or-prefix re maybe-tok accept-type? cont)
11982 (let* ((tok (get-token re maybe-tok))
11983 (start-pos (macro-readenv-filepos re)))
11984 (cond ((eq? tok |token.\\|)
11989 ((or (not (symbol? tok))
11990 (and (not accept-type?)
11991 (six-type? re tok)))
11992 (invalid-infix-syntax re)
12000 (let ((identifier (macro-readenv-wrap re tok)))
12008 (define (read-prefix re start-pos cont)
12009 (let ((expr (##read-datum-or-label re)))
12018 (if (##label-marker? expr)
12019 (##label-marker-fixup-handler-add!
12022 (lambda (resolved-obj)
12023 (set-car! obj2 resolved-obj))))
12028 (define (read-quasiquotation re start-pos cont)
12034 (##build-read-macro
12038 (macro-readtable-quasiquote-keyword
12039 (macro-readenv-readtable re))))))
12041 (define (read-sharp re start-pos cont)
12042 (let ((x (##read-sharp-aux re start-pos)))
12048 x))));;;;;;;;;;;;;;;;;;;;
12050 (define (statement-starter? re tok)
12051 ;; this function must be kept in sync with "read-statement"
12052 (or (eq? tok |token.{|)
12053 (eq? tok |token.;|)
12055 (expression-starter? re tok)))
12057 (define (read-statement re maybe-tok cont)
12059 (get-token re maybe-tok))
12061 (macro-readenv-filepos re)))
12062 (cond ((eq? tok |token.{|)
12063 (read-compound-statement
12070 (read-paren-expression
12073 (lambda (re maybe-tok expr)
12077 (lambda (re maybe-tok stat1)
12079 (get-token re maybe-tok)))
12080 (if (eq? tok 'else)
12084 (lambda (re maybe-tok stat2)
12101 (read-paren-expression
12104 (lambda (re maybe-tok expr)
12108 (lambda (re maybe-tok stat)
12120 (lambda (re maybe-tok stat)
12121 (read-paren-expression
12123 (expect re maybe-tok 'while)
12124 (lambda (re maybe-tok expr)
12126 (expect re maybe-tok |token.;|)
12135 (define (get-stat1 re maybe-tok)
12138 (expect re maybe-tok |token.(|)
12139 (lambda (re maybe-tok stat1)
12144 (define (get-expr2 re maybe-tok stat1)
12146 (get-token re maybe-tok)))
12147 (if (expression-starter? re tok)
12153 (lambda (re maybe-tok expr2)
12161 (##wrap re start-pos #f)))))
12163 (define (get-expr3 re maybe-tok stat1 expr2)
12165 (get-token re (expect re maybe-tok |token.;|))))
12166 (if (expression-starter? re tok)
12172 (lambda (re maybe-tok expr3)
12182 (##wrap re start-pos #f)))))
12184 (define (get-body re maybe-tok stat1 expr2 expr3)
12187 (expect re maybe-tok |token.)|)
12188 (lambda (re maybe-tok stat)
12202 (read-paren-expression
12205 (lambda (re maybe-tok expr)
12209 (lambda (re maybe-tok stat)
12219 (expect re #f |token.;|)
12223 ((eq? tok 'continue)
12225 (expect re #f |token.;|)
12231 (get-token re #f)))
12232 (if (expression-starter? re tok)
12238 (lambda (re maybe-tok expr)
12240 (expect re maybe-tok |token.;|)
12246 (expect re tok |token.;|)
12256 (lambda (re maybe-tok expr)
12258 (expect re maybe-tok |token.;|)
12269 (lambda (re maybe-tok expr)
12272 (expect re maybe-tok |op.:|)
12273 (lambda (re maybe-tok stat)
12281 ((eq? tok |token.;|)
12287 ((six-type? re tok)
12288 (read-definition-or-expression-or-clause
12295 ((and (symbol? tok)
12296 (not (eq? tok 'new)))
12298 (macro-readenv-wrap re tok))
12300 (get-token re #f)))
12301 (if (eq? tok |op.:|)
12305 (lambda (re maybe-tok stat)
12313 (read-expression-or-clause
12315 (cons ;; special combined token
12326 (read-expression-or-clause
12334 (define (read-definition re maybe-tok terminated? start-pos type identifier cont)
12336 (define (get-dimensions re maybe-tok rev-dims)
12337 (let ((tok (get-token re maybe-tok)))
12338 (cond ((eq? tok |token.[|)
12344 (lambda (re maybe-tok dim)
12346 (expect re maybe-tok |token.]|)
12347 (cons dim rev-dims)))))
12354 (lambda (re maybe-tok init)
12363 (##wrap re start-pos #f))))))
12365 (define (get-tail re maybe-tok rev-dims init)
12368 (expect re maybe-tok |token.;|)
12372 'six.define-variable
12375 (##wrap re start-pos (reverse rev-dims))
12378 (let ((tok (get-token re maybe-tok)))
12379 (if (eq? tok |token.(|)
12385 (lambda (re maybe-tok proc)
12390 'six.define-procedure
12397 (define (read-procedure re maybe-tok start-pos type cont)
12399 (get-token re maybe-tok))
12401 (macro-readenv-filepos re)))
12403 (define (get-body re maybe-tok rev-params)
12404 (read-compound-statement
12406 (expect re maybe-tok |token.{|)
12408 'six.procedure-body
12409 (lambda (re maybe-tok stat)
12416 (##wrap re params-start-pos (reverse rev-params))
12419 (define (err re tok rev-params)
12420 (invalid-infix-syntax re)
12422 (if (eq? tok |token.)|)
12427 (if (not (six-type? re tok))
12429 (expect re tok |token.)|)
12431 (let loop ((tok tok) (rev-params '()))
12432 (if (not (six-type? re tok))
12433 (err re tok rev-params)
12435 (macro-readenv-wrap re tok))
12437 (get-token re #f)))
12438 (read-identifier-or-prefix
12442 (lambda (re maybe-tok identifier)
12443 (let* ((new-rev-params
12444 (cons (macro-readenv-wrap re (list identifier type))
12447 (get-token re maybe-tok)))
12448 (if (eq? tok |op.,|)
12449 (loop (get-token re #f)
12452 (expect re tok |token.)|)
12453 new-rev-params)))))))))))
12455 (define (read-compound-statement re maybe-tok start-pos kind cont)
12456 (read-statements-tail
12461 (lambda (re maybe-tok stats)
12469 (define (read-statements-tail re maybe-tok start-pos rev-stats cont)
12470 (let ((tok (get-token re maybe-tok)))
12471 (if (statement-starter? re tok)
12475 (lambda (re maybe-tok stat)
12476 (read-statements-tail
12480 (cons stat rev-stats)
12483 (expect re tok |token.}|)
12484 (reverse rev-stats)))))
12486 (define (invalid-infix-syntax re)
12487 (##raise-datum-parsing-exception
12488 'invalid-infix-syntax
12491 (define (invalid-infix-syntax-character re)
12492 (##raise-datum-parsing-exception
12493 'invalid-infix-syntax-character
12496 (define (invalid-infix-syntax-number re)
12497 (##raise-datum-parsing-exception
12498 'invalid-infix-syntax-number
12501 (define (six-type? re tok)
12502 ((macro-readtable-six-type? (macro-readenv-readtable re)) tok))
12505 (get-token re #f)))
12506 (cond ((and allow-eof?
12507 (eq? tok (##none-marker))
12508 (not (char? (macro-peek-next-char-or-eof re))))
12509 (macro-read-next-char-or-eof re) ;; make sure reader progresses
12510 #!eof) ;; end-of-file was reached so return end-of-file object
12511 ((eq? tok (##script-marker))
12517 (lambda (re maybe-tok expr)
12520 (define (##six-type? x)
12521 (assq x ##six-types))
12523 (define ##six-types '())
12533 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12535 ;;; Setup the standard readtable.
12537 (define (##make-standard-readtable)
12539 (macro-make-readtable
12540 #f ;; preserve case in symbols, character names, etc
12541 #t ;; keywords ending with ":" are allowed
12542 ##standard-escaped-char-table
12543 ##standard-named-char-table
12544 ##standard-sharp-bang-table
12545 (##make-chartable #f) ;; all chars are non-delimiters
12546 (##make-chartable ##read-number/keyword/symbol)
12547 (##make-chartable ##read-sharp-other)
12548 (##fixnum.->char 127) ;; max-unescaped-char
12549 #t ;; escape-ctrl-chars?
12550 #f ;; sharing-allowed?
12551 #f ;; eval-allowed?
12552 #f ;; write-extended-read-macros?
12553 #f ;; write-cdr-read-macros?
12554 ##max-fixnum ;; max-write-level
12555 ##max-fixnum ;; max-write-length
12556 ##standard-pretty-print-formats
12557 'quote ;; quote-keyword
12558 'quasiquote ;; quasiquote-keyword
12559 'unquote ;; unquote-keyword
12560 'unquote-splicing ;; unquote-splicing-keyword
12561 'syntax ;; sharp-quote-keyword
12562 'quasisyntax ;; sharp-quasiquote-keyword
12563 'unsyntax ;; sharp-unquote-keyword
12564 'unsyntax-splicing ;; sharp-unquote-splicing-keyword
12565 'serial-number->object ;; sharp-num-keyword
12566 'repl-result-history-ref ;; sharp-seq-keyword
12567 #f ;; paren-keyword
12568 #f ;; bracket-keyword
12569 #f ;; brace-keyword
12570 #f ;; angle-keyword
12572 ##six-type? ;; six-type?
12573 #t ;; r6rs-compatible-read?
12574 #t ;; r6rs-compatible-write?
12575 'multiline ;; here-strings-allowed?
12578 (##readtable-setup-for-standard-level! rt)
12580 ;; setup control characters
12585 (##readtable-char-class-set!
12587 (UCS-4->character i)
12592 ;; setup whitespace characters
12594 (##readtable-char-class-set! rt #\space #t ##read-whitespace)
12595 (##readtable-char-class-set! rt #\linefeed #t ##read-whitespace)
12596 (##readtable-char-class-set! rt #\return #t ##read-whitespace)
12597 (##readtable-char-class-set! rt #\tab #t ##read-whitespace)
12598 (##readtable-char-class-set! rt #\page #t ##read-whitespace)
12600 ;; setup handlers for non-whitespace delimiters
12602 (##readtable-char-class-set! rt #\; #t ##read-single-line-comment)
12604 (##readtable-char-class-set! rt #\" #t ##read-escaped-string)
12605 (##readtable-char-class-set! rt #\| #t ##read-number/keyword/symbol)
12607 (##readtable-char-class-set! rt #\' #t ##read-quotation)
12608 (##readtable-char-class-set! rt #\` #t ##read-quotation)
12609 (##readtable-char-class-set! rt #\, #t ##read-quotation)
12611 (##readtable-char-class-set! rt #\( #t ##read-list)
12612 (##readtable-char-class-set! rt #\) #t ##read-none)
12614 (##readtable-char-class-set! rt #\[ #t ##read-vector-or-list)
12615 (##readtable-char-class-set! rt #\] #t ##read-none)
12617 (##readtable-char-class-set! rt #\{ #t ##read-other)
12618 (##readtable-char-class-set! rt #\} #t ##read-none)
12620 (##readtable-char-class-set! rt #\\ #t ##read-six)
12622 ;; setup handlers for "#" and "." (these are NOT delimiters)
12624 (##readtable-char-class-set! rt #\# #f ##read-sharp)
12625 (##readtable-char-class-set! rt #\. #f ##read-dot)
12627 ;; setup handlers for sharp read-macros
12632 (##readtable-char-sharp-handler-set!
12634 (UCS-4->character i)
12635 ##read-sharp-digit)
12638 (##readtable-char-sharp-handler-set! rt #\( ##read-sharp-vector)
12639 (##readtable-char-sharp-handler-set! rt #\\ ##read-sharp-char)
12640 (##readtable-char-sharp-handler-set! rt #\| ##read-sharp-comment)
12641 (##readtable-char-sharp-handler-set! rt #\! ##read-sharp-bang)
12642 (##readtable-char-sharp-handler-set! rt #\# ##read-sharp-keyword/symbol)
12643 (##readtable-char-sharp-handler-set! rt #\% ##read-sharp-keyword/symbol)
12644 (##readtable-char-sharp-handler-set! rt #\: ##read-sharp-colon)
12645 (##readtable-char-sharp-handler-set! rt #\; ##read-sharp-semicolon)
12646 (##readtable-char-sharp-handler-set! rt #\' ##read-sharp-quotation)
12647 (##readtable-char-sharp-handler-set! rt #\` ##read-sharp-quotation)
12648 (##readtable-char-sharp-handler-set! rt #\, ##read-sharp-quotation)
12649 (##readtable-char-sharp-handler-set! rt #\& ##read-sharp-ampersand)
12650 (##readtable-char-sharp-handler-set! rt #\. ##read-sharp-dot)
12651 (##readtable-char-sharp-handler-set! rt #\< ##read-sharp-less)
12655 (if (not ##main-readtable)
12656 (set! ##main-readtable
12657 (##make-standard-readtable)))
12659 ;;;----------------------------------------------------------------------------
12661 ;;; Setup readtable according to program's script line.
12663 (let* ((program-script-line
12664 (##vector-ref ##program-descr 2))
12666 (##extract-language-and-tail program-script-line)))
12667 (if language-and-tail
12668 (let ((language (##car language-and-tail)))
12669 (##readtable-setup-for-language! ##main-readtable language)
12670 (##main-set! (##start-main language)))))
12672 ;;;============================================================================