dump.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Dump and restore
  4. ; Unix has special meanings for
  5. ; ETX, FS, DEL, ETB, NAK, DC2, EOT, EM (or SUB?), DC3, DC1, SI, SYN,
  6. ; 3 28 127 23 21 18 4 25 26 19 17 15 22
  7. ; so avoid using them.
  8. (define type/null #\n)
  9. (define type/true #\t)
  10. (define type/false #\f)
  11. (define type/unspecific #\u)
  12. (define type/pair #\p) ;obj1 obj2
  13. (define type/string #\s) ;length chars
  14. (define type/number #\i) ;#chars rep
  15. (define type/symbol #\y) ;length chars
  16. (define type/char #\c) ;char
  17. (define type/vector #\v) ;length objects
  18. (define type/template #\a) ;length objects
  19. (define type/code-vector #\k) ;length bytes (each byte is 2 hex digits?)
  20. (define type/location #\l) ;uid
  21. (define type/closure #\q) ;template-info
  22. (define type/ellipsis #\e)
  23. (define type/random #\r)
  24. ; Recursive entry
  25. (define (dump obj write-char depth)
  26. (cond ((null? obj) (dump-type type/null write-char))
  27. ((eq? obj #t) (dump-type type/true write-char))
  28. ((eq? obj #f) (dump-type type/false write-char))
  29. ((pair? obj) (dump-pair obj write-char depth))
  30. ;; Template case needs to precede vector case
  31. ((template? obj) (dump-template obj write-char depth))
  32. ((vector? obj) (dump-vector obj write-char depth))
  33. ((symbol? obj) (dump-symbol obj write-char))
  34. ((number? obj) (dump-number obj write-char))
  35. ((string? obj) (dump-string obj write-char))
  36. ((char? obj) (dump-char-literal obj write-char))
  37. ((code-vector? obj) (dump-code-vector obj write-char))
  38. ((location? obj) (dump-location obj write-char))
  39. ((unspecific? obj) (dump-type type/unspecific write-char))
  40. ((closure? obj) (dump-closure obj write-char))
  41. (else (dump-random obj write-char depth))))
  42. (define (restore read-char)
  43. (let ((type (restore-type read-char)))
  44. ((vector-ref restorers (char->ascii type)) type read-char)))
  45. (define restorers
  46. (make-vector 256 (lambda (type read-char)
  47. ;; Invalid type
  48. (assertion-violation 'restore "invalid type code" type))))
  49. (define (define-restorer! type proc)
  50. (vector-set! restorers (char->ascii type) proc))
  51. ; Particular dumpers & restorers
  52. (define-restorer! type/null (lambda (c read-char) '()))
  53. (define-restorer! type/false (lambda (c read-char) #f))
  54. (define-restorer! type/true (lambda (c read-char) #t))
  55. (define-restorer! type/unspecific (lambda (c read-char) (if #f #f)))
  56. ; Pairs
  57. (define (dump-pair obj write-char depth)
  58. (if (= depth 0)
  59. (dump-ellipsis obj write-char)
  60. (let ((depth (- depth 1)))
  61. (dump-type type/pair write-char)
  62. (dump (car obj) write-char depth)
  63. (dump (cdr obj) write-char depth))))
  64. (define-restorer! type/pair
  65. (lambda (c write-char)
  66. c ;ignored
  67. (let ((the-car (restore write-char)))
  68. (cons the-car (restore write-char)))))
  69. ; Symbols
  70. (define (dump-symbol obj write-char)
  71. (dump-type type/symbol write-char)
  72. (dump-a-string (symbol-case-converter (symbol->string obj)) write-char))
  73. (define-restorer! type/symbol
  74. (lambda (c read-char)
  75. c ;ignored
  76. (string->symbol (symbol-case-converter (restore-a-string read-char)))))
  77. ; Numbers
  78. ; <space> ... _ represent 0 ... 63,
  79. ; {<space> ... {_ represent 64 ... 127, -- { is ascii 123
  80. ; |<space> ... |_ represent 128 ... 191, -- | is ascii 124
  81. ; }<space> ... }_ represent 192 ... 256. -- } is ascii 125
  82. (define (dump-number n write-char)
  83. (if (not (communicable-number? n))
  84. (assertion-violation 'dump-number "can't dump this number" n))
  85. (if (and (integer? n)
  86. (>= n 0)
  87. (< n 256))
  88. (dump-byte n write-char)
  89. (begin (dump-type type/number write-char)
  90. ;; Note logarithmic recursion
  91. (dump-a-string (number->string n comm-radix) write-char))))
  92. (define (communicable-number? n) #t) ;this gets redefined in client
  93. (define (dump-byte n write-char) ;Dump a number between 0 and 255
  94. (if (< n 64)
  95. (write-char (ascii->char (+ n ascii-space)))
  96. (begin (write-char (ascii->char (+ (arithmetic-shift n -6)
  97. 122)))
  98. (write-char (ascii->char (+ (bitwise-and n 63)
  99. ascii-space))))))
  100. (define ascii-space (char->ascii #\space)) ;32
  101. (define (restore-small-integer c read-char)
  102. (- (char->ascii c) ascii-space))
  103. (do ((i (+ ascii-space 63) (- i 1)))
  104. ((< i ascii-space))
  105. (define-restorer! (ascii->char i) restore-small-integer))
  106. (define (restore-medium-integer c read-char)
  107. (+ (arithmetic-shift (- (char->ascii c) 122) 6)
  108. (- (char->ascii (read-char)) ascii-space)))
  109. (do ((i 123 (+ i 1)))
  110. ((> i 125))
  111. (define-restorer! (ascii->char i) restore-medium-integer))
  112. (define (restore-number read-char)
  113. (let ((c (read-char)))
  114. (if (char=? c type/number)
  115. (string->number (restore-a-string read-char) comm-radix)
  116. (let ((n (char->ascii c)))
  117. (if (> n 122)
  118. (restore-medium-integer c read-char)
  119. (- n ascii-space))))))
  120. (define-restorer! type/number
  121. (lambda (c read-char)
  122. c ;ignored
  123. (string->number (restore-a-string read-char) comm-radix)))
  124. (define comm-radix 16)
  125. ; String literals
  126. (define (dump-string obj write-char)
  127. (dump-type type/string write-char)
  128. (dump-a-string obj write-char))
  129. (define-restorer! type/string
  130. (lambda (c read-char)
  131. c ;ignored
  132. (restore-a-string read-char)))
  133. ; Characters
  134. (define (dump-char-literal obj write-char)
  135. (dump-type type/char write-char)
  136. (dump-a-char obj write-char))
  137. (define-restorer! type/char
  138. (lambda (c read-char)
  139. c ;ignored
  140. (restore-a-char read-char)))
  141. ; Vectors
  142. (define (dump-vector obj write-char depth)
  143. (dump-vector-like obj write-char depth
  144. type/vector vector-length vector-ref))
  145. (define (dump-template obj write-char depth)
  146. (dump-vector-like obj write-char depth
  147. type/template template-length template-ref))
  148. (define (dump-vector-like obj write-char depth type vector-length vector-ref)
  149. (if (= depth 0)
  150. (dump-ellipsis obj write-char)
  151. (let ((depth (- depth 1))
  152. (len (vector-length obj)))
  153. (dump-type type write-char)
  154. (dump-length len write-char)
  155. (do ((i 0 (+ i 1)))
  156. ((= i len) 'done)
  157. (dump (vector-ref obj i) write-char depth)))))
  158. (define (restore-vector-like make-vector vector-set!)
  159. (lambda (c read-char)
  160. c ;ignored
  161. (let* ((len (restore-length read-char))
  162. (v (make-vector len #\?)))
  163. (do ((i 0 (+ i 1)))
  164. ((= i len) v)
  165. (vector-set! v i (restore read-char))))))
  166. (define-restorer! type/vector
  167. (restore-vector-like make-vector vector-set!))
  168. (define-restorer! type/template
  169. (restore-vector-like make-template template-set!))
  170. ; Code vectors
  171. (define (dump-code-vector obj write-char)
  172. (dump-type type/code-vector write-char)
  173. (let ((len (code-vector-length obj)))
  174. (dump-length len write-char)
  175. (do ((i 0 (+ i 1)))
  176. ((= i len) 'done)
  177. (dump-byte (code-vector-ref obj i) write-char))))
  178. (define-restorer! type/code-vector
  179. (lambda (c read-char)
  180. c ;ignored
  181. (let* ((len (restore-length read-char))
  182. (cv (make-code-vector len 0)))
  183. (do ((i 0 (+ i 1)))
  184. ((= i len) cv)
  185. (code-vector-set! cv i
  186. (restore-number read-char))))))
  187. ; Locations
  188. (define (dump-location obj write-char)
  189. (dump-type type/location write-char)
  190. (dump-number (location->uid obj) write-char))
  191. (define (location->uid obj)
  192. (or ((fluid $dump-index) obj)
  193. (location-id obj)))
  194. (define-restorer! type/location
  195. (lambda (c read-char)
  196. c ;ignored
  197. (uid->location (restore-number read-char))))
  198. (define (uid->location uid)
  199. (or ((fluid $restore-index) uid)
  200. (table-ref uid->location-table uid)
  201. (let ((loc (make-undefined-location uid)))
  202. (note-location! loc)
  203. loc)))
  204. (define $restore-index (make-fluid (lambda (uid) #f)))
  205. (define uid->location-table (make-table))
  206. (define (note-location! den)
  207. (table-set! uid->location-table
  208. (location-id den)
  209. den))
  210. (define $dump-index (make-fluid (lambda (loc) #f)))
  211. ; For simulation purposes, it's better for location uid's not to
  212. ; conflict with any that might be in the base Scheme 48 system. (In the
  213. ; real server system there isn't any base Scheme 48 system, so there's
  214. ; no danger of conflict.)
  215. ; (define location-uid-origin 5000)
  216. ; Closure
  217. (define (dump-closure obj write-char)
  218. (dump-type type/closure write-char)
  219. (let ((id (template-info (closure-template obj))))
  220. (dump-number (if (integer? id) id 0) write-char)))
  221. (define-restorer! type/closure
  222. (lambda (c read-char)
  223. c ;ignored
  224. (make-random (list 'closure (restore-number read-char)))))
  225. ; Random
  226. (define random-type (make-record-type 'random '(disclosure)))
  227. (define make-random (record-constructor random-type '(disclosure)))
  228. (define-record-discloser random-type
  229. (let ((d (record-accessor random-type 'disclosure)))
  230. (lambda (r) (cons "Remote" (d r)))))
  231. (define (dump-random obj write-char depth)
  232. (dump-type type/random write-char)
  233. (dump (or (disclose obj) (list '?))
  234. write-char
  235. depth))
  236. (define-restorer! type/random
  237. (lambda (c read-char)
  238. (make-random (restore read-char))))
  239. ; Ellipsis
  240. (define (dump-ellipsis obj write-char)
  241. (dump-type type/ellipsis write-char))
  242. (define-restorer! type/ellipsis
  243. (lambda (c read-char) (make-random (list (string->symbol "---")))))
  244. ; Auxiliaries:
  245. ; Strings (not necessarily preceded by type code)
  246. (define (dump-a-string obj write-char)
  247. (let ((len (string-length obj)))
  248. (dump-length len write-char)
  249. (do ((i 0 (+ i 1)))
  250. ((= i len) 'done)
  251. (dump-a-char (string-ref obj i) write-char))))
  252. (define (restore-a-string read-char)
  253. (let* ((len (restore-length read-char))
  254. (str (make-string len #\?)))
  255. (do ((i 0 (+ i 1)))
  256. ((= i len) str)
  257. (string-set! str i (restore-a-char read-char)))))
  258. (define (dump-a-char c write-char)
  259. (write-char c))
  260. (define (restore-a-char read-char)
  261. (read-char))
  262. ; Type characters
  263. (define (dump-type c write-char)
  264. (write-char c))
  265. (define (restore-type read-char)
  266. (read-char))
  267. (define dump-length dump-number)
  268. (define restore-length restore-number)
  269. ;(define char->ascii char->integer) -- defined in p-features.scm
  270. ;(define ascii->char integer->char) -- ditto
  271. ; Miscellaneous support
  272. (define (unspecific? obj)
  273. (eq? obj *unspecific*))
  274. (define *unspecific* (if #f #f)) ;foo
  275. ;(define (integer->digit-char n)
  276. ; (ascii->char (+ n (if (< n 10) ascii-zero a-minus-ten))))
  277. ;
  278. ;(define (digit-char->integer c)
  279. ; (cond ((char-numeric? c)
  280. ; (- (char->ascii c) ascii-zero))
  281. ; ((char=? c #\#) 0)
  282. ; (else
  283. ; (- (char->ascii (char-downcase c)) a-minus-ten))))
  284. ;
  285. ;(define ascii-zero (char->ascii #\0))
  286. ;
  287. ;(define a-minus-ten (- (char->integer #\a) 10))
  288. ; These modified from s48/boot/transport.scm
  289. (define (string-case-converter string)
  290. (let ((new (make-string (string-length string) #\?)))
  291. (do ((i 0 (+ i 1)))
  292. ((>= i (string-length new)) new)
  293. (string-set! new i (invert-case (string-ref string i))))))
  294. (define (invert-case c)
  295. (cond ((char-upper-case? c) (char-downcase c))
  296. ((char-lower-case? c) (char-upcase c))
  297. (else c)))
  298. (define symbol-case-converter
  299. (if (char=? (string-ref (symbol->string 't) 0) #\t)
  300. (lambda (string) string)
  301. string-case-converter))
  302. ; ASCII
  303. ; !"#$%&'()*+,-./0123456789:;<=>?
  304. ; @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
  305. ; `abcdefghijklmnopqrstuvwxyz{|}~
  306. ;(define (tst x)
  307. ; (let ((l '()))
  308. ; (dump x (lambda (c) (set! l (cons c l))) -1)
  309. ; (let ((l (reverse l)))
  310. ; (restore (lambda ()
  311. ; (let ((c (car l)))
  312. ; (set! l (cdr l))
  313. ; c))))))
  314. ;(define cwcc call-with-current-continuation)
  315. ;
  316. ;(define (tst x)
  317. ; (letrec ((write-cont (lambda (ignore)
  318. ; (dump x
  319. ; (lambda (c)
  320. ; (cwcc (lambda (k)
  321. ; (set! write-cont k)
  322. ; (read-cont c))))
  323. ; -1)))
  324. ; (read-cont #f))
  325. ; (restore (lambda ()
  326. ; (cwcc (lambda (k)
  327. ; (set! read-cont k)
  328. ; (write-cont 'ignore)))))))