Previous: Multiple return values in Pre-Scheme, Up: More Pre-Scheme packages


9.4.4 Low-level memory manipulation

Pre-Scheme is a low-level language. It provides very low-level, direct memory manipulation. `Addresses' index a flat store of sequences of bytes. While Pre-Scheme `pointers' are statically checked for data coherency, allow no arbitrary arithmetic, and in general are high-level abstract data to some extent, addresses are much lower-level, have no statically checked coherency — the values an address represents are selected by what operation used to read or write from it —, permit arbitrary address arithmetic, and are a much more concrete interface into direct memory. The ps-memory structure exports these direct memory manipulation primitives.

— procedure: allocate-memory size –> address
— procedure: deallocate-memory address –> unit

Allocate-memory reserves a sequence of size bytes in the store and returns an address to the first byte in the sequence. Deallocate-memory releases the memory at address, which should have been the initial address of a contiguous byte sequence, as allocate-memory would return, not an offset address from such an initial address.

— procedure: unsigned-byte-ref address –> unsigned-byte
— procedure: unsigned-byte-set! address unsigned-byte –> unit
— procedure: word-ref address –> word
— procedure: word-set! address word –> unit
— procedure: flonum-ref address –> float
— procedure: flonum-set! address float –> unit

Procedures for reading from & storing to memory. Unsigned-byte-ref & unsigned-byte-set! access & store the first unsigned byte at address. Word-ref & word-set! access & store the first word — Pre-Scheme integer — beginning at address. Flonum-ref & flonum-set! access & store 64-bit floats beginning at address..

Bug: Flonum-ref & flonum-set! are unimplemented in the Pre-Scheme-as-Scheme layer (see Running Pre-Scheme as Scheme).

— procedure: address? value –> boolean

Disjoint type predicate for addresses.

Note: Address? is available only at the top level, where code is evaluated at compile-time. Do not use this in any place where it may be called at run-time.

— constant: null-address –> address

The null address. This is somewhat similar to the null pointer, except that it is an address.

Note: One acquires the null pointer by calling the procedure null-pointer, whereas the constant value of the binding named null-address is the null address.

— procedure: null-address? address –> boolean

Null-address? returns true if address is the null address and false if not.

— procedure: address+ address increment –> address
— procedure: address- address decrement –> address
— procedure: address-difference addressa addressb –> integer

Address arithmetic operators. Address+ adds increment to address; address- subtracts decrement from address; and address-difference returns the integer difference between addressa and addressb. For any addressp & addressq, (address+ addressp (address-difference addressp addressq)) is equal to addressq.

— procedure: address= addressa addressb –> boolean
— procedure: address< addressa addressb –> boolean
— procedure: address> addressa addressb –> boolean
— procedure: address<= addressa addressb –> boolean
— procedure: address>= addressa addressb –> boolean

Address comparators.

— procedure: integer->address integer –> address
— procedure: address->integer address –> integer

Integers and addresses, although not the same type, may be converted to and from each other; integer->address & address->integer perform this conversion. Note that Pre-Scheme pointers may not be converted to addresses or integers, and the converse is also true.

— procedure: copy-memory! source-address target-address count –> unit

Copies count bytes starting at source-address to target-address. This is similar to C's memcpy.

— procedure: memory-equal? addressa addressb count –> boolean

Compares the two sequences of count bytes starting at addresses addressa & addressb. It returns true if every byte is equal and false if not.

— procedure: char-pointer->string address size –> string
— procedure: char-pointer->nul-terminated-string address –> string

Char-pointer->string returns a string with size bytes from the contiguous sequence of bytes starting at address. Char-pointer->nul-terminated-string does similarly, but it returns a string whose contents include every byte starting at address until, but not including, the first 0 byte, i.e. ASCII nul character, following address.

— procedure: read-block port address count –> [count-read eof? status]
— procedure: write-block port address count –> status

Read-block attempts to read count bytes from port into memory starting at address. Write-block attempts to write count bytes to port from the contiguous sequence in memory starting at address. Read-block returns three values: the number of bytes read, whether or not the read went to the end of the file, and the error status (see Pre-Scheme error handling). Write-block returns the error status.