more-env.texi 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. @node More Pre-Scheme packages
  2. @section More Pre-Scheme packages
  3. Along with the @code{prescheme} structure, there are several other
  4. structures built-in to Pre-Scheme.
  5. @menu
  6. * Pre-Scheme floating point operation::
  7. * Pre-Scheme record types::
  8. * Multiple return values in Pre-Scheme::
  9. * Low-level Pre-Scheme memory manipulation::
  10. @end menu
  11. @node Pre-Scheme floating point operation
  12. @subsection Floating point operation
  13. @stindex ps-flonums
  14. Since Pre-Scheme's strict static type system would not permit
  15. overloading of the arithmetic operators for integers & floats, it
  16. provides a different set of operators for floats. These names are all
  17. exported by the @code{ps-flonums} structure.
  18. @deffn procedure fl+ augend addend @dots{} @returns{} float
  19. @deffnx procedure fl- float @returns{} float
  20. @deffnx procedure fl- minuend subtrahend @returns{} float
  21. @deffnx procedure fl* multiplier multiplicand @dots{} @returns{} float
  22. @deffnx procedure fl/ divisor dividend @returns{} float
  23. @deffnx procedure fl= float@suba{a} float@suba{b} @returns{} boolean
  24. @deffnx procedure fl< float@suba{a} float@suba{b} @returns{} boolean
  25. @deffnx procedure fl> float@suba{a} float@suba{b} @returns{} boolean
  26. @deffnx procedure fl<= float@suba{a} float@suba{b} @returns{} boolean
  27. @deffnx procedure fl>= float@suba{a} float@suba{b} @returns{} boolean
  28. All of these operations @code{fl@var{op}} correspond as floating point
  29. variations of their @var{op} integer equivalents.
  30. @end deffn
  31. @node Pre-Scheme record types
  32. @subsection Record types
  33. @stindex ps-record-types
  34. The @code{ps-record-types} structure defines the following special form
  35. for introducing record types. Pre-Scheme record types are translated
  36. to C as structs.
  37. @deffn syntax define-record-type
  38. @lisp
  39. (define-record-type @var{type} @var{type-descriptor}
  40. (@var{constructor} @var{argument-field-tag} @dots{})
  41. (@var{field-tag@sub{1}} @var{field-type-spec@sub{1}}
  42. @var{field-accessor@sub{1}} [@var{field-modifier@sub{1}}])
  43. (@var{field-tag@sub{2}} @var{field-type-spec@sub{2}}
  44. @var{field-accessor@sub{2}} [@var{field-modifier@sub{2}}])
  45. @dots{}
  46. (@var{field-tag@sub{n}} @var{field-type-spec@sub{n}}
  47. @var{field-accessor@sub{n}} [@var{field-modifier@sub{n}}])@end lisp
  48. Defines a record type. @var{Type} is mangled to the C struct type name
  49. (@var{type-descriptor-name} is unused unless running Pre-Scheme as
  50. Scheme). @var{Constructor} is defined to construct a record of the new
  51. type and initialize the fields @var{argument-type-field} @dots{} with
  52. its arguments, respectively. If it cannot allocate a sufficient
  53. quantity of memory, @var{constructor} returns a null pointer. The
  54. initial values of fields that are not passed to the constructor are
  55. undefined. For each field @var{field@suba{i}} specified,
  56. @itemize @bullet
  57. @item @var{field@suba{i}} is specified to have the type
  58. @var{field-type-spec@suba{i}};
  59. @item @var{field-accessor@suba{i}} is defined to be a procedure of one
  60. argument, a record of type @var{type-name}, that returns the value of
  61. the field @var{field@suba{i}} of that record --- its type is defined to
  62. be @code{(=> (@var{type-name}) @var{field-type-spec@suba{i}})}; and
  63. @item if present, @var{field-modifier@suba{i}} is defined to be a
  64. procedure of two arguments, a record of type @var{type-name} and a
  65. value of type @var{field-type-spec}, that assigns the value of the
  66. field @var{field@suba{i}} in its first argument to be the value of its
  67. second argument; its type is @code{(=> (@var{type-name}
  68. @var{field-type-spec}) unit)}.
  69. @end itemize
  70. Records must be deallocated explicitly when their lifetime has expired
  71. with @code{deallocate}.
  72. @end deffn
  73. @node Multiple return values in Pre-Scheme
  74. @subsection Multiple return values
  75. @stindex ps-receive
  76. Pre-Scheme support multiple return values, like in Scheme. The only
  77. difference is that one cannot operate on multiple return values as
  78. lists, since Pre-Scheme does not have lists. Multiple return values
  79. are implemented in C as returning in C the first value and passing
  80. pointers to the remaining values, which the function returning multiple
  81. values assigns. The @code{prescheme} structure exports the two
  82. multiple return value primitives, @code{call-with-values} and
  83. @code{values}, but the @code{ps-receive} structure exports this macro
  84. for more conveniently binding multiple return values.
  85. @deffn syntax receive formals producer body
  86. Binds the @code{lambda} parameter list @var{formals} to the multiple
  87. values that @var{producer} returns, and evaluates @var{body} with the
  88. new variables bound.
  89. @lisp
  90. (receive @var{formals}
  91. @var{producer}
  92. @var{body})
  93. @equiv{}
  94. (call-with-values
  95. (lambda () @var{producer})
  96. (lambda @var{formals}
  97. @var{body}))@end lisp
  98. @end deffn
  99. @node Low-level Pre-Scheme memory manipulation
  100. @subsection Low-level memory manipulation
  101. @cindex Pre-Scheme memory management
  102. @cindex memory management in Pre-Scheme
  103. @stindex ps-memory
  104. Pre-Scheme is a low-level language. It provides very low-level, direct
  105. memory manipulation. `Addresses' index a flat store of sequences of
  106. bytes. While Pre-Scheme `pointers' are statically checked for data
  107. coherency, allow no arbitrary arithmetic, and in general are high-level
  108. abstract data to some extent, addresses are much lower-level, have no
  109. statically checked coherency --- the values an address represents are
  110. selected by what operation used to read or write from it ---, permit
  111. arbitrary address arithmetic, and are a much more concrete interface
  112. into direct memory. The @code{ps-memory} structure exports these
  113. direct memory manipulation primitives.
  114. @deffn procedure allocate-memory size @returns{} address
  115. @deffnx procedure deallocate-memory address @returns{} unit
  116. @code{Allocate-memory} reserves a sequence of @var{size} bytes in the
  117. store and returns an address to the first byte in the sequence.
  118. @code{Deallocate-memory} releases the memory at @var{address}, which
  119. should have been the initial address of a contiguous byte sequence, as
  120. @code{allocate-memory} would return, not an offset address from such an
  121. initial address.
  122. @end deffn
  123. @deffn procedure unsigned-byte-ref address @returns{} unsigned-byte
  124. @deffnx procedure unsigned-byte-set! address unsigned-byte @returns{} unit
  125. @deffnx procedure word-ref address @returns{} word
  126. @deffnx procedure word-set! address word @returns{} unit
  127. @deffnx procedure flonum-ref address @returns{} float
  128. @deffnx procedure flonum-set! address float @returns{} unit
  129. Procedures for reading from & storing to memory.
  130. @code{Unsigned-byte-ref} & @code{unsigned-byte-set!} access & store the
  131. first unsigned byte at @var{address}. @code{Word-ref} &
  132. @code{word-set!} access & store the first word --- Pre-Scheme integer
  133. --- beginning at @var{address}. @code{Flonum-ref} & @code{flonum-set!}
  134. access & store 64-bit floats beginning at @var{address}..
  135. @strong{Bug:} @code{Flonum-ref} & @code{flonum-set!} are unimplemented
  136. in the Pre-Scheme-as-Scheme layer (@pxref{Running Pre-Scheme as
  137. Scheme}).
  138. @end deffn
  139. @deffn procedure address? value @returns{} boolean
  140. Disjoint type predicate for addresses.
  141. @strong{Note:} @code{Address?} is available @emph{only} at the top
  142. level, where code is evaluated at compile-time. Do not use this in any
  143. place where it may be called at run-time.
  144. @end deffn
  145. @defvr constant null-address @returns{} address
  146. The null address. This is somewhat similar to the null pointer, except
  147. that it is an address.
  148. @strong{Note:} One acquires the null @emph{pointer} by calling the
  149. @emph{procedure} @code{null-pointer}, whereas the constant value of the
  150. @emph{binding} named @code{null-address} is the null @emph{address}.
  151. @end defvr
  152. @deffn procedure null-address? address @returns{} boolean
  153. @code{Null-address?} returns true if @var{address} is the null
  154. address and false if not.
  155. @end deffn
  156. @deffn procedure address+ address increment @returns{} address
  157. @deffnx procedure address- address decrement @returns{} address
  158. @deffnx procedure address-difference address@suba{a} address@suba{b} @returns{} integer
  159. Address arithmetic operators. @code{Address+} adds @var{increment} to
  160. @var{address}; @code{address-} subtracts @var{decrement} from
  161. @var{address}; and @code{address-difference} returns the integer
  162. difference between @var{address@suba{a}} and @var{address@suba{b}}.
  163. For any @var{address@suba{p}} & @var{address@suba{q}}, @code{(address+
  164. @var{address@suba{p}} (address-difference @var{address@suba{p}}
  165. @var{address@suba{q}}))} is equal to @var{address@suba{q}}.
  166. @end deffn
  167. @deffn procedure address= address@suba{a} address@suba{b} @returns{} boolean
  168. @deffnx procedure address< address@suba{a} address@suba{b} @returns{} boolean
  169. @deffnx procedure address> address@suba{a} address@suba{b} @returns{} boolean
  170. @deffnx procedure address<= address@suba{a} address@suba{b} @returns{} boolean
  171. @deffnx procedure address>= address@suba{a} address@suba{b} @returns{} boolean
  172. Address comparators.
  173. @end deffn
  174. @deffn procedure integer->address integer @returns{} address
  175. @deffnx procedure address->integer address @returns{} integer
  176. Integers and addresses, although not the same type, may be converted to
  177. and from each other; @code{integer->address} & @code{address->integer}
  178. perform this conversion. Note that Pre-Scheme @emph{pointers} may not
  179. be converted to addresses or integers, and the converse is also true.
  180. @end deffn
  181. @deffn procedure copy-memory! source-address target-address count @returns{} unit
  182. Copies @var{count} bytes starting at @var{source-address} to
  183. @var{target-address}. This is similar to C's @code{memcpy}.
  184. @end deffn
  185. @deffn procedure memory-equal? address@suba{a} address@suba{b} count @returns{} boolean
  186. Compares the two sequences of @var{count} bytes starting at addresses
  187. @var{address@suba{a}} & @var{address@suba{b}}. It returns true if every
  188. byte is equal and false if not.
  189. @end deffn
  190. @deffn procedure char-pointer->string address size @returns{} string
  191. @deffnx procedure char-pointer->nul-terminated-string address @returns{} string
  192. @code{Char-pointer->string} returns a string with @var{size} bytes from
  193. the contiguous sequence of bytes starting at @var{address}.
  194. @code{Char-pointer->nul-terminated-string} does similarly, but it
  195. returns a string whose contents include every byte starting at
  196. @var{address} until, but not including, the first 0 byte, @ie{} ASCII
  197. nul character, following @var{address}.
  198. @end deffn
  199. @deffn procedure read-block port address count @returns{} [count-read eof? status]
  200. @deffnx procedure write-block port address count @returns{} status
  201. @code{Read-block} attempts to read @var{count} bytes from @var{port}
  202. into memory starting at @var{address}. @code{Write-block} attempts to
  203. write @var{count} bytes to @var{port} from the contiguous sequence in
  204. memory starting at @var{address}. @code{Read-block} returns three
  205. values: the number of bytes read, whether or not the read went to the
  206. end of the file, and the error status (@pxref{Pre-Scheme error
  207. handling}). @code{Write-block} returns the error status.
  208. @end deffn