low.scm 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Low-level things that rely on the fact that we're running under the
  3. ; Scheme 48 VM.
  4. ; Historical kludge; ASCII is a misnomer (as it covers only [0, 127])---
  5. ; we really mean Latin-1.
  6. (define (char->ascii c)
  7. (let ((scalar-value (char->scalar-value c)))
  8. (if (>= scalar-value ascii-limit)
  9. (signal-condition
  10. (cons 'call-error
  11. (cons "not an ASCII character"
  12. (cons char->ascii (cons c '()))))))
  13. scalar-value))
  14. (define (ascii->char x)
  15. (if (or (>= x ascii-limit) (< x 0))
  16. (signal-condition
  17. (cons 'call-error
  18. (cons"not an ASCII code"
  19. (cons ascii->char
  20. (cons x '()))))))
  21. (scalar-value->char x))
  22. (define (char->integer c) (char->scalar-value c))
  23. (define (integer->char n) (scalar-value->char n))
  24. (define ascii-limit 128)
  25. ; space, horizontal tab, line feed (= newline), vertical tab, form feed, and
  26. ; carriage return
  27. (define ascii-whitespaces '(32 9 10 11 12 13))
  28. ; Procedures and closures are two different abstractions. Procedures
  29. ; are created by LAMBDA and invoked with procedure call; those are
  30. ; their only defined operations. Closures are made with MAKE-CLOSURE,
  31. ; accessed using CLOSURE-TEMPLATE and CLOSURE-ENV, and invoked by
  32. ; INVOKE-CLOSURE, which starts the virtual machine going.
  33. ; In a running Scheme 48 system, the two happen to be implemented
  34. ; using the same data type. The following is the only part of the
  35. ; system that should know this fact.
  36. (define procedure? closure?)
  37. (define (invoke-closure closure . args)
  38. (apply (loophole :procedure closure)
  39. args))
  40. ; Similarly, there are escapes and there are VM continuations.
  41. ; Escapes are obtained with PRIMITIVE-CWCC and invoked with
  42. ; WITH-CONTINUATION. VM continuations are obtained with
  43. ; PRIMITIVE-CATCH and inspected using CONTINUATION-REF and friends.
  44. ; (This is not such a hot naming strategy; it would perhaps be better
  45. ; to use the terms "continuation" and "frame".)
  46. ; In a running Scheme 48 system, the two happen to be implemented
  47. ; using the same data type. The following is the only part of the
  48. ; system that should know this fact.
  49. (define (primitive-cwcc p)
  50. (primitive-catch (lambda (cont)
  51. (p (loophole :escape cont))))) ;?
  52. ; (define (invoke-continuation cont thunk)
  53. ; (with-continuation (loophole :escape cont) thunk))
  54. ; These two procedures are part of the location abstraction.
  55. ; We don't let UNASSIGNED escape because use of the value it returns can
  56. ; be confusing. Here we just test it against other values.
  57. (define (make-undefined-location id)
  58. (let ((loc (make-location id #f)))
  59. (set-location-defined?! loc #f)
  60. loc))
  61. (define (location-assigned? loc)
  62. (and (location-defined? loc)
  63. (if (eq? (contents loc)
  64. (unassigned))
  65. #f
  66. #t)))
  67. ; Used by the cell discloser
  68. (define (cell-unassigned? cell)
  69. (eq? (cell-ref cell) (unassigned)))
  70. ; Used by the inspector.
  71. (define (vector-unassigned? v i)
  72. (eq? (vector-ref v i) (unassigned)))
  73. ; STRING-COPY is here because it's needed by STRING->SYMBOL.
  74. (define (string-copy s)
  75. (let* ((z (string-length s))
  76. (copy (make-string z)))
  77. (copy-string-chars! s 0 copy 0 z)
  78. copy))
  79. ; The symbol table
  80. (define (string->symbol string)
  81. (intern (if (immutable? string)
  82. string ;+++
  83. (make-immutable! (string-copy string)))))
  84. ; The following magic bitmasks are derived from PORT-STATUS-OPTIONS in arch.scm.
  85. (define (input-port? port)
  86. (and (port? port)
  87. (= 1 (bitwise-and 1 (port-status port)))))
  88. (define (output-port? port)
  89. (and (port? port)
  90. (= 2 (bitwise-and 2 (port-status port)))))
  91. ; Every record has a record type (another record) in the first slot.
  92. (define (record-type r)
  93. (record-ref r 0))
  94. ; code-vectors == byte-vectors
  95. ; These are functions so that they will be inlined.
  96. (define (make-code-vector length init) (make-byte-vector length init))
  97. (define (code-vector? x) (byte-vector? x))
  98. (define (code-vector-length bv) (byte-vector-length bv))
  99. (define (code-vector-ref bv i) (byte-vector-ref bv i))
  100. (define (code-vector-set! bv i x) (byte-vector-set! bv i x))
  101. ; Shared bindings - six procedures from two primitives. The lookup and
  102. ; undefine primitives take a flag which is true for imports and false for
  103. ; exports.
  104. (define (lookup-imported-binding name)
  105. (lookup-shared-binding name #t))
  106. (define (lookup-exported-binding name)
  107. (lookup-shared-binding name #f))
  108. (define (define-imported-binding name value)
  109. (shared-binding-set! (lookup-shared-binding name #t)
  110. value))
  111. (define (define-exported-binding name value)
  112. (shared-binding-set! (lookup-shared-binding name #f)
  113. value))
  114. (define (undefine-imported-binding name)
  115. (undefine-shared-binding name #t))
  116. (define (undefine-exported-binding name)
  117. (undefine-shared-binding name #f))
  118. ; This really shouldn't be here, but I don't know where else to put it.
  119. (define (byte-vector . l)
  120. (let ((v (make-byte-vector (secret-length l 0) 0)))
  121. (do ((i 0 (+ i 1))
  122. (l l (cdr l)))
  123. ((eq? l '()) v)
  124. (byte-vector-set! v i (car l)))))
  125. (define (secret-length list length)
  126. (if (eq? list '())
  127. length
  128. (secret-length (cdr list) (+ length 1))))
  129. ; Writing debugging messages.
  130. (define (debug-message . stuff)
  131. (message stuff))
  132. ; Checking for undumpable objects when writing images.
  133. ; Also convert file-name to VM format
  134. (define (write-image file-name start-procedure message)
  135. (let ((undumpable (make-vector 1000 #f)))
  136. (write-image-low file-name
  137. start-procedure
  138. message
  139. undumpable)
  140. (if (vector-ref undumpable 0)
  141. (signal 'error
  142. "undumpable records written in image"
  143. (vector-prefix->list undumpable)))))
  144. ; Return a list containing the non-#F values at the beginning of VECTOR.
  145. (define (vector-prefix->list vector)
  146. (do ((i 0 (+ i 1))
  147. (losers '() (cons (vector-ref vector i) losers)))
  148. ((or (= i (vector-length vector))
  149. (if (vector-ref vector i) #f #t))
  150. losers)))
  151. ; Proposals are just vectors.
  152. (define empty-log '#(#f))
  153. (define (make-proposal)
  154. (vector #f empty-log empty-log #f))