
7.ss, scheme.1.in, comments of many files original commit: 06f858f9a505b9d6fb6ca1ac97234927cb2dc641
3488 lines
176 KiB
Scheme
3488 lines
176 KiB
Scheme
;;; 6.ms
|
||
;;; Copyright 1984-2017 Cisco Systems, Inc.
|
||
;;;
|
||
;;; Licensed under the Apache License, Version 2.0 (the "License");
|
||
;;; you may not use this file except in compliance with the License.
|
||
;;; You may obtain a copy of the License at
|
||
;;;
|
||
;;; http://www.apache.org/licenses/LICENSE-2.0
|
||
;;;
|
||
;;; Unless required by applicable law or agreed to in writing, software
|
||
;;; distributed under the License is distributed on an "AS IS" BASIS,
|
||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
;;; See the License for the specific language governing permissions and
|
||
;;; limitations under the License.
|
||
|
||
;;; sections 6-1 and 6-2:
|
||
|
||
(mat current-input-port
|
||
(port? (current-input-port))
|
||
(input-port? (current-input-port))
|
||
(eq? (current-input-port) (console-input-port))
|
||
)
|
||
|
||
(mat current-output-port
|
||
(port? (current-output-port))
|
||
(output-port? (current-output-port))
|
||
(eq? (current-output-port) (console-output-port))
|
||
)
|
||
|
||
(mat port-operations
|
||
(error? (open-input-file "nonexistent file"))
|
||
(error? (open-input-file "nonexistent file" 'compressed))
|
||
(error? (open-output-file "/nonexistent/directory/nonexistent/file"))
|
||
(error? (open-output-file "/nonexistent/directory/nonexistent/file" 'replace))
|
||
(error? (open-input-output-file "/nonexistent/directory/nonexistent/file"))
|
||
(error? (open-input-output-file "/nonexistent/directory/nonexistent/file" 'truncate))
|
||
; the following several clauses test various open-output-file options
|
||
(let ([p (open-output-file "testfile.ss" 'truncate)])
|
||
(and (port? p) (output-port? p) (begin (close-output-port p) #t)))
|
||
(error? (open-output-file "testfile.ss"))
|
||
(error? (open-output-file "testfile.ss" 'error))
|
||
(let ([p (open-output-file "testfile.ss" 'replace)])
|
||
(and (port? p) (output-port? p) (begin (close-output-port p) #t)))
|
||
(let ([p (open-output-file "testfile.ss" 'truncate)])
|
||
(and (port? p) (output-port? p) (begin (close-output-port p) #t)))
|
||
(let ([p (open-output-file "testfile.ss" 'truncate)])
|
||
(display "\"hello" p)
|
||
(close-output-port p)
|
||
(let ([p (open-output-file "testfile.ss" 'append)])
|
||
(display " there\"" p)
|
||
(close-output-port p)
|
||
(let ([p (open-input-file "testfile.ss")])
|
||
(and (equal? (read p) "hello there")
|
||
(eof-object? (read p))
|
||
(begin (close-input-port p) #t)))))
|
||
; the following tests open-output-file, close-output-port, write,
|
||
; display, and newline---and builds testfile.ss for the next test
|
||
(let ([p (let loop () (if (file-exists? "testfile.ss")
|
||
(begin (delete-file "testfile.ss" #f) (loop))
|
||
(open-output-file "testfile.ss")))])
|
||
(for-each (lambda (x) (write x p) (display " " p))
|
||
'(a b c d e))
|
||
(newline p)
|
||
(close-output-port p)
|
||
#t)
|
||
; the following tests open-input-file, close-input-port, read,
|
||
; and eof-object?
|
||
(equal? (let ([p (open-input-file "testfile.ss")])
|
||
(let f ([x (read p)])
|
||
(if (eof-object? x)
|
||
(begin (close-input-port p) '())
|
||
(cons x (f (read p))))))
|
||
'(a b c d e))
|
||
; the following tests with-output-to-file, close-port,
|
||
; and write-char---and builds testfile.ss for the next test
|
||
(equal? (call-with-values
|
||
(lambda ()
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda ()
|
||
(for-each (lambda (c) (write-char c))
|
||
(string->list "a b c d e"))
|
||
(values 1 2 3))
|
||
'replace))
|
||
list)
|
||
'(1 2 3))
|
||
; the following tests with-input-from-file, close-port,
|
||
; read-char, unread-char, and eof-object?
|
||
(equal? (with-input-from-file "testfile.ss"
|
||
(lambda ()
|
||
(list->string
|
||
(let f ()
|
||
(let ([c (read-char)])
|
||
(if (eof-object? c)
|
||
'()
|
||
(begin (unread-char c)
|
||
(let ([c (read-char)])
|
||
(cons c (f))))))))))
|
||
"a b c d e")
|
||
; the following tests call-with-output-file, close-port,
|
||
; and write-char---and builds testfile.ss for the next test
|
||
(equal? (call-with-values
|
||
(lambda ()
|
||
(call-with-output-file "testfile.ss"
|
||
(lambda (p)
|
||
(for-each (lambda (c) (write-char c p))
|
||
(string->list "a b c d e"))
|
||
(close-port p)
|
||
(values 1 2 3))
|
||
'replace))
|
||
list)
|
||
'(1 2 3))
|
||
; the following tests call-with-input-file, close-port,
|
||
; read-char, unread-char, and eof-object?
|
||
(equal? (call-with-input-file "testfile.ss"
|
||
(lambda (p)
|
||
(list->string
|
||
(let f ()
|
||
(let ([c (read-char p)])
|
||
(if (eof-object? c)
|
||
(begin (close-port p) '())
|
||
(begin (unread-char c p)
|
||
(let ([c (read-char p)])
|
||
(cons c (f))))))))))
|
||
"a b c d e")
|
||
; the following tests call-with-input-file, close-port,
|
||
; read-char, unread-char, and eof-object?
|
||
(equal? (call-with-values
|
||
(lambda ()
|
||
(call-with-input-file "testfile.ss"
|
||
(lambda (p)
|
||
(apply values
|
||
(let f ()
|
||
(let ([c (read-char p)])
|
||
(if (eof-object? c)
|
||
(begin (close-port p) '())
|
||
(begin (unread-char c p)
|
||
(let ([c (read-char p)])
|
||
(cons c (f)))))))))))
|
||
(lambda ls (list->string ls)))
|
||
"a b c d e")
|
||
; the following tests call-with-input-file, close-input-port,
|
||
; read-char, peek-char, and eof-object?
|
||
(equal? (call-with-input-file "testfile.ss"
|
||
(lambda (p)
|
||
(list->string
|
||
(let f ()
|
||
(let ([c (peek-char p)])
|
||
(if (eof-object? c)
|
||
(begin (close-input-port p) '())
|
||
(let ([c (read-char p)])
|
||
(cons c (f)))))))))
|
||
"a b c d e")
|
||
; test various errors related to input ports
|
||
(begin (set! ip (open-input-file "testfile.ss"))
|
||
(and (port? ip) (input-port? ip)))
|
||
(error? (unread-char #\a ip))
|
||
(eqv? (read-char ip) #\a)
|
||
(begin (unread-char #\a ip) (eqv? (read-char ip) #\a))
|
||
(begin (clear-input-port ip) #t)
|
||
(error? (unread-char #\a ip))
|
||
(error? (write-char #\a ip))
|
||
(error? (write 'a ip))
|
||
(error? (display 'a ip))
|
||
(error? (newline ip))
|
||
(error? (fprintf ip "hi"))
|
||
(error? (flush-output-port ip))
|
||
(error? (clear-output-port ip))
|
||
(begin (close-input-port ip) #t)
|
||
(error? (read-char ip))
|
||
(error? (read ip))
|
||
(error? (char-ready? ip))
|
||
; test various errors related to output ports
|
||
(begin (set! op (open-output-file "testfile.ss" 'replace))
|
||
(and (port? op) (output-port? op)))
|
||
(error? (char-ready? op))
|
||
(error? (peek-char op))
|
||
(error? (read-char op))
|
||
(error? (unread-char #\a op))
|
||
(error? (read op))
|
||
(error? (clear-input-port op))
|
||
(begin (close-output-port op) #t)
|
||
(error? (write-char #\a op))
|
||
(error? (write 'a op))
|
||
(error? (display 'a op))
|
||
(error? (newline op))
|
||
(error? (fprintf op "hi"))
|
||
(error? (flush-output-port op))
|
||
(error? (clear-output-port op))
|
||
(error? (current-output-port 'a))
|
||
(error? (current-input-port 'a))
|
||
(begin (current-output-port (console-output-port)) #t)
|
||
(begin (current-input-port (console-input-port)) #t)
|
||
|
||
; the following tests open-input-string, open-output-string, read-char,
|
||
; eof-object?, unread-char, write-char, and get-ouptut-string
|
||
(let ([s "hi there, mom!"])
|
||
(let ([ip (open-input-string s)] [op (open-output-string)])
|
||
(do ([c (read-char ip) (read-char ip)])
|
||
((eof-object? c)
|
||
(equal? (get-output-string op) s))
|
||
(unread-char c ip)
|
||
(write-char (read-char ip) op))))
|
||
|
||
(error? (with-input-from-string))
|
||
(error? (with-input-from-string "a"))
|
||
(error? (with-input-from-string 'a (lambda () 3)))
|
||
(error? (with-input-from-string "a" 'foo))
|
||
(error? (with-input-from-string (lambda () 3) "a"))
|
||
(error? (with-input-from-string '(this too?) values))
|
||
(error? (with-input-from-string "a" (lambda () 3) 'compressed))
|
||
(error? (with-output-to-string))
|
||
(error? (with-output-to-string "a"))
|
||
(error? (with-output-to-string 'a (lambda () 3)))
|
||
(error? (with-output-to-string '(this too?)))
|
||
(error? (eof-object #!eof))
|
||
(eq? (with-input-from-string "" read) #!eof)
|
||
(eq? (with-input-from-string "" read) (eof-object))
|
||
(eq? (eof-object) #!eof)
|
||
(error? (with-input-from-string "'" read))
|
||
; the following tests with-input-from-string, with-output-to-string,
|
||
; read-char, eof-object?, unread-char, and write-char
|
||
(let ([s "hi there, mom!"])
|
||
(equal?
|
||
(with-input-from-string s
|
||
(lambda ()
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(do ([c (read-char) (read-char)])
|
||
((eof-object? c))
|
||
(unread-char c)
|
||
(write-char (read-char)))))))
|
||
s))
|
||
|
||
; the following makes sure that call-with-{in,out}put-file close the
|
||
; port (from Dave Boyer)---at least on systems which restrict the
|
||
; number of open ports to less than 20
|
||
(let loop ((i 20))
|
||
(or (zero? i)
|
||
(begin (call-with-output-file "testfile.ss"
|
||
(lambda (p) (write i p))
|
||
'replace)
|
||
(and (eq? (call-with-input-file "testfile.ss"
|
||
(lambda (p) (read p)))
|
||
i)
|
||
(loop (- i 1))))))
|
||
|
||
; test source information in error messages from read
|
||
(error?
|
||
(begin
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display "(cons 1 2 . 3 4)"))
|
||
'replace)
|
||
(let ([ip (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (read ip))
|
||
(lambda () (close-input-port ip))))))
|
||
|
||
; test source information in error messages from read
|
||
(error?
|
||
(begin
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display "(cons 1 2 ] 3 4)"))
|
||
'replace)
|
||
(let ([ip (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (read ip))
|
||
(lambda () (close-input-port ip))))))
|
||
)
|
||
|
||
(mat port-operations1
|
||
(error? (open-input-output-file))
|
||
(error? (open-input-output-file 'furball))
|
||
(error? (open-input-output-file "/probably/not/a/good/path"))
|
||
(error? (open-input-output-file "testfile.ss" 'compressed))
|
||
(error? (open-input-output-file "testfile.ss" 'uncompressed))
|
||
(begin
|
||
(define $ppp (open-input-output-file "testfile.ss"))
|
||
(and (input-port? $ppp) (output-port? $ppp) (port? $ppp)))
|
||
(error? (truncate-file $ppp -3))
|
||
(error? (truncate-file $ppp 'all-the-way))
|
||
(eof-object?
|
||
(begin
|
||
(truncate-file $ppp)
|
||
(display "hello" $ppp)
|
||
(flush-output-port $ppp)
|
||
(read $ppp)))
|
||
(eq? (begin (file-position $ppp 0) (read $ppp)) 'hello)
|
||
(eqv? (begin
|
||
(display "goodbye\n" $ppp)
|
||
(truncate-file $ppp 9)
|
||
(file-position $ppp))
|
||
9)
|
||
(eof-object? (read $ppp))
|
||
(eqv? (begin (file-position $ppp 0) (file-position $ppp)) 0)
|
||
(eq? (read $ppp) 'hellogood)
|
||
(eqv? (begin
|
||
(display "byebye\n" $ppp)
|
||
(truncate-file $ppp 0)
|
||
(file-position $ppp))
|
||
0)
|
||
(eof-object? (read $ppp))
|
||
(eof-object?
|
||
(begin
|
||
(close-port $ppp)
|
||
(let ([ip (open-input-file "testfile.ss")])
|
||
(let ([c (read-char ip)])
|
||
(close-input-port ip)
|
||
c))))
|
||
(error?
|
||
(let ([ip (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (truncate-file ip))
|
||
(lambda () (close-input-port ip)))))
|
||
(error? (truncate-file 'animal-crackers))
|
||
(error? (truncate-file))
|
||
(error? (truncate-file $ppp))
|
||
(let ([op (open-output-string)])
|
||
(and (= (file-position op) 0)
|
||
(= (file-length op) 0)
|
||
(begin (fresh-line op) #t)
|
||
(= (file-length op) 0)
|
||
(= (file-position op) 0)
|
||
(do ([i 4000 (fx- i 1)])
|
||
((fx= i 0) #t)
|
||
(display "hello" op))
|
||
(= (file-length op) 20000)
|
||
(= (file-position op) 20000)
|
||
(begin (file-position op 5000) #t)
|
||
(= (file-position op) 5000)
|
||
(= (file-length op) 20000)
|
||
(begin (truncate-file op) #t)
|
||
(= (file-length op) 0)
|
||
(= (file-position op) 0)
|
||
(begin (truncate-file op 17) #t)
|
||
(= (file-length op) 17)
|
||
(= (file-position op) 17)
|
||
(begin (display "okay" op) #t)
|
||
(= (file-length op) 21)
|
||
(= (file-position op) 21)
|
||
(equal? (substring (get-output-string op) 17 21) "okay")
|
||
(= (file-length op) 0)
|
||
(= (file-position op) 0)
|
||
(begin (fresh-line op) #t)
|
||
(= (file-length op) 0)
|
||
(= (file-position op) 0)
|
||
(begin
|
||
(write-char #\a op)
|
||
(fresh-line op)
|
||
#t)
|
||
(= (file-position op) 2)
|
||
(begin (fresh-line op) #t)
|
||
(= (file-position op) 2)
|
||
(equal? (get-output-string op) "a\n")))
|
||
(let ([ip (open-input-string "beam me up, scotty!")]
|
||
[s (make-string 10)])
|
||
(and (= (file-position ip) 0)
|
||
(= (file-length ip) 19)
|
||
(not (eof-object? (peek-char ip)))
|
||
(equal? (read ip) 'beam)
|
||
(= (file-position ip) 4)
|
||
(not (eof-object? (peek-char ip)))
|
||
(equal? (block-read ip s 10) 10)
|
||
(equal? s " me up, sc")
|
||
(= (file-position ip) 14)
|
||
(equal? (block-read ip s 10) 5)
|
||
(equal? s "otty!p, sc")
|
||
(= (file-position ip) 19)
|
||
(eof-object? (peek-char ip))
|
||
(eof-object? (read-char ip))
|
||
(eof-object? (block-read ip s 10))
|
||
(eof-object? (block-read ip s 0))
|
||
(begin
|
||
(file-position ip 10)
|
||
(= (file-position ip) 10))
|
||
(equal? (block-read ip s 10) 9)
|
||
(equal? s ", scotty!c")))
|
||
(error? ; unhandled message
|
||
(get-output-string (open-input-string "oops")))
|
||
(error? ; unhandled message
|
||
(let ([op (open-output-file "testfile.ss" 'replace)])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (get-output-string op))
|
||
(lambda () (close-output-port op)))))
|
||
)
|
||
|
||
(mat compression
|
||
(let ()
|
||
(define cp
|
||
(lambda (mode src dst)
|
||
(define buf-size 4096)
|
||
(let ([buf (make-string buf-size)])
|
||
(call-with-output-file dst
|
||
(lambda (op)
|
||
(call-with-input-file src
|
||
(lambda (ip)
|
||
(let lp ()
|
||
(let ([n (block-read ip buf buf-size)])
|
||
(unless (eof-object? n) (block-write op buf n) (lp)))))))
|
||
mode))))
|
||
(define cmp
|
||
(lambda (mode1 src1 mode2 src2)
|
||
(define buf-size 4096)
|
||
(let ([buf1 (make-string buf-size)]
|
||
[buf2 (make-string buf-size)])
|
||
(call-with-input-file src1
|
||
(lambda (ip1)
|
||
(call-with-input-file src2
|
||
(lambda (ip2)
|
||
(let lp ()
|
||
(let ([n1 (block-read ip1 buf1 buf-size)]
|
||
[n2 (block-read ip2 buf2 buf-size)])
|
||
(if (eof-object? n1)
|
||
(eof-object? n2)
|
||
(and (eqv? n1 n2)
|
||
(string=? (substring buf1 0 n1)
|
||
(substring buf2 0 n2))
|
||
(lp))))))
|
||
mode2))
|
||
mode1))))
|
||
(and
|
||
(cmp '() "prettytest.ss" '() "prettytest.ss")
|
||
(cmp '(compressed) "prettytest.ss" '() "prettytest.ss")
|
||
(cmp '() "prettytest.ss" '(compressed) "prettytest.ss")
|
||
(cmp '(compressed) "prettytest.ss" '(compressed) "prettytest.ss")
|
||
(begin
|
||
(cp '(replace compressed) "prettytest.ss" "testfile.ss")
|
||
#t)
|
||
(cmp '(compressed) "testfile.ss" '() "prettytest.ss")
|
||
(not (= (call-with-input-file "testfile.ss" file-length) (call-with-input-file "prettytest.ss" file-length)))
|
||
; the following test could cause an error with anything but latin-1 codec
|
||
#;(not (cmp '() "testfile.ss" '() "prettytest.ss"))
|
||
(begin
|
||
(cp '(compressed append) "prettytest.ss" "testfile.ss")
|
||
#t)
|
||
(not (cmp '(compressed) "testfile.ss" '() "prettytest.ss"))
|
||
))
|
||
(error? (open-output-file "testfile.ss" '(replace append)))
|
||
(error? (open-output-file "testfile.ss" '(append truncate)))
|
||
; test workaround for bogus gzclose error return for empty input files
|
||
(and
|
||
(eqv? (with-output-to-file "testfile.ss" void 'replace) (void))
|
||
(eof-object? (with-input-from-file "testfile.ss" read 'compressed)))
|
||
)
|
||
|
||
(mat read-comment
|
||
(equal? '; this is the first comment
|
||
(a ; second comment
|
||
#;(third ; comment in comment
|
||
comment #;(comment #1=e in
|
||
. #;(comment in comment in comment)
|
||
comment)) b ; fourth comment
|
||
c #| fifth comment #| more
|
||
nesting here |# |# d
|
||
; sixth and final comment
|
||
#1#)
|
||
'(a b c d e))
|
||
(equal? (read (open-input-string "; this is the first comment
|
||
(a ; second comment
|
||
#;(third ; comment in comment
|
||
comment #;(comment #1=e in
|
||
. #;(comment in comment in comment)
|
||
comment)) b ; fourth comment
|
||
c #| fifth comment #| more
|
||
nesting here |# |# d
|
||
; sixth and final comment
|
||
#1#)"))
|
||
'(a b c d e))
|
||
(equal? (read (open-input-string "(#|##|# |#|#1
|
||
#||#2
|
||
#|||#3
|
||
#|#||#|#4
|
||
#|| hello ||#5
|
||
#| ; rats |#)"))
|
||
'(1 2 3 4 5))
|
||
)
|
||
|
||
(mat read-graph
|
||
(begin
|
||
(define read-test-graph
|
||
(case-lambda
|
||
[(s) (read-test-graph s s)]
|
||
[(s1 s2)
|
||
(string=?
|
||
(parameterize ((print-graph #t))
|
||
(format "~s" (read (open-input-string s1))))
|
||
s2)]))
|
||
#t)
|
||
(error? ; verify that the error message is NOT "invalid memory reference"
|
||
(let ((ip (open-input-string "(cons 0 #0#)")))
|
||
((#%$make-read ip #t #f) #t)))
|
||
(let ()
|
||
(define-record foo ((immutable x) (immutable y)))
|
||
(record-reader 'foo (record-rtd (make-foo 3 4)))
|
||
(and
|
||
(read-test-graph "#0=#[foo (#0#) 0]")
|
||
(read-test-graph "#0=(#[foo #0# 0])")
|
||
(read-test-graph "#[foo #0=(a b c) #0#]")))
|
||
(error? (read-test-graph "#0=#[foo #0# #0#]"))
|
||
(read-test-graph "#(123 #[foo #0=(a b c) #0#])")
|
||
(read-test-graph "#(#0=#[foo #1=(a b c) #1#] 0 #0#)")
|
||
(read-test-graph "#(#1# 0 #1=#[foo #0=(a b c) #0#])"
|
||
"#(#0=#[foo #1=(a b c) #1#] 0 #0#)")
|
||
(read-test-graph "#(123 #0=(#0#))")
|
||
(read-test-graph "#(123 #0=(#0#))")
|
||
(let ()
|
||
(define-record r1 ((mutable a) (immutable b)))
|
||
(define-record r2 ((immutable a)))
|
||
(let* ((x2 (make-r2 (make-r1 '* '(a b c)))) (x1 (r2-a x2)))
|
||
(set-r1-a! x1 x2)
|
||
(record-reader 'r1 (record-rtd (make-r1 3 4)))
|
||
(record-reader 'r2 (record-rtd (make-r2 3)))
|
||
(read-test-graph
|
||
(parameterize ((print-graph #t))
|
||
(format "~s" (list (r1-b x1) x1))))))
|
||
(read-test-graph "(#0=(a b c) #1=#[r1 #[r2 #1#] #0#])")
|
||
)
|
||
|
||
(mat block-io
|
||
; test block-write and build testfile.ss for the following test
|
||
(let ([p (open-output-file "testfile.ss" 'truncate)])
|
||
(block-write p "hi there")
|
||
(display " mom" p)
|
||
(block-write p ", how are you?xxxx" (string-length ", how are you?"))
|
||
(newline p)
|
||
(let ([s (make-string 100 #\X)])
|
||
(string-set! s 99 #\newline)
|
||
(let ([s (apply string-append (make-list 10 s))])
|
||
(let ([s (apply string-append (make-list 10 s))])
|
||
(block-write p s)
|
||
(block-write p s 5000))))
|
||
(close-output-port p)
|
||
#t)
|
||
; test block-read
|
||
(let ([random-read-up
|
||
(lambda (p n)
|
||
(let f ([n n] [ls '()])
|
||
(if (fx= n 0)
|
||
(apply string-append (reverse ls))
|
||
(if (fxodd? n)
|
||
(f (- n 1) (cons (string (read-char p)) ls))
|
||
(let ([s (make-string (random (fx+ n 1)))])
|
||
(let ([i (if (fx= (random 2) 0)
|
||
(block-read p s)
|
||
(block-read p s (string-length s)))])
|
||
(f (- n i) (cons (substring s 0 i) ls))))))))])
|
||
(let ([s (make-string 100 #\X)])
|
||
(string-set! s 99 #\newline)
|
||
(let ([s (apply string-append (make-list 10 s))])
|
||
(let ([s (apply string-append (make-list 10 s))])
|
||
(let ([s (string-append "hi there mom, how are you?"
|
||
(string #\newline)
|
||
s
|
||
(substring s 0 5000))])
|
||
(let ([p (open-input-file "testfile.ss")])
|
||
(let ([t (random-read-up p (string-length s))])
|
||
(and (eof-object? (read-char p))
|
||
(string=? t s)
|
||
(eqv? (close-input-port p) (void))))))))))
|
||
; test for bug: block-read complained when handler returned eof
|
||
(eof-object?
|
||
(let ((p (make-input-port (lambda args #!eof) "")))
|
||
(block-read p (make-string 100))))
|
||
)
|
||
|
||
(mat file-length-and-file-position
|
||
(procedure? file-length)
|
||
(procedure? file-position)
|
||
(let ([s "hi there"])
|
||
(let ([n (string-length s)]
|
||
[p (open-output-file "testfile.ss" 'replace)])
|
||
(and (eqv? (file-length p) 0)
|
||
(begin (display s p)
|
||
(= (file-position p) (file-length p) n))
|
||
(begin (display #\space p)
|
||
(= (file-position p) (file-length p) (+ n 1)))
|
||
(eqv? (file-position p 1) (void))
|
||
(write-char #\o p)
|
||
(eqv? (file-position p 2000) (void))
|
||
(begin (display s p)
|
||
(= (file-length p) (file-position p) (+ 2000 n)))
|
||
(eqv? (close-output-port p) (void)))))
|
||
;;; no error is reported, which isn't serious
|
||
; (error? (file-position (open-input-file "testfile.ss") 10000))
|
||
(error?
|
||
(let ((p (open-input-file "testfile.ss")))
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (file-position p -1))
|
||
(lambda () (close-input-port p)))))
|
||
(guard (c [(i/o-invalid-position-error? c)])
|
||
(let ([p (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
void
|
||
(lambda ()
|
||
(file-position p (if (fixnum? (expt 2 32)) (- (expt 2 63) 1) (- (expt 2 31) 1)))
|
||
#t)
|
||
(lambda () (close-input-port p)))))
|
||
(error?
|
||
(let ([p (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (file-position p (expt 2 64)))
|
||
(lambda () (close-input-port p)))))
|
||
(error? (file-position 1))
|
||
(error? (file-length 1))
|
||
(let ([s "hi there"])
|
||
(let ([n (string-length s)] [p (open-input-file "testfile.ss")])
|
||
(and (eqv? (file-length p) (+ 2000 n))
|
||
(eq? (read p) 'ho)
|
||
(eq? (read p) 'there)
|
||
(eqv? (file-position p) n)
|
||
(eqv? (file-position p 2000) (void))
|
||
(eq? (read p) 'hi)
|
||
(eq? (read p) 'there)
|
||
(= (file-position p) (file-length p) (+ 2000 n))
|
||
(eqv? (close-input-port p) (void)))))
|
||
)
|
||
|
||
(mat string-port-file-position
|
||
(let ([ip (open-input-string "hit me")])
|
||
(and (eq? (read ip) 'hit)
|
||
(eq? (file-position ip) 3)
|
||
(begin
|
||
(file-position ip 1)
|
||
(eq? (read ip) 'it))
|
||
(begin
|
||
(file-position ip 6)
|
||
(eof-object? (read ip)))
|
||
(begin
|
||
(file-position ip 0)
|
||
(eq? (read ip) 'hit))))
|
||
(error? (file-position (open-input-string "hi") 3))
|
||
(error? (file-position (open-input-string "hi") -1))
|
||
(let ()
|
||
(define f
|
||
(lambda (n)
|
||
(let ([op (open-output-string)])
|
||
(and (begin
|
||
(write 'ab op)
|
||
(eq? (file-position op) 2))
|
||
(begin
|
||
(file-position op 4)
|
||
(write 'ef op)
|
||
(eq? (file-position op) 6))
|
||
(begin
|
||
(file-position op 2)
|
||
(write 'cd op)
|
||
(eq? (file-position op) 4))
|
||
(begin
|
||
(set-port-length! op n)
|
||
(get-output-string op))))))
|
||
(and (equal? (f 6) "abcdef")
|
||
(equal? (f 4) "abcd")
|
||
(equal? (f 2) "ab")
|
||
(equal? (f 0) "")
|
||
(equal? (f 5) "abcde")
|
||
(let ((s (f 2000)))
|
||
(and s (= (string-length s) 2000)))))
|
||
(error? (file-position (open-output-string) -1))
|
||
)
|
||
|
||
(mat fresh-line
|
||
(procedure? fresh-line)
|
||
(error? (fresh-line 3))
|
||
(error? (fresh-line (open-input-string "hello")))
|
||
(equal?
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(fresh-line)
|
||
(fresh-line)
|
||
(display "hello")
|
||
(fresh-line)
|
||
(fresh-line)))
|
||
"hello\n")
|
||
(begin
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda ()
|
||
(fresh-line)
|
||
(fresh-line)
|
||
(display "hello")
|
||
(fresh-line)
|
||
(fresh-line))
|
||
'replace)
|
||
#t)
|
||
(call-with-input-file "testfile.ss"
|
||
(lambda (p)
|
||
(let ([s (make-string 100)])
|
||
(and
|
||
(= (block-read p s (string-length s)) 6)
|
||
(string=? (substring s 0 6) "hello\n")
|
||
(eof-object? (read-char p))))))
|
||
(begin
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda ()
|
||
(write-char #\a)
|
||
(fresh-line)
|
||
(flush-output-port)
|
||
(set-port-bol! (current-output-port) #f)
|
||
(fresh-line)
|
||
(write-char #\b)
|
||
(flush-output-port)
|
||
(set-port-bol! (current-output-port) #t)
|
||
(fresh-line)
|
||
(fresh-line)
|
||
(write-char #\c)
|
||
(fresh-line)
|
||
(fresh-line))
|
||
'replace)
|
||
#t)
|
||
(call-with-input-file "testfile.ss"
|
||
(lambda (p)
|
||
(let ([s (make-string 100)])
|
||
(and
|
||
(= (block-read p s (string-length s)) 6)
|
||
(string=? (substring s 0 6) "a\n\nbc\n")
|
||
(eof-object? (read-char p))))))
|
||
)
|
||
|
||
(mat char-ready?
|
||
(procedure? char-ready?)
|
||
(let ([x (open-input-string "a")])
|
||
(and (char-ready? x)
|
||
(eqv? (read-char x) #\a)
|
||
(char-ready? x)
|
||
(eof-object? (read-char x))))
|
||
)
|
||
|
||
(mat clear-input-port ; test interactively
|
||
(procedure? clear-input-port)
|
||
)
|
||
|
||
;;; pretty-equal? is like equal? except that it considers gensyms
|
||
;;; with equal print names to be equal and any two nans to be equal.
|
||
(define pretty-equal?
|
||
(rec equal?
|
||
(lambda (x y) ; mostly snarfed from 5_1.ss
|
||
(or (cond
|
||
[(eq? x y) #t]
|
||
[(pair? x)
|
||
(and (pair? y)
|
||
(equal? (car x) (car y))
|
||
(equal? (cdr x) (cdr y)))]
|
||
[(symbol? x)
|
||
(and (gensym? x)
|
||
(gensym? y)
|
||
(string=? (symbol->string x) (symbol->string y)))]
|
||
[(or (null? x) (null? y)) #f]
|
||
[(or (char? x) (char? y)) #f]
|
||
[(flonum? x)
|
||
(and (flonum? y)
|
||
(or (let ([nan? (lambda (x) (not (fl= x x)))])
|
||
(and (nan? x) (nan? y)))
|
||
(fl= x y)))]
|
||
[(number? x)
|
||
(and (number? y)
|
||
(if (exact? x)
|
||
(and (exact? y) (= x y))
|
||
(and (equal? (real-part x) (real-part y))
|
||
(equal? (imag-part x) (imag-part y)))))]
|
||
[(string? x) (and (string? y) (string=? x y))]
|
||
[(box? x) (and (box? y) (equal? (unbox x) (unbox y)))]
|
||
[(vector? x)
|
||
(and (vector? y)
|
||
(= (vector-length x) (vector-length y))
|
||
(let f ([i (- (vector-length x) 1)])
|
||
(or (< i 0)
|
||
(and (equal? (vector-ref x i) (vector-ref y i))
|
||
(f (1- i))))))]
|
||
[(fxvector? x)
|
||
(and (fxvector? y)
|
||
(= (fxvector-length x) (fxvector-length y))
|
||
(let f ([i (- (fxvector-length x) 1)])
|
||
(or (< i 0)
|
||
(and (fx= (fxvector-ref x i) (fxvector-ref y i))
|
||
(f (1- i))))))]
|
||
[(bytevector? x)
|
||
(and (bytevector? y)
|
||
(bytevector=? x y))]
|
||
[else #f])
|
||
(parameterize ([print-length 6] [print-level 3])
|
||
(display "----------------------\n")
|
||
(pretty-print x)
|
||
(pretty-print '=/=)
|
||
(pretty-print y)
|
||
(display "----------------------\n")
|
||
#f)))))
|
||
|
||
(mat pretty-print
|
||
(let ([pretty-copy
|
||
(lambda (ifn ofn)
|
||
(let ([ip (open-input-file ifn)]
|
||
[op (open-output-file ofn 'replace)])
|
||
(dynamic-wind
|
||
(lambda () #f)
|
||
(rec loop
|
||
(lambda ()
|
||
(let ([x (read ip)])
|
||
(or (eof-object? x)
|
||
(parameterize ([print-unicode #f])
|
||
(pretty-print x op)
|
||
(newline op)
|
||
(loop))))))
|
||
(lambda ()
|
||
(close-input-port ip)
|
||
(close-output-port op)))))])
|
||
(pretty-copy "prettytest.ss" "testfile.ss"))
|
||
(let ([p1 (open-input-file "prettytest.ss")]
|
||
[p2 (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
(lambda () #f)
|
||
(rec loop
|
||
(lambda ()
|
||
(let ([x1 (read p1)] [x2 (read p2)])
|
||
(unless (pretty-equal? x1 x2)
|
||
(errorf 'pretty-equal "~s is not equal to ~s" x1 x2))
|
||
(or (eof-object? x1) (loop)))))
|
||
(lambda ()
|
||
(close-input-port p1)
|
||
(close-input-port p2))))
|
||
(error? (pretty-format))
|
||
(error? (pretty-format 'foo 'x 'x))
|
||
(error? (pretty-format 3 'x))
|
||
(error? (pretty-format 'foo '(bad 0 ... ... 0 format)))
|
||
(list? (pretty-format 'let))
|
||
(let ([x (pretty-format 'let)])
|
||
(pretty-format 'let x)
|
||
(equal? x (pretty-format 'let)))
|
||
(string=?
|
||
(parameterize ([pretty-standard-indent 2] [pretty-one-line-limit 1])
|
||
(pretty-format 'frob '(frob (x 1 ...) 3 (x #f ...) 4 (x y 3 ...) ...))
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(pretty-print '(frob (alpha b c d)
|
||
(peter o n m)
|
||
(zero 1 2 3)
|
||
(nine 8 7 6))))))
|
||
"(frob (alpha\n b\n c\n d)\n (peter\n o\n n\n m)\n (zero 1\n 2\n 3)\n (nine 8\n 7\n 6))\n")
|
||
(eqv? (begin (pretty-format 'frob #f) (pretty-format 'frob)) #f)
|
||
(equal?
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(pretty-print ''#'#`#,#,@,,@`(a b c))))
|
||
"'#'#`#,#,@,,@`(a b c)\n")
|
||
)
|
||
|
||
(mat write
|
||
(let ([unpretty-copy
|
||
(lambda (ifn ofn)
|
||
(let ([ip (open-input-file ifn)]
|
||
[op (open-output-file ofn 'replace)])
|
||
(dynamic-wind
|
||
(lambda () #f)
|
||
(rec loop
|
||
(lambda ()
|
||
(let ([x (read ip)])
|
||
(or (eof-object? x)
|
||
(parameterize ([print-unicode #f])
|
||
(write x op)
|
||
(newline op)
|
||
(loop))))))
|
||
(lambda ()
|
||
(close-input-port ip)
|
||
(close-output-port op)))))])
|
||
(unpretty-copy "prettytest.ss" "testfile.ss"))
|
||
(let ([p1 (open-input-file "prettytest.ss")]
|
||
[p2 (open-input-file "testfile.ss")])
|
||
(dynamic-wind
|
||
(lambda () #f)
|
||
(rec loop
|
||
(lambda ()
|
||
(let ([x1 (read p1)] [x2 (read p2)])
|
||
(unless (pretty-equal? x1 x2)
|
||
(errorf 'pretty-equal "~s is not equal to ~s" x1 x2))
|
||
(or (eof-object? x1) (loop)))))
|
||
(lambda ()
|
||
(close-input-port p1)
|
||
(close-input-port p2))))
|
||
)
|
||
|
||
(mat fasl
|
||
(pretty-equal?
|
||
(begin
|
||
(call-with-port
|
||
(open-file-output-port "testfile.ss" (file-options replace))
|
||
(lambda (p) (fasl-write +nan.0 p)))
|
||
(call-with-port (open-file-input-port "testfile.ss") fasl-read))
|
||
(/ 0.0 0.0))
|
||
(let ([ls (with-input-from-file "prettytest.ss"
|
||
(rec f
|
||
(lambda ()
|
||
(let ([x (read)])
|
||
(if (eof-object? x) '() (cons x (f)))))))])
|
||
(define-record frob (x1 (uptr x2) (fixnum x3) (float x4) (double x5) (wchar_t x6) (integer-64 x7) (char x8) (unsigned-64 x9)))
|
||
(let ([x (make-frob '#(#&3+4i 3.456+723i 3/4) 7500000 (most-negative-fixnum) +nan.0 3.1415 #\x3d0
|
||
(- (expt 2 63) 5) #\$ (- (expt 2 64) 5))])
|
||
(define put-stuff
|
||
(lambda (p)
|
||
(fasl-write (cons x x) p)
|
||
(fasl-write (list +nan.0 +inf.0 -inf.0 -0.0) p)
|
||
(for-each (lambda (x) (fasl-write x p)) ls)))
|
||
(define (get-stuff fasl-read)
|
||
(lambda (p)
|
||
(let ([y (fasl-read p)])
|
||
(and (equal? ($record->vector (car y)) ($record->vector x))
|
||
(eq? (cdr y) (car y))
|
||
(pretty-equal? (fasl-read p) (list +nan.0 +inf.0 -inf.0 -0.0))
|
||
(let loop ([ls ls])
|
||
(let ([x1 (fasl-read p)] [x2 (if (null? ls) #!eof (car ls))])
|
||
(unless (pretty-equal? x1 x2)
|
||
(errorf #f "~s is not equal to ~s" x1 x2))
|
||
(or (eof-object? x1) (loop (cdr ls)))))))))
|
||
(call-with-port
|
||
(open-file-output-port "testfile.ss" (file-options replace))
|
||
put-stuff)
|
||
(and
|
||
(call-with-port
|
||
(open-file-input-port "testfile.ss")
|
||
(get-stuff fasl-read))
|
||
(call-with-port
|
||
(open-file-input-port "testfile.ss" (file-options compressed))
|
||
(get-stuff fasl-read))
|
||
(call-with-port
|
||
(open-file-input-port "testfile.ss" (file-options compressed))
|
||
(get-stuff (lambda (p)
|
||
(when (eof-object? (lookahead-u8 p)) (printf "done\n"))
|
||
(fasl-read p))))
|
||
(begin
|
||
(call-with-port
|
||
(open-file-output-port "testfile.ss" (file-options compressed replace))
|
||
put-stuff)
|
||
(call-with-port
|
||
(open-file-input-port "testfile.ss" (file-options compressed))
|
||
(get-stuff fasl-read)))
|
||
(call-with-port
|
||
(open-bytevector-input-port
|
||
(call-with-bytevector-output-port put-stuff))
|
||
(get-stuff fasl-read)))))
|
||
(eqv? (fasl-file "prettytest.ss" "testfile.ss") (void))
|
||
(let ([ls (with-input-from-file "prettytest.ss"
|
||
(rec f
|
||
(lambda ()
|
||
(let ([x (read)])
|
||
(if (eof-object? x) '() (cons x (f)))))))])
|
||
(call-with-port
|
||
(open-file-input-port "testfile.ss")
|
||
(lambda (p)
|
||
(let loop ([ls ls])
|
||
(let ([x1 (fasl-read p)] [x2 (if (null? ls) #!eof (car ls))])
|
||
(unless (pretty-equal? x1 x2)
|
||
(errorf #f "~s is not equal to ~s" x1 x2))
|
||
(or (eof-object? x1) (loop (cdr ls))))))))
|
||
(equal?
|
||
(with-interrupts-disabled
|
||
(let ([ls (cons (weak-cons 'a 'b) (weak-cons 'c (cons 'd (weak-cons 'e #f))))])
|
||
(call-with-port
|
||
(open-file-output-port "testfile.ss" (file-options replace))
|
||
(lambda (p) (fasl-write ls p))))
|
||
(let ([ls (call-with-port (open-file-input-port "testfile.ss") fasl-read)])
|
||
(list
|
||
(equal? ls '((a . b) c d e . #f))
|
||
(weak-pair? ls)
|
||
(weak-pair? (car ls))
|
||
(weak-pair? (cdr ls))
|
||
(weak-pair? (cddr ls))
|
||
(weak-pair? (cdddr ls)))))
|
||
'(#t #f #t #t #f #t))
|
||
)
|
||
|
||
(mat clear-output-port ; test interactively
|
||
(procedure? clear-output-port)
|
||
)
|
||
|
||
(mat flush-output-port ; test interactively
|
||
(procedure? flush-output-port)
|
||
)
|
||
|
||
;;; section 6-3:
|
||
|
||
(mat format
|
||
(equal? (format "abcde") "abcde")
|
||
(equal? (format "~s ~a ~c ~~ ~%" "hi" "there" #\X)
|
||
(string-append "\"hi\" there X ~ " (string #\newline)))
|
||
(equal? (format "~s" car) "#<procedure car>")
|
||
(equal? (format "~s" (lambda () #f)) "#<procedure>")
|
||
)
|
||
|
||
(mat printf
|
||
(let ([p (open-output-string)])
|
||
(parameterize ([current-output-port p])
|
||
(printf "~s:~s" 3 4))
|
||
(equal? (get-output-string p) "3:4"))
|
||
)
|
||
|
||
(mat fprintf
|
||
(let ([p (open-output-string)])
|
||
(fprintf p "~s.~s:~s" 'abc 345 "xyz")
|
||
(equal? (get-output-string p) "abc.345:\"xyz\""))
|
||
)
|
||
|
||
(mat cp1in-verify-format-warnings
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda () (import scheme) (format "~a~~~s" 5)))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda () (import scheme) (format "~a~a~a~s" 1 2 3 4 5 6)))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda () (import scheme) (format "~a~~~s" 5))))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda () (import scheme) (format "~a~a~a~s" 1 2 3 4 5 6))))))
|
||
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda () (import scheme) (printf "abc~s")))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda () (import scheme) (printf "~%~abc~adef~ag~s~~~%" 1 2 3 4 5)))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda () (import scheme) (printf "abc~s"))))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda () (import scheme) (printf "~%~abc~adef~ag~s~~~%" 1 2 3 4 5))))))
|
||
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda (p) (import scheme) (fprintf p "abc~s")))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(lambda (p) (import scheme) (fprintf p "~%~abc~adef~ag~s~~~%" 1 2 3 4 5)))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda (p) (import scheme) (fprintf p "abc~s"))))))
|
||
(warning? (parameterize ([#%$suppress-primitive-inlining #f])
|
||
(eval '(mat/cf (lambda (p) (import scheme) (fprintf p "~%~abc~adef~ag~s~~~%" 1 2 3 4 5))))))
|
||
)
|
||
|
||
(mat print-parameters
|
||
(equal? (parameterize ([print-level 3])
|
||
(format "~s" (let ([x (list 'a)]) (set-car! x x) x)))
|
||
"((((...))))")
|
||
(equal? (parameterize ([print-length 3])
|
||
(format "~s" (let ([x (list 'a)]) (set-cdr! x x) x)))
|
||
"(a a a ...)")
|
||
(equal? (parameterize ([print-graph #t])
|
||
(format "~s" (let ([x (list 'a)]) (set-car! x x) x)))
|
||
"#0=(#0#)")
|
||
(equal? (parameterize ([print-graph #t])
|
||
(format "~s" (let ([x (list 'a)]) (set-cdr! x x) x)))
|
||
"#0=(a . #0#)")
|
||
(equal? (parameterize ([print-graph #t])
|
||
(format "~s" (let ([x (list 'a)] [y (list 'b)])
|
||
(list x y y x))))
|
||
"(#0=(a) #1=(b) #1# #0#)")
|
||
(equal? (parameterize ([print-graph #t])
|
||
(format "~s" (let ([x (list 'a)] [y (list 'b)])
|
||
(vector x y y x))))
|
||
"#(#0=(a) #1=(b) #1# #0#)")
|
||
(equal? (parameterize ([print-graph #t])
|
||
(format "~s" '(#2# #2=#{a b})))
|
||
"(#0=#{a b} #0#)")
|
||
(error? (guard (c [(and (warning? c) (format-condition? c))
|
||
(apply errorf (condition-who c) (condition-message c) (condition-irritants c))])
|
||
(format "~s"
|
||
(let ([x (list '*)])
|
||
(set-car! x x)
|
||
(set-cdr! x x)
|
||
x))))
|
||
(equal? (parameterize ([print-vector-length #f])
|
||
(format "~s ~s" '#5(1 2 3) '#8vfx(5 7 9 8 8 9 -1)))
|
||
"#(1 2 3 3 3) #vfx(5 7 9 8 8 9 -1 -1)")
|
||
(equal? (parameterize ([print-vector-length #t])
|
||
(format "~s ~s" '#(1 2 3 3 3) '#vfx(5 7 9 8 8 9 -1 -1)))
|
||
"#5(1 2 3) #8vfx(5 7 9 8 8 9 -1)")
|
||
(equal? (parameterize ([print-vector-length #f])
|
||
(format "~a ~a" '#5(1 2 3) '#8vfx(5 7 9 8 8 9 -1)))
|
||
"#(1 2 3 3 3) #vfx(5 7 9 8 8 9 -1 -1)")
|
||
(equal? (parameterize ([print-vector-length #t])
|
||
(format "~a ~a" '#(1 2 3 3 3) '#vfx(5 7 9 8 8 9 -1 -1)))
|
||
"#(1 2 3 3 3) #vfx(5 7 9 8 8 9 -1 -1)")
|
||
(equal? (parameterize ([print-vector-length #f])
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(pretty-print '#5(1 2 3))
|
||
(pretty-print '#8vfx(5 7 9 8 8 9 -1)))))
|
||
"#(1 2 3 3 3)\n#vfx(5 7 9 8 8 9 -1 -1)\n")
|
||
(equal? (parameterize ([print-vector-length #t])
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(pretty-print '#(1 2 3 3 3))
|
||
(pretty-print '#vfx(5 7 9 8 8 9 -1 -1)))))
|
||
"#5(1 2 3)\n#8vfx(5 7 9 8 8 9 -1)\n")
|
||
(equal? (parameterize ([print-extended-identifiers #f])
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(for-each pretty-print '(1+ +++ .. |12| xyz aBc |-155| |.5e7| |.5e|)))))
|
||
"\\x31;+\n\\x2B;++\n\\x2E;.\n\\x31;2\nxyz\naBc\n\\x2D;155\n\\x2E;5e7\n\\x2E;5e\n")
|
||
(equal? (parameterize ([print-extended-identifiers #t])
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(for-each pretty-print '(1+ +++ .. |12| xyz aBc |-155| |.5e7| |.5e|)))))
|
||
"1+\n+++\n..\n\\x31;2\nxyz\naBc\n\\x2D;155\n\\x2E;5e7\n.5e\n")
|
||
(equal? (parameterize ([print-gensym #f])
|
||
(format "~s" '(#3# #3=#{g0 fool})))
|
||
"(g0 g0)")
|
||
(equal? (parameterize ([print-graph #t] [print-gensym #f])
|
||
(format "~s" '(#4# #4=#{g0 fool})))
|
||
"(#0=g0 #0#)")
|
||
(equal? (parameterize ([print-gensym 'pretty])
|
||
(format "~s" '(#5# #5=#{g0 fool})))
|
||
"(#:g0 #:g0)")
|
||
(equal? (parameterize ([print-graph #t] [print-gensym 'pretty])
|
||
(format "~s" '(#6# #6=#{g0 fool})))
|
||
"(#0=#:g0 #0#)")
|
||
(equal? (parameterize ([print-gensym 'pretty])
|
||
(format "~s" '(#7# #7=#:g0)))
|
||
"(#:g0 #:g0)")
|
||
(let ([g (gensym "x")])
|
||
(parameterize ([print-gensym 'pretty/suffix])
|
||
(equal? (format "~s" g) (format "~s" g))))
|
||
(do ([i 100 (fx- i 1)])
|
||
((fx= i 0) #t)
|
||
(let ([g (gensym "x")])
|
||
(unless (< (string-length (parameterize ([print-gensym 'pretty/suffix])
|
||
(format "~s" g)))
|
||
(string-length (parameterize ([print-gensym #t])
|
||
(format "~s" g))))
|
||
(error #f "failed"))))
|
||
(let ([g (gensym "x")])
|
||
(let ([x (with-input-from-string
|
||
(parameterize ([print-gensym 'pretty/suffix])
|
||
(format "~s" g))
|
||
read)])
|
||
(and (symbol? x) (not (gensym? x)))))
|
||
(equal? (parameterize ([print-gensym 'pretty/suffix])
|
||
(format "~s" '#{g0 cfdhkxfnlo6opm0x-c}))
|
||
"g0.cfdhkxfnlo6opm0x-c")
|
||
(equal? (parameterize ([print-graph #t] [print-gensym 'pretty])
|
||
(format "~s" '(#8# #8=#:g0)))
|
||
"(#0=#:g0 #0#)")
|
||
(equal? (parameterize ([print-brackets #t])
|
||
(let ([p (open-output-string)])
|
||
(pretty-print '(let ((x 3)) x) p)
|
||
(get-output-string p)))
|
||
(format "~a~%" "(let ([x 3]) x)"))
|
||
(equal? (parameterize ([print-brackets #f])
|
||
(let ([p (open-output-string)])
|
||
(pretty-print '(let ((x 3)) x) p)
|
||
(get-output-string p)))
|
||
(format "~a~%" "(let ((x 3)) x)"))
|
||
(equal? (parameterize ([case-sensitive #t])
|
||
(format "~s" (string->symbol "AbcDEfg")))
|
||
"AbcDEfg")
|
||
(equal? (format "~s" (read (open-input-string "abCdEfG")))
|
||
"abCdEfG")
|
||
(equal? (parameterize ([case-sensitive #f])
|
||
(format "~s" (read (open-input-string "abCdEfG"))))
|
||
"abcdefg")
|
||
(equal? (parameterize ([print-radix 36])
|
||
(format "~s" 35))
|
||
"#36rZ")
|
||
(equal? (parameterize ([print-radix 36])
|
||
(format "~a" 35))
|
||
"Z")
|
||
)
|
||
|
||
(mat general-port
|
||
(<= (port-input-index (console-input-port))
|
||
(port-input-size (console-input-port))
|
||
(string-length (port-input-buffer (console-input-port))))
|
||
(<= (port-input-count (console-input-port))
|
||
(string-length (port-input-buffer (console-input-port))))
|
||
(<= (port-output-index (console-output-port))
|
||
(port-output-size (console-output-port))
|
||
(string-length (port-output-buffer (console-output-port))))
|
||
(<= (port-output-count (console-output-port))
|
||
(string-length (port-output-buffer (console-output-port))))
|
||
(equal?
|
||
(let ([sip (open-string-input-port "hello")])
|
||
(let ([n1 (port-input-count sip)])
|
||
(read-char sip)
|
||
(list n1 (port-input-count sip))))
|
||
'(5 4))
|
||
(equal?
|
||
(let ([op (make-output-port (lambda args (error #f "oops")) (make-string 10))])
|
||
(let ([n1 (port-output-count op)])
|
||
(display "hey!" op)
|
||
(list n1 (port-output-count op))))
|
||
'(10 6))
|
||
(let ()
|
||
(define make-two-way-port
|
||
; no local buffering
|
||
; close-port passed through
|
||
(lambda (ip op)
|
||
(define handler
|
||
(lambda (msg . args)
|
||
(record-case (cons msg args)
|
||
[block-read (p s n) (block-read ip s n)]
|
||
[block-write (p s n) (block-write op s n)]
|
||
[char-ready? (p) (char-ready? ip)]
|
||
[clear-input-port (p) (clear-input-port ip)]
|
||
[clear-output-port (p) (clear-output-port op)]
|
||
[close-port (p)
|
||
(close-port ip)
|
||
(close-port op)
|
||
(mark-port-closed! p)]
|
||
; [file-length (p) #f]
|
||
[file-position (p . pos)
|
||
(if (null? pos)
|
||
(most-negative-fixnum)
|
||
(errorf 'two-way-port "cannot reposition"))]
|
||
[flush-output-port (p) (flush-output-port op)]
|
||
[peek-char (p) (peek-char ip)]
|
||
[port-name (p) "two-way port"]
|
||
[read-char (p) (read-char ip)]
|
||
[unread-char (c p) (unread-char c ip)]
|
||
[write-char (c p) (write-char c op)]
|
||
[else (errorf 'two-way-port "operation ~s not handled"
|
||
msg)])))
|
||
(make-input/output-port handler "" "")))
|
||
(let ([sip (open-input-string "far out")]
|
||
[sop (open-output-string)])
|
||
(let ([p1 (make-two-way-port sip sop)])
|
||
(and (port? p1)
|
||
(begin (write (read p1) p1)
|
||
(string=? (get-output-string sop) "far"))
|
||
(char-ready? p1)
|
||
(char=? (read-char p1) #\space)
|
||
(char=? (read-char p1) #\o)
|
||
(begin (unread-char #\o p1)
|
||
(char=? (read-char p1) #\o))
|
||
; can't count on clear-output-port doing anything for
|
||
; string output ports, so next two checks are bogus
|
||
#;(begin (write-char #\a p1)
|
||
(clear-output-port p1)
|
||
(string=? (get-output-string sop) ""))
|
||
(begin
|
||
(file-position sip (file-length sip))
|
||
(char-ready? p1))
|
||
(eof-object? (peek-char p1))
|
||
; make sure these don't error out
|
||
(eq? (clear-input-port p1) (void))
|
||
(eq? (clear-output-port p1) (void))
|
||
(begin (close-port p1) (port-closed? p1))
|
||
(port-closed? sip)
|
||
(port-closed? sop)))))
|
||
(let ()
|
||
(define make-broadcast-port
|
||
; local buffering
|
||
; closed-port not passed through
|
||
; critical sections used where necessary to protect against interrupts
|
||
; uses block-write to dump buffers to subordinate ports
|
||
; check cltl2 to see what it says about local buffering,
|
||
; and about passing through flush, clear, and close
|
||
; size set so that buffer always has room for character to be written,
|
||
; allowing buffer to be flushed as soon as it becomes full
|
||
(lambda ports
|
||
(define handler
|
||
(lambda (msg . args)
|
||
(record-case (cons msg args)
|
||
; [block-read (p s n) #f]
|
||
[block-write (p s n)
|
||
(unless (null? ports)
|
||
(with-interrupts-disabled
|
||
(flush-output-port p)
|
||
(for-each (lambda (p) (block-write p s n))
|
||
ports)))]
|
||
; [char-ready? (p) (char-ready? ip)]
|
||
; [clear-input-port (p) (clear-input-port ip)]
|
||
[clear-output-port (p) (set-port-output-index! p 0)]
|
||
[close-port (p)
|
||
(set-port-output-size! p 0)
|
||
(mark-port-closed! p)]
|
||
; [file-length (p) #f]
|
||
[file-position (p . pos)
|
||
(if (null? pos)
|
||
(most-negative-fixnum)
|
||
(errorf 'broadcast-port "cannot reposition"))]
|
||
[flush-output-port (p)
|
||
(with-interrupts-disabled
|
||
(unless (null? ports)
|
||
(let ([b (port-output-buffer p)]
|
||
[i (port-output-index p)])
|
||
(for-each (lambda (p) (block-write p b i))
|
||
ports)))
|
||
(set-port-output-index! p 0))]
|
||
; [peek-char (p) (peek-char ip)]
|
||
[port-name (p) "broadcast port"]
|
||
; [read-char (p) (read-char ip)]
|
||
; [unread-char (c p) (unread-char c ip)]
|
||
[write-char (c p)
|
||
(with-interrupts-disabled
|
||
(unless (null? ports)
|
||
(let ([b (port-output-buffer p)]
|
||
[i (port-output-index p)])
|
||
; could check here to be sure that we really need
|
||
; to flush
|
||
(string-set! b i c)
|
||
(for-each (lambda (p)
|
||
(block-write p b (fx+ i 1)))
|
||
ports)))
|
||
(set-port-output-index! p 0))]
|
||
[else (errorf 'broadcast-port "operation ~s not handled"
|
||
msg)])))
|
||
(let ([len 1024])
|
||
(let ([p (make-output-port handler (make-string len))])
|
||
(set-port-output-size! p (fx- len 1))
|
||
p))))
|
||
(let ([p (make-broadcast-port)])
|
||
(and (port? p)
|
||
(let ([x (make-string 1000 #\a)])
|
||
(let loop ([i 1000])
|
||
(if (fx= i 0)
|
||
(fx<= (port-output-index p)
|
||
(port-output-size p)
|
||
(string-length (port-output-buffer p)))
|
||
(begin (display x p)
|
||
(loop (fx- i 1))))))
|
||
(begin (close-port p) (port-closed? p))))
|
||
(let ([sop (open-output-string)])
|
||
(let ([p (make-broadcast-port sop sop)])
|
||
(and (port? p)
|
||
(let ([x "abcde"])
|
||
(display x p)
|
||
(and (string=? (get-output-string sop) "")
|
||
(begin (flush-output-port p)
|
||
(string=? (get-output-string sop)
|
||
(string-append x x)))))
|
||
(begin (close-output-port p) (port-closed? p))))))
|
||
|
||
(let ()
|
||
(define make-transcript-port
|
||
; local buffering; run into problems with unread-char and
|
||
; clear-output-port otherwise
|
||
; close-port passed through to tp only
|
||
(lambda (ip op tp)
|
||
(define handler
|
||
(lambda (msg . args)
|
||
(record-case (cons msg args)
|
||
[block-read (p str cnt)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-input-buffer p)]
|
||
[i (port-input-index p)]
|
||
[s (port-input-size p)])
|
||
(if (< i s)
|
||
(let ([cnt (fxmin cnt (fx- s i))])
|
||
(do ([i i (fx+ i 1)]
|
||
[j 0 (fx+ j 1)])
|
||
((fx= j cnt)
|
||
(set-port-input-index! p i)
|
||
cnt)
|
||
(string-set! str j (string-ref b i))))
|
||
(let ([cnt (block-read ip str cnt)])
|
||
(unless (eof-object? cnt)
|
||
(block-write tp str cnt))
|
||
cnt))))]
|
||
[char-ready? (p)
|
||
(or (< (port-input-index p) (port-input-size p))
|
||
(char-ready? ip))]
|
||
[clear-input-port (p)
|
||
; set size to zero rather than index to size
|
||
; in order to invalidate unread-char
|
||
(set-port-input-size! p 0)]
|
||
[clear-output-port (p) (set-port-output-index! p 0)]
|
||
[close-port (p)
|
||
(flush-output-port p)
|
||
(close-port tp)
|
||
(set-port-output-size! p 0)
|
||
(set-port-input-size! p 0)
|
||
(mark-port-closed! p)]
|
||
; [file-length (p) #f]
|
||
[file-position (p . pos)
|
||
(if (null? pos)
|
||
(most-negative-fixnum)
|
||
(errorf 'transcript-port "cannot reposition"))]
|
||
[flush-output-port (p)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-output-buffer p)]
|
||
[i (port-output-index p)])
|
||
(block-write op b i)
|
||
(block-write tp b i)
|
||
(set-port-output-index! p 0)
|
||
(flush-output-port op)
|
||
(flush-output-port tp)))]
|
||
[peek-char (p)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-input-buffer p)]
|
||
[i (port-input-index p)]
|
||
[s (port-input-size p)])
|
||
(if (fx< i s)
|
||
(string-ref b i)
|
||
(begin (flush-output-port p)
|
||
(let ([s (block-read ip b)])
|
||
(if (eof-object? s)
|
||
s
|
||
(begin (block-write tp b s)
|
||
(set-port-input-size! p s)
|
||
(string-ref b 0))))))))]
|
||
[port-name (p) "transcript"]
|
||
[read-char (p)
|
||
(with-interrupts-disabled
|
||
(let ([c (peek-char p)])
|
||
(unless (eof-object? c)
|
||
(set-port-input-index! p
|
||
(fx+ (port-input-index p) 1)))
|
||
c))]
|
||
[unread-char (c p)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-input-buffer p)]
|
||
[i (port-input-index p)]
|
||
[s (port-input-size p)])
|
||
(when (fx= i 0)
|
||
(errorf 'unread-char
|
||
"tried to unread too far on ~s"
|
||
p))
|
||
(set-port-input-index! p (fx- i 1))
|
||
; following could be skipped; supposed to be
|
||
; same character
|
||
(string-set! b (fx- i 1) c)))]
|
||
[write-char (c p)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-output-buffer p)]
|
||
[i (port-output-index p)]
|
||
[s (port-output-size p)])
|
||
(string-set! b i c)
|
||
; could check here to be sure that we really need
|
||
; to flush
|
||
(block-write op b (fx+ i 1))
|
||
(block-write tp b (fx+ i 1))
|
||
(set-port-output-index! p 0)))]
|
||
[block-write (p str cnt)
|
||
(with-interrupts-disabled
|
||
(let ([b (port-output-buffer p)]
|
||
[i (port-output-index p)])
|
||
; flush buffered data
|
||
(when (fx> i 0)
|
||
(block-write op b i)
|
||
(block-write tp b i))
|
||
; write new data
|
||
(block-write op str cnt)
|
||
(block-write tp str cnt)
|
||
(set-port-output-index! p 0)))]
|
||
[else (errorf 'transcript-port "operation ~s not handled"
|
||
msg)])))
|
||
(let ([ib (make-string 100)] [ob (make-string 100)])
|
||
(let ([p (make-input/output-port handler ib ob)])
|
||
(if (char-ready? ip)
|
||
; kludge so that old input doesn't show up after later
|
||
; output (e.g., input newline after output prompt)
|
||
(let ((n (block-read ip ib (string-length ib))))
|
||
(if (eof-object? n)
|
||
(set-port-input-size! p 0)
|
||
(set-port-input-size! p n)))
|
||
(set-port-input-size! p 0))
|
||
(set-port-output-size! p (fx- (string-length ob) 1))
|
||
p))))
|
||
; (define-record tp-frame (cip cop tp))
|
||
; (define tp-stack '())
|
||
; (define transcript-on
|
||
; (lambda (fn)
|
||
; (with-interrupts-disabled
|
||
; (let ((cip (console-input-port))
|
||
; (cop (console-output-port)))
|
||
; (let ((tp (make-transcript-port cip cop
|
||
; (open-output-file fn 'replace))))
|
||
; (set! tp-stack (cons (make-tp-frame cip cop tp) tp-stack))
|
||
; (console-output-port tp)
|
||
; (console-input-port tp)
|
||
; (when (eq? (current-input-port) cip)
|
||
; (current-input-port tp))
|
||
; (when (eq? (current-output-port) cop)
|
||
; (current-output-port tp)))))))
|
||
; (define transcript-off
|
||
; (lambda ()
|
||
; (with-interrupts-disabled
|
||
; (when (null? tp-stack) (errorf 'transcript-off "no transcript running"))
|
||
; (let ((frame (car tp-stack)))
|
||
; (let ((cip (tp-frame-cip frame))
|
||
; (cop (tp-frame-cop frame))
|
||
; (tp (tp-frame-tp frame)))
|
||
; (console-input-port cip)
|
||
; (console-output-port cop)
|
||
; (when (eq? (current-input-port) tp) (current-input-port cip))
|
||
; (when (eq? (current-output-port) tp) (current-output-port cop))
|
||
; (set! tp-stack (cdr tp-stack))
|
||
; (close-port tp))))))
|
||
(let ([ip (open-input-string (format "2"))]
|
||
[op (open-output-string)]
|
||
[tp (open-output-string)])
|
||
(let ([p (make-transcript-port ip op tp)])
|
||
(and (begin (display "1" p) (eq? (read p) 2))
|
||
(begin (display "3" p)
|
||
(flush-output-port p)
|
||
(and (string=? (get-output-string op) "13")
|
||
; 2 doesn't show up since we scan past available
|
||
; input (see "kludge" above)
|
||
(string=? (get-output-string tp) "13")))
|
||
(begin (close-port p)
|
||
(and (port-closed? p) (port-closed? tp)))))))
|
||
)
|
||
|
||
(mat port-handler
|
||
(begin (set! ph (port-handler (current-output-port)))
|
||
(procedure? ph))
|
||
(string? (ph 'port-name (current-output-port)))
|
||
(error? (ph))
|
||
(error? (ph 'foo))
|
||
(error? (ph 'foo (current-output-port)))
|
||
(error? (ph 'read-char))
|
||
(error? (ph 'write-char))
|
||
(error? (ph 'write-char 3))
|
||
(error? (ph 'write-char (current-input-port)))
|
||
(error? (ph 'write-char 'a (current-output-port)))
|
||
(error? (ph 'write-char #\a 'a))
|
||
(error? (ph 'write-char #\a (open-input-string "hello")))
|
||
(error? (ph 'write-char #\a (current-output-port) 'a))
|
||
(boolean? (ph 'char-ready? (current-input-port)))
|
||
)
|
||
|
||
(mat char-name
|
||
(eqv? (char-name 'space) #\space)
|
||
(eqv? (char-name #\space) 'space)
|
||
(eqv? (char-name 'tab) #\tab)
|
||
(eqv? (char-name #\tab) 'tab)
|
||
(eqv? (char-name 'return) #\return)
|
||
(eqv? (char-name #\return) 'return)
|
||
(eqv? (char-name 'page) #\page)
|
||
(eqv? (char-name #\page) 'page)
|
||
(eqv? (char-name 'linefeed) #\linefeed)
|
||
(eqv? (char-name #\linefeed) 'newline)
|
||
(eqv? (char-name 'newline) #\newline)
|
||
(eqv? (char-name #\newline) 'newline)
|
||
(eqv? (char-name #\backspace) 'backspace)
|
||
(eqv? (char-name 'backspace) #\backspace)
|
||
(eqv? (char-name #\rubout) 'delete)
|
||
(eqv? (char-name 'rubout) #\rubout)
|
||
(eqv? (char-name #\nul) 'nul)
|
||
(eqv? (char-name 'nul) #\nul)
|
||
(eqv? (char-name 'foo) #f)
|
||
(eqv? (char-name 'delete) #\delete)
|
||
(eqv? (char-name #\delete) 'delete)
|
||
(eqv? (char-name 'vtab) #\vtab)
|
||
(eqv? (char-name #\vtab) 'vtab)
|
||
(eqv? (char-name 'alarm) #\alarm)
|
||
(eqv? (char-name #\alarm) 'alarm)
|
||
(eqv? (char-name 'esc) #\esc)
|
||
(eqv? (char-name #\esc) 'esc)
|
||
(error? (read (open-input-string "#\\foo")))
|
||
(and (eqv? (char-name 'foo #\003) (void))
|
||
(eqv? (char-name 'foo) #\003)
|
||
(eqv? (char-name #\003) 'foo)
|
||
(eqv? (read (open-input-string "#\\foo")) #\003))
|
||
(equal?
|
||
(begin
|
||
(char-name 'foo #f)
|
||
(list (char-name 'foo) (char-name #\003)))
|
||
'(#f #f))
|
||
(error? (read (open-input-string "#\\new\\line")))
|
||
(error? (read (open-input-string "#\\new\\x6c;ine")))
|
||
)
|
||
|
||
(mat string-escapes
|
||
(eqv? (string-ref "ab\b" 2) #\backspace)
|
||
(eqv? (string-ref "\n" 0) #\newline)
|
||
(eqv? (string-ref "a\fb" 1) #\page)
|
||
(eqv? (string-ref "ab\r" 2) #\return)
|
||
(eqv? (string-ref "\t" 0) #\tab)
|
||
(eqv? (string-ref "\a\v" 0) #\bel)
|
||
(eqv? (string-ref "\a\v" 1) #\vt)
|
||
(eqv? (string-ref "\000" 0) #\nul)
|
||
(eqv? (string-ref "\x00;" 0) #\nul)
|
||
(eqv? (string-ref "a\x20;b" 1) #\space)
|
||
(eqv? (string-ref "\\\"\'" 0) #\\)
|
||
(eqv? (string-ref "\\\"\'" 1) #\")
|
||
(eqv? (string-ref "\\\"\'" 2) #\')
|
||
(= (char->integer (string-ref "a\012" 1)) #o12 10)
|
||
(= (char->integer (string-ref "a\015" 1)) #o15 13)
|
||
(= (char->integer (string-ref "a\177" 1)) #o177 127)
|
||
(= (char->integer (string-ref "a\377" 1)) #o377 255)
|
||
(error? (read (open-input-string "\"ab\\\"")))
|
||
(error? (read (open-input-string "\"ab\\0\"")))
|
||
(error? (read (open-input-string "\"ab\\01\"")))
|
||
(error? (read (open-input-string "\"ab\\*\"")))
|
||
(error? (read (open-input-string "\"ab\\x\"")))
|
||
(error? (read (open-input-string "\"ab\\x*\"")))
|
||
(error? (read (open-input-string "\"ab\\xg\"")))
|
||
(equal? (format "~s" "\bab\nc\f\rd\t\v\a") "\"\\bab\\nc\\f\\rd\\t\\v\\a\"")
|
||
)
|
||
|
||
(mat read-token
|
||
(let ([ip (open-input-string "(cons 33 #;hello \"rot\")")])
|
||
(and (let-values ([vals (read-token ip)])
|
||
(equal? vals '(lparen #f 0 1)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(atomic cons 1 5)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(atomic 33 6 8)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(quote datum-comment 9 11)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(atomic hello 11 16)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(atomic "rot" 17 22)))
|
||
(let-values ([vals (read-token ip)])
|
||
(equal? vals '(rparen #f 22 23)))))
|
||
(let ()
|
||
(define with-input-from-string
|
||
(lambda (s p)
|
||
(parameterize ([current-input-port (open-input-string s)])
|
||
(p))))
|
||
(with-input-from-string "\n#17#\n"
|
||
(lambda ()
|
||
(let-values ([vals (read-token)])
|
||
(equal? vals '(insert 17 1 5))))))
|
||
(let ()
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display "\n#eat\n"))
|
||
'replace)
|
||
#t)
|
||
(error?
|
||
(let* ([ip (open-file-input-port "testfile.ss")]
|
||
[sfd (#%$source-file-descriptor "testfile.ss" ip)]
|
||
[ip (transcoded-port ip (native-transcoder))])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (read-token ip sfd))
|
||
(lambda () (close-input-port ip)))))
|
||
(let ()
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display "\neat\n"))
|
||
'replace)
|
||
#t)
|
||
; $transcoded-source-port is no more
|
||
#;(equal?
|
||
(let-values ([vals (let* ([ip (open-file-input-port "testfile.ss")]
|
||
[sfd (#%$source-file-descriptor "testfile.ss" ip)]
|
||
[ip (#%$transcoded-source-port ip (native-transcoder))])
|
||
(dynamic-wind
|
||
void
|
||
(lambda () (read-token ip sfd))
|
||
(lambda () (close-input-port ip))))])
|
||
vals)
|
||
'(atomic eat 1 4))
|
||
)
|
||
|
||
(define read-test
|
||
(lambda (s)
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display s))
|
||
'replace)
|
||
(load "testfile.ss" values)
|
||
#t))
|
||
(define load-test
|
||
(lambda (s)
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display s))
|
||
'replace)
|
||
(load "testfile.ss")
|
||
#t))
|
||
(define compile-test
|
||
(lambda (s)
|
||
(with-output-to-file "testfile.ss"
|
||
(lambda () (display s))
|
||
'replace)
|
||
(compile-file "testfile.ss")
|
||
(load "testfile.so")
|
||
#t))
|
||
|
||
(define-syntax xmat
|
||
(syntax-rules ()
|
||
[(_ string ...)
|
||
(begin
|
||
(mat read-test (error? (read-test string)) ...)
|
||
(mat load-test (error? (load-test string)) ...)
|
||
(mat compile-test (error? (compile-test string)) ...))]))
|
||
|
||
(begin (define-record f800 (a b)) (record-reader "zinjanthropus" (type-descriptor f800)))
|
||
(begin (define-record $acyclic ((immutable notme))) (record-reader '$acyclic (type-descriptor $acyclic)))
|
||
|
||
(xmat
|
||
"; Test error \"fasl object created by different release\"\n; This one is the list (a b c d) created by version 5.9b\n\n#@ |