123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- ; Part of Scheme 48 1.9. See file COPYING for notices and license.
- ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
- ; Dump and restore
- ; Unix has special meanings for
- ; ETX, FS, DEL, ETB, NAK, DC2, EOT, EM (or SUB?), DC3, DC1, SI, SYN,
- ; 3 28 127 23 21 18 4 25 26 19 17 15 22
- ; so avoid using them.
- (define type/null #\n)
- (define type/true #\t)
- (define type/false #\f)
- (define type/unspecific #\u)
- (define type/pair #\p) ;obj1 obj2
- (define type/string #\s) ;length chars
- (define type/number #\i) ;#chars rep
- (define type/symbol #\y) ;length chars
- (define type/char #\c) ;char
- (define type/vector #\v) ;length objects
- (define type/template #\a) ;length objects
- (define type/code-vector #\k) ;length bytes (each byte is 2 hex digits?)
- (define type/location #\l) ;uid
- (define type/closure #\q) ;template-info
- (define type/ellipsis #\e)
- (define type/random #\r)
- ; Recursive entry
- (define (dump obj write-char depth)
- (cond ((null? obj) (dump-type type/null write-char))
- ((eq? obj #t) (dump-type type/true write-char))
- ((eq? obj #f) (dump-type type/false write-char))
- ((pair? obj) (dump-pair obj write-char depth))
- ;; Template case needs to precede vector case
- ((template? obj) (dump-template obj write-char depth))
- ((vector? obj) (dump-vector obj write-char depth))
- ((symbol? obj) (dump-symbol obj write-char))
- ((number? obj) (dump-number obj write-char))
- ((string? obj) (dump-string obj write-char))
- ((char? obj) (dump-char-literal obj write-char))
- ((code-vector? obj) (dump-code-vector obj write-char))
- ((location? obj) (dump-location obj write-char))
- ((unspecific? obj) (dump-type type/unspecific write-char))
- ((closure? obj) (dump-closure obj write-char))
- (else (dump-random obj write-char depth))))
- (define (restore read-char)
- (let ((type (restore-type read-char)))
- ((vector-ref restorers (char->ascii type)) type read-char)))
-
- (define restorers
- (make-vector 256 (lambda (type read-char)
- ;; Invalid type
- (assertion-violation 'restore "invalid type code" type))))
- (define (define-restorer! type proc)
- (vector-set! restorers (char->ascii type) proc))
- ; Particular dumpers & restorers
- (define-restorer! type/null (lambda (c read-char) '()))
- (define-restorer! type/false (lambda (c read-char) #f))
- (define-restorer! type/true (lambda (c read-char) #t))
- (define-restorer! type/unspecific (lambda (c read-char) (if #f #f)))
- ; Pairs
- (define (dump-pair obj write-char depth)
- (if (= depth 0)
- (dump-ellipsis obj write-char)
- (let ((depth (- depth 1)))
- (dump-type type/pair write-char)
- (dump (car obj) write-char depth)
- (dump (cdr obj) write-char depth))))
- (define-restorer! type/pair
- (lambda (c write-char)
- c ;ignored
- (let ((the-car (restore write-char)))
- (cons the-car (restore write-char)))))
- ; Symbols
- (define (dump-symbol obj write-char)
- (dump-type type/symbol write-char)
- (dump-a-string (symbol-case-converter (symbol->string obj)) write-char))
- (define-restorer! type/symbol
- (lambda (c read-char)
- c ;ignored
- (string->symbol (symbol-case-converter (restore-a-string read-char)))))
- ; Numbers
- ; <space> ... _ represent 0 ... 63,
- ; {<space> ... {_ represent 64 ... 127, -- { is ascii 123
- ; |<space> ... |_ represent 128 ... 191, -- | is ascii 124
- ; }<space> ... }_ represent 192 ... 256. -- } is ascii 125
- (define (dump-number n write-char)
- (if (not (communicable-number? n))
- (assertion-violation 'dump-number "can't dump this number" n))
- (if (and (integer? n)
- (>= n 0)
- (< n 256))
- (dump-byte n write-char)
- (begin (dump-type type/number write-char)
- ;; Note logarithmic recursion
- (dump-a-string (number->string n comm-radix) write-char))))
- (define (communicable-number? n) #t) ;this gets redefined in client
- (define (dump-byte n write-char) ;Dump a number between 0 and 255
- (if (< n 64)
- (write-char (ascii->char (+ n ascii-space)))
- (begin (write-char (ascii->char (+ (arithmetic-shift n -6)
- 122)))
- (write-char (ascii->char (+ (bitwise-and n 63)
- ascii-space))))))
- (define ascii-space (char->ascii #\space)) ;32
- (define (restore-small-integer c read-char)
- (- (char->ascii c) ascii-space))
- (do ((i (+ ascii-space 63) (- i 1)))
- ((< i ascii-space))
- (define-restorer! (ascii->char i) restore-small-integer))
- (define (restore-medium-integer c read-char)
- (+ (arithmetic-shift (- (char->ascii c) 122) 6)
- (- (char->ascii (read-char)) ascii-space)))
- (do ((i 123 (+ i 1)))
- ((> i 125))
- (define-restorer! (ascii->char i) restore-medium-integer))
- (define (restore-number read-char)
- (let ((c (read-char)))
- (if (char=? c type/number)
- (string->number (restore-a-string read-char) comm-radix)
- (let ((n (char->ascii c)))
- (if (> n 122)
- (restore-medium-integer c read-char)
- (- n ascii-space))))))
- (define-restorer! type/number
- (lambda (c read-char)
- c ;ignored
- (string->number (restore-a-string read-char) comm-radix)))
- (define comm-radix 16)
- ; String literals
- (define (dump-string obj write-char)
- (dump-type type/string write-char)
- (dump-a-string obj write-char))
- (define-restorer! type/string
- (lambda (c read-char)
- c ;ignored
- (restore-a-string read-char)))
- ; Characters
- (define (dump-char-literal obj write-char)
- (dump-type type/char write-char)
- (dump-a-char obj write-char))
- (define-restorer! type/char
- (lambda (c read-char)
- c ;ignored
- (restore-a-char read-char)))
- ; Vectors
- (define (dump-vector obj write-char depth)
- (dump-vector-like obj write-char depth
- type/vector vector-length vector-ref))
- (define (dump-template obj write-char depth)
- (dump-vector-like obj write-char depth
- type/template template-length template-ref))
- (define (dump-vector-like obj write-char depth type vector-length vector-ref)
- (if (= depth 0)
- (dump-ellipsis obj write-char)
- (let ((depth (- depth 1))
- (len (vector-length obj)))
- (dump-type type write-char)
- (dump-length len write-char)
- (do ((i 0 (+ i 1)))
- ((= i len) 'done)
- (dump (vector-ref obj i) write-char depth)))))
- (define (restore-vector-like make-vector vector-set!)
- (lambda (c read-char)
- c ;ignored
- (let* ((len (restore-length read-char))
- (v (make-vector len #\?)))
- (do ((i 0 (+ i 1)))
- ((= i len) v)
- (vector-set! v i (restore read-char))))))
- (define-restorer! type/vector
- (restore-vector-like make-vector vector-set!))
- (define-restorer! type/template
- (restore-vector-like make-template template-set!))
-
- ; Code vectors
- (define (dump-code-vector obj write-char)
- (dump-type type/code-vector write-char)
- (let ((len (code-vector-length obj)))
- (dump-length len write-char)
- (do ((i 0 (+ i 1)))
- ((= i len) 'done)
- (dump-byte (code-vector-ref obj i) write-char))))
- (define-restorer! type/code-vector
- (lambda (c read-char)
- c ;ignored
- (let* ((len (restore-length read-char))
- (cv (make-code-vector len 0)))
- (do ((i 0 (+ i 1)))
- ((= i len) cv)
- (code-vector-set! cv i
- (restore-number read-char))))))
- ; Locations
- (define (dump-location obj write-char)
- (dump-type type/location write-char)
- (dump-number (location->uid obj) write-char))
- (define (location->uid obj)
- (or ((fluid $dump-index) obj)
- (location-id obj)))
- (define-restorer! type/location
- (lambda (c read-char)
- c ;ignored
- (uid->location (restore-number read-char))))
- (define (uid->location uid)
- (or ((fluid $restore-index) uid)
- (table-ref uid->location-table uid)
- (let ((loc (make-undefined-location uid)))
- (note-location! loc)
- loc)))
- (define $restore-index (make-fluid (lambda (uid) #f)))
- (define uid->location-table (make-table))
- (define (note-location! den)
- (table-set! uid->location-table
- (location-id den)
- den))
- (define $dump-index (make-fluid (lambda (loc) #f)))
- ; For simulation purposes, it's better for location uid's not to
- ; conflict with any that might be in the base Scheme 48 system. (In the
- ; real server system there isn't any base Scheme 48 system, so there's
- ; no danger of conflict.)
- ; (define location-uid-origin 5000)
- ; Closure
- (define (dump-closure obj write-char)
- (dump-type type/closure write-char)
- (let ((id (template-info (closure-template obj))))
- (dump-number (if (integer? id) id 0) write-char)))
- (define-restorer! type/closure
- (lambda (c read-char)
- c ;ignored
- (make-random (list 'closure (restore-number read-char)))))
- ; Random
- (define random-type (make-record-type 'random '(disclosure)))
- (define make-random (record-constructor random-type '(disclosure)))
- (define-record-discloser random-type
- (let ((d (record-accessor random-type 'disclosure)))
- (lambda (r) (cons "Remote" (d r)))))
- (define (dump-random obj write-char depth)
- (dump-type type/random write-char)
- (dump (or (disclose obj) (list '?))
- write-char
- depth))
- (define-restorer! type/random
- (lambda (c read-char)
- (make-random (restore read-char))))
- ; Ellipsis
- (define (dump-ellipsis obj write-char)
- (dump-type type/ellipsis write-char))
- (define-restorer! type/ellipsis
- (lambda (c read-char) (make-random (list (string->symbol "---")))))
- ; Auxiliaries:
- ; Strings (not necessarily preceded by type code)
- (define (dump-a-string obj write-char)
- (let ((len (string-length obj)))
- (dump-length len write-char)
- (do ((i 0 (+ i 1)))
- ((= i len) 'done)
- (dump-a-char (string-ref obj i) write-char))))
- (define (restore-a-string read-char)
- (let* ((len (restore-length read-char))
- (str (make-string len #\?)))
- (do ((i 0 (+ i 1)))
- ((= i len) str)
- (string-set! str i (restore-a-char read-char)))))
- (define (dump-a-char c write-char)
- (write-char c))
- (define (restore-a-char read-char)
- (read-char))
- ; Type characters
- (define (dump-type c write-char)
- (write-char c))
- (define (restore-type read-char)
- (read-char))
- (define dump-length dump-number)
- (define restore-length restore-number)
- ;(define char->ascii char->integer) -- defined in p-features.scm
- ;(define ascii->char integer->char) -- ditto
- ; Miscellaneous support
- (define (unspecific? obj)
- (eq? obj *unspecific*))
- (define *unspecific* (if #f #f)) ;foo
- ;(define (integer->digit-char n)
- ; (ascii->char (+ n (if (< n 10) ascii-zero a-minus-ten))))
- ;
- ;(define (digit-char->integer c)
- ; (cond ((char-numeric? c)
- ; (- (char->ascii c) ascii-zero))
- ; ((char=? c #\#) 0)
- ; (else
- ; (- (char->ascii (char-downcase c)) a-minus-ten))))
- ;
- ;(define ascii-zero (char->ascii #\0))
- ;
- ;(define a-minus-ten (- (char->integer #\a) 10))
- ; These modified from s48/boot/transport.scm
- (define (string-case-converter string)
- (let ((new (make-string (string-length string) #\?)))
- (do ((i 0 (+ i 1)))
- ((>= i (string-length new)) new)
- (string-set! new i (invert-case (string-ref string i))))))
- (define (invert-case c)
- (cond ((char-upper-case? c) (char-downcase c))
- ((char-lower-case? c) (char-upcase c))
- (else c)))
- (define symbol-case-converter
- (if (char=? (string-ref (symbol->string 't) 0) #\t)
- (lambda (string) string)
- string-case-converter))
- ; ASCII
- ; !"#$%&'()*+,-./0123456789:;<=>?
- ; @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
- ; `abcdefghijklmnopqrstuvwxyz{|}~
- ;(define (tst x)
- ; (let ((l '()))
- ; (dump x (lambda (c) (set! l (cons c l))) -1)
- ; (let ((l (reverse l)))
- ; (restore (lambda ()
- ; (let ((c (car l)))
- ; (set! l (cdr l))
- ; c))))))
- ;(define cwcc call-with-current-continuation)
- ;
- ;(define (tst x)
- ; (letrec ((write-cont (lambda (ignore)
- ; (dump x
- ; (lambda (c)
- ; (cwcc (lambda (k)
- ; (set! write-cont k)
- ; (read-cont c))))
- ; -1)))
- ; (read-cont #f))
- ; (restore (lambda ()
- ; (cwcc (lambda (k)
- ; (set! read-cont k)
- ; (write-cont 'ignore)))))))
|