123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- @node More Pre-Scheme packages
- @section More Pre-Scheme packages
- Along with the @code{prescheme} structure, there are several other
- structures built-in to Pre-Scheme.
- @menu
- * Pre-Scheme floating point operation::
- * Pre-Scheme record types::
- * Multiple return values in Pre-Scheme::
- * Low-level Pre-Scheme memory manipulation::
- @end menu
- @node Pre-Scheme floating point operation
- @subsection Floating point operation
- @stindex ps-flonums
- Since Pre-Scheme's strict static type system would not permit
- overloading of the arithmetic operators for integers & floats, it
- provides a different set of operators for floats. These names are all
- exported by the @code{ps-flonums} structure.
- @deffn procedure fl+ augend addend @dots{} @returns{} float
- @deffnx procedure fl- float @returns{} float
- @deffnx procedure fl- minuend subtrahend @returns{} float
- @deffnx procedure fl* multiplier multiplicand @dots{} @returns{} float
- @deffnx procedure fl/ divisor dividend @returns{} float
- @deffnx procedure fl= float@suba{a} float@suba{b} @returns{} boolean
- @deffnx procedure fl< float@suba{a} float@suba{b} @returns{} boolean
- @deffnx procedure fl> float@suba{a} float@suba{b} @returns{} boolean
- @deffnx procedure fl<= float@suba{a} float@suba{b} @returns{} boolean
- @deffnx procedure fl>= float@suba{a} float@suba{b} @returns{} boolean
- All of these operations @code{fl@var{op}} correspond as floating point
- variations of their @var{op} integer equivalents.
- @end deffn
- @node Pre-Scheme record types
- @subsection Record types
- @stindex ps-record-types
- The @code{ps-record-types} structure defines the following special form
- for introducing record types. Pre-Scheme record types are translated
- to C as structs.
- @deffn syntax define-record-type
- @lisp
- (define-record-type @var{type} @var{type-descriptor}
- (@var{constructor} @var{argument-field-tag} @dots{})
- (@var{field-tag@sub{1}} @var{field-type-spec@sub{1}}
- @var{field-accessor@sub{1}} [@var{field-modifier@sub{1}}])
- (@var{field-tag@sub{2}} @var{field-type-spec@sub{2}}
- @var{field-accessor@sub{2}} [@var{field-modifier@sub{2}}])
- @dots{}
- (@var{field-tag@sub{n}} @var{field-type-spec@sub{n}}
- @var{field-accessor@sub{n}} [@var{field-modifier@sub{n}}])@end lisp
- Defines a record type. @var{Type} is mangled to the C struct type name
- (@var{type-descriptor-name} is unused unless running Pre-Scheme as
- Scheme). @var{Constructor} is defined to construct a record of the new
- type and initialize the fields @var{argument-type-field} @dots{} with
- its arguments, respectively. If it cannot allocate a sufficient
- quantity of memory, @var{constructor} returns a null pointer. The
- initial values of fields that are not passed to the constructor are
- undefined. For each field @var{field@suba{i}} specified,
- @itemize @bullet
- @item @var{field@suba{i}} is specified to have the type
- @var{field-type-spec@suba{i}};
- @item @var{field-accessor@suba{i}} is defined to be a procedure of one
- argument, a record of type @var{type-name}, that returns the value of
- the field @var{field@suba{i}} of that record --- its type is defined to
- be @code{(=> (@var{type-name}) @var{field-type-spec@suba{i}})}; and
- @item if present, @var{field-modifier@suba{i}} is defined to be a
- procedure of two arguments, a record of type @var{type-name} and a
- value of type @var{field-type-spec}, that assigns the value of the
- field @var{field@suba{i}} in its first argument to be the value of its
- second argument; its type is @code{(=> (@var{type-name}
- @var{field-type-spec}) unit)}.
- @end itemize
- Records must be deallocated explicitly when their lifetime has expired
- with @code{deallocate}.
- @end deffn
- @node Multiple return values in Pre-Scheme
- @subsection Multiple return values
- @stindex ps-receive
- Pre-Scheme support multiple return values, like in Scheme. The only
- difference is that one cannot operate on multiple return values as
- lists, since Pre-Scheme does not have lists. Multiple return values
- are implemented in C as returning in C the first value and passing
- pointers to the remaining values, which the function returning multiple
- values assigns. The @code{prescheme} structure exports the two
- multiple return value primitives, @code{call-with-values} and
- @code{values}, but the @code{ps-receive} structure exports this macro
- for more conveniently binding multiple return values.
- @deffn syntax receive formals producer body
- Binds the @code{lambda} parameter list @var{formals} to the multiple
- values that @var{producer} returns, and evaluates @var{body} with the
- new variables bound.
- @lisp
- (receive @var{formals}
- @var{producer}
- @var{body})
- @equiv{}
- (call-with-values
- (lambda () @var{producer})
- (lambda @var{formals}
- @var{body}))@end lisp
- @end deffn
- @node Low-level Pre-Scheme memory manipulation
- @subsection Low-level memory manipulation
- @cindex Pre-Scheme memory management
- @cindex memory management in Pre-Scheme
- @stindex ps-memory
- 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 @code{ps-memory} structure exports these
- direct memory manipulation primitives.
- @deffn procedure allocate-memory size @returns{} address
- @deffnx procedure deallocate-memory address @returns{} unit
- @code{Allocate-memory} reserves a sequence of @var{size} bytes in the
- store and returns an address to the first byte in the sequence.
- @code{Deallocate-memory} releases the memory at @var{address}, which
- should have been the initial address of a contiguous byte sequence, as
- @code{allocate-memory} would return, not an offset address from such an
- initial address.
- @end deffn
- @deffn procedure unsigned-byte-ref address @returns{} unsigned-byte
- @deffnx procedure unsigned-byte-set! address unsigned-byte @returns{} unit
- @deffnx procedure word-ref address @returns{} word
- @deffnx procedure word-set! address word @returns{} unit
- @deffnx procedure flonum-ref address @returns{} float
- @deffnx procedure flonum-set! address float @returns{} unit
- Procedures for reading from & storing to memory.
- @code{Unsigned-byte-ref} & @code{unsigned-byte-set!} access & store the
- first unsigned byte at @var{address}. @code{Word-ref} &
- @code{word-set!} access & store the first word --- Pre-Scheme integer
- --- beginning at @var{address}. @code{Flonum-ref} & @code{flonum-set!}
- access & store 64-bit floats beginning at @var{address}..
- @strong{Bug:} @code{Flonum-ref} & @code{flonum-set!} are unimplemented
- in the Pre-Scheme-as-Scheme layer (@pxref{Running Pre-Scheme as
- Scheme}).
- @end deffn
- @deffn procedure address? value @returns{} boolean
- Disjoint type predicate for addresses.
- @strong{Note:} @code{Address?} is available @emph{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.
- @end deffn
- @defvr constant null-address @returns{} address
- The null address. This is somewhat similar to the null pointer, except
- that it is an address.
- @strong{Note:} One acquires the null @emph{pointer} by calling the
- @emph{procedure} @code{null-pointer}, whereas the constant value of the
- @emph{binding} named @code{null-address} is the null @emph{address}.
- @end defvr
- @deffn procedure null-address? address @returns{} boolean
- @code{Null-address?} returns true if @var{address} is the null
- address and false if not.
- @end deffn
- @deffn procedure address+ address increment @returns{} address
- @deffnx procedure address- address decrement @returns{} address
- @deffnx procedure address-difference address@suba{a} address@suba{b} @returns{} integer
- Address arithmetic operators. @code{Address+} adds @var{increment} to
- @var{address}; @code{address-} subtracts @var{decrement} from
- @var{address}; and @code{address-difference} returns the integer
- difference between @var{address@suba{a}} and @var{address@suba{b}}.
- For any @var{address@suba{p}} & @var{address@suba{q}}, @code{(address+
- @var{address@suba{p}} (address-difference @var{address@suba{p}}
- @var{address@suba{q}}))} is equal to @var{address@suba{q}}.
- @end deffn
- @deffn procedure address= address@suba{a} address@suba{b} @returns{} boolean
- @deffnx procedure address< address@suba{a} address@suba{b} @returns{} boolean
- @deffnx procedure address> address@suba{a} address@suba{b} @returns{} boolean
- @deffnx procedure address<= address@suba{a} address@suba{b} @returns{} boolean
- @deffnx procedure address>= address@suba{a} address@suba{b} @returns{} boolean
- Address comparators.
- @end deffn
- @deffn procedure integer->address integer @returns{} address
- @deffnx procedure address->integer address @returns{} integer
- Integers and addresses, although not the same type, may be converted to
- and from each other; @code{integer->address} & @code{address->integer}
- perform this conversion. Note that Pre-Scheme @emph{pointers} may not
- be converted to addresses or integers, and the converse is also true.
- @end deffn
- @deffn procedure copy-memory! source-address target-address count @returns{} unit
- Copies @var{count} bytes starting at @var{source-address} to
- @var{target-address}. This is similar to C's @code{memcpy}.
- @end deffn
- @deffn procedure memory-equal? address@suba{a} address@suba{b} count @returns{} boolean
- Compares the two sequences of @var{count} bytes starting at addresses
- @var{address@suba{a}} & @var{address@suba{b}}. It returns true if every
- byte is equal and false if not.
- @end deffn
- @deffn procedure char-pointer->string address size @returns{} string
- @deffnx procedure char-pointer->nul-terminated-string address @returns{} string
- @code{Char-pointer->string} returns a string with @var{size} bytes from
- the contiguous sequence of bytes starting at @var{address}.
- @code{Char-pointer->nul-terminated-string} does similarly, but it
- returns a string whose contents include every byte starting at
- @var{address} until, but not including, the first 0 byte, @ie{} ASCII
- nul character, following @var{address}.
- @end deffn
- @deffn procedure read-block port address count @returns{} [count-read eof? status]
- @deffnx procedure write-block port address count @returns{} status
- @code{Read-block} attempts to read @var{count} bytes from @var{port}
- into memory starting at @var{address}. @code{Write-block} attempts to
- write @var{count} bytes to @var{port} from the contiguous sequence in
- memory starting at @var{address}. @code{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 (@pxref{Pre-Scheme error
- handling}). @code{Write-block} returns the error status.
- @end deffn
|