diff --git a/src/ikarus.boot b/src/ikarus.boot index 440d79f..160e83b 100644 Binary files a/src/ikarus.boot and b/src/ikarus.boot differ diff --git a/src/ikarus.fasl.write.ss b/src/ikarus.fasl.write.ss index 64d510f..ef1c1c1 100644 --- a/src/ikarus.fasl.write.ss +++ b/src/ikarus.fasl.write.ss @@ -10,18 +10,17 @@ (define write-fixnum (lambda (x p) (unless (fixnum? x) (error 'write-fixnum "not a fixnum ~s" x)) - (write-char (integer->char (fxsll (fxlogand x #x3F) 2)) p) - (write-char (integer->char (fxlogand (fxsra x 6) #xFF)) p) - (write-char (integer->char (fxlogand (fxsra x 14) #xFF)) p) - (write-char (integer->char (fxlogand (fxsra x 22) #xFF)) p))) + (write-byte (fxsll (fxlogand x #x3F) 2) p) + (write-byte (fxlogand (fxsra x 6) #xFF) p) + (write-byte (fxlogand (fxsra x 14) #xFF) p) + (write-byte (fxlogand (fxsra x 22) #xFF) p))) (define write-int (lambda (x p) (unless (fixnum? x) (error 'write-int "not a fixnum ~s" x)) - (write-char (integer->char (fxlogand x #xFF)) p) - (write-char (integer->char (fxlogand (fxsra x 8) #xFF)) p) - (write-char (integer->char (fxlogand (fxsra x 16) #xFF)) p) - (write-char (integer->char (fxlogand (fxsra x 24) #xFF)) p))) - + (write-byte (fxlogand x #xFF) p) + (write-byte (fxlogand (fxsra x 8) #xFF) p) + (write-byte (fxlogand (fxsra x 16) #xFF) p) + (write-byte (fxlogand (fxsra x 24) #xFF) p))) (define fasl-write-immediate (lambda (x p) (cond @@ -76,7 +75,7 @@ (write-fixnum (code-freevars x) p) (let f ([i 0] [n (code-size x)]) (unless (fx= i n) - (write-char (integer->char (code-ref x i)) p) + (write-byte (code-ref x i) p) (f (fxadd1 i) n))) (fasl-write-object (code-reloc-vector x) p h m)] [(record? x) diff --git a/src/ikarus.io.output-files.ss b/src/ikarus.io.output-files.ss index 28fb4e3..191a1f3 100644 --- a/src/ikarus.io.output-files.ss +++ b/src/ikarus.io.output-files.ss @@ -7,6 +7,8 @@ (ikarus system $ports) (ikarus system $io) (ikarus system $strings) + (ikarus system $chars) + (ikarus system $bytevectors) (ikarus system $fx) (except (ikarus) standard-output-port standard-error-port @@ -48,7 +50,7 @@ (close-output-port p) (close-ports))]))) - (define do-write-buffer + (define do-write-buffer-old (lambda (fd port-name p caller) (let ([bytes (foreign-call "ikrt_write_file" fd @@ -58,7 +60,14 @@ (set-port-output-index! p 0) (error caller "cannot write to file ~s: ~a" port-name bytes))))) - (define make-output-file-handler + (define do-write-buffer + (lambda (fd port-name buff idx caller) + (let ([bytes (foreign-call "ikrt_write_file" fd buff idx)]) + (if (fixnum? bytes) + bytes + (error caller "cannot write to file ~s: ~a" port-name bytes))))) + + (define make-output-file-handler-old (lambda (fd port-name) (define open? #t) (define output-file-handler @@ -98,6 +107,56 @@ "unhandled message ~s" (cons msg args))]))) output-file-handler)) + (define make-output-file-handler + (lambda (fd port-name) + (define open? #t) + (define buff ($make-bytevector 4096)) + (define idx 0) + (define size 4096) + (define output-file-handler + (lambda (msg . args) + (message-case msg args + [(write-byte b p) + (if (and (fixnum? b) ($fx<= 0 b) ($fx<= b 255)) + (if (output-port? p) + (if ($fx< idx size) + (begin + ($bytevector-set! buff idx b) + (set! idx ($fxadd1 idx))) + (if open? + (let ([bytes (do-write-buffer fd port-name buff idx 'write-char)]) + (set! idx 0) + ($write-byte b p)) + (error 'write-byte "port ~s is closed" p))) + (error 'write-byte "~s is not an output-port" p)) + (error 'write-byte "~s is not a byte" b))] + [(write-char c p) + (if (char? c) + (if (output-port? p) + (let ([b ($char->fixnum c)]) + (if ($fx<= b 255) + ($write-byte b p) + (error 'write-char "multibyte write of ~s not implemented" c))) + (error 'write-char "~s is not an output-port" p)) + (error 'write-char "~s is not a character" c))] + [(flush-output-port p) + (if (output-port? p) + (if open? + (let ([bytes (do-write-buffer fd port-name buff idx 'flush-output-port)]) + (set! idx 0)) + (error 'flush-output-port "port ~s is closed" p)) + (error 'flush-output-port "~s is not an output-port" p))] + [(close-port p) + (when open? + (flush-output-port p) + (set! size 0) + (set! open? #f) + (unless (foreign-call "ikrt_close_file" fd) + (error 'close-output-port "cannot close ~s" port-name)))] + [(port-name p) port-name] + [else (error 'output-file-handler + "unhandled message ~s" (cons msg args))]))) + output-file-handler)) (define (option-id x) (case x [(error) 0] @@ -117,7 +176,7 @@ (let ([port (make-output-port (make-output-file-handler fd/error filename) - (make-string 4096))]) + (make-string 0))]) (guardian port) port) (error 'open-output-file "cannot open ~s: ~a" filename fd/error))))) @@ -191,9 +250,9 @@ (set! *standard-output-port* (make-output-port (make-output-file-handler 1 '*stdout*) - (make-string 4096))) + (make-string 0))) (set! *current-output-port* *standard-output-port*) (set! *standard-error-port* (make-output-port (make-output-file-handler 2 '*stderr*) - (make-string 4096))) ) + (make-string 0))) ) diff --git a/src/ikarus.io.output-strings.ss b/src/ikarus.io.output-strings.ss index 52639fd..adb7219 100644 --- a/src/ikarus.io.output-strings.ss +++ b/src/ikarus.io.output-strings.ss @@ -3,6 +3,8 @@ (export open-output-string get-output-string with-output-to-string) (import (ikarus system $strings) + (ikarus system $bytevectors) + (ikarus system $chars) (ikarus system $fx) (ikarus system $pairs) (ikarus system $ports) @@ -35,7 +37,7 @@ (lambda (s) (substring s 0 (string-length s)))) - (define concat + (define concat-old (lambda (str i ls) (let ([n (sum i ls)]) (let ([outstr (make-string n)]) @@ -45,13 +47,28 @@ (let ([a ($car ls)]) (f (copy outstr a (string-length a) n) ($cdr ls))))))))) + (define concat + (lambda (bv i ls) + (let ([n (sum i ls)]) + (let ([outstr (make-string n)]) + (let f ([n (copy outstr bv i n)] [ls ls]) + (if (null? ls) + outstr + (let ([a ($car ls)]) + (f (copy outstr a ($bytevector-length a) n) ($cdr ls))))))))) (define sum (lambda (ac ls) (cond [(null? ls) ac] - [else (sum ($fx+ ac (string-length ($car ls))) ($cdr ls))]))) + [else (sum ($fx+ ac ($bytevector-length ($car ls))) ($cdr ls))]))) - (define copy + (define sum-old + (lambda (ac ls) + (cond + [(null? ls) ac] + [else (sum ($fx+ ac (string-length ($car ls))) ($cdr ls))]))) + + (define copy-old (lambda (dst src n end) (let f ([di end] [si n]) @@ -61,8 +78,21 @@ (let ([di ($fxsub1 di)] [si ($fxsub1 si)]) (string-set! dst di (string-ref src si)) (f di si))])))) - - (define make-output-string-handler + + (define copy + (lambda (dst src n end) + (let f ([di end] + [si n]) + (cond + [($fx= si 0) di] + [else + (let ([di ($fxsub1 di)] [si ($fxsub1 si)]) + (string-set! dst di + (integer->char ($bytevector-u8-ref src si))) + (f di si))])))) + + + (define make-output-string-handler-old (lambda () (define buffer-list '()) (define open? #t) @@ -102,11 +132,57 @@ "unhandled message ~s" (cons msg args))]))) output-handler)) + (define make-output-string-handler + (lambda () + (define buffer-list '()) + (define open? #t) + (define idx 0) + (define buff (make-bytevector 59)) + (define size 59) + (define output-handler + (lambda (msg . args) + (message-case msg args + [(write-byte b p) + (if (and (fixnum? b) ($fx<= 0 b) ($fx<= b 255)) + (if (output-port? p) + (if ($fx< idx size) + (begin + ($bytevector-set! buff idx b) + (set! idx ($fxadd1 idx))) + (if open? + (begin + (set! buffer-list (cons buff buffer-list)) + (set! buff (make-bytevector 59)) + ($bytevector-set! buff 0 b) + (set! idx 1)) + (error 'write-byte "port ~s is closed" p))) + (error 'write-byte "~s is not an output-port" p)) + (error 'write-byte "~s is not a byte" b))] + [(write-char c p) + (if (char? c) + (if (output-port? p) + (let ([b ($char->fixnum c)]) + (if ($fx<= b 255) + ($write-byte b p) + (error 'write-char "multibyte write of ~s is not implemented" c))) + (error 'write-char "~s is not an output-port" p)) + (error 'write-char "~s is not a character" c))] + [(flush-output-port p) + (void)] + [(close-port p) + (set! open? #f)] + [(port-name p) 'string-port] + [(get-output-string p) + (concat buff idx buffer-list)] + [else (error 'output-handler + "unhandled message ~s" (cons msg args))]))) + output-handler)) + (define open-output-string (lambda () (make-output-port (make-output-string-handler) - (make-string 10)))) + (make-string 0)))) (define get-output-string (lambda (p)