prescheme/www/1.3/index.html

1422 lines
75 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- This manual is for Scheme48 version 1.3.
Copyright (C) 2004, 2005, 2006 Taylor Campbell.
All rights reserved.
This manual includes material derived from works bearing the following
notice:
Copyright (C) 1993-2005 Richard Kelsey, Jonathan Rees, and
Mike Sperber.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
The name of the authors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>The Nearly Complete Scheme48 PreScheme 1.3 Reference Manual</title>
<meta name="description" content="The Nearly Complete Scheme48 PreScheme 1.3 Reference Manual">
<meta name="keywords" content="The Nearly Complete Scheme48 PreScheme 1.3 Reference Manual">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<link href="#Top" rel="start" title="Top">
<link href="#SEC_Contents" rel="contents" title="Table of Contents">
<link href="dir.html#Top" rel="up" title="(dir)">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smalllisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>
</head>
<body lang="en">
<h1 class="settitle" align="center">The Nearly Complete Scheme48 PreScheme 1.3 Reference Manual</h1>
<a name="SEC_Contents"></a>
<h2 class="contents-heading">Table of Contents</h2>
<div class="contents">
<ul class="no-bullet">
<li><a name="toc-Pre_002dScheme_003a-A-low_002dlevel-dialect-of-Scheme" href="#Pre_002dScheme">1 Pre-Scheme: A low-level dialect of Scheme</a>
<ul class="no-bullet">
<li><a name="toc-Differences-between-Pre_002dScheme-_0026-Scheme-1" href="#Differences-between-Pre_002dScheme-_0026-Scheme">1.1 Differences between Pre-Scheme &amp; Scheme</a></li>
<li><a name="toc-Type-specifiers" href="#Pre_002dScheme-type-specifiers">1.2 Type specifiers</a></li>
<li><a name="toc-Standard-environment" href="#Standard-Pre_002dScheme-environment">1.3 Standard environment</a>
<ul class="no-bullet">
<li><a name="toc-Scheme-bindings" href="#Scheme-bindings-in-Pre_002dScheme">1.3.1 Scheme bindings</a></li>
<li><a name="toc-Tail-call-optimization" href="#Tail-call-optimization-in-Pre_002dScheme">1.3.2 Tail call optimization</a></li>
<li><a name="toc-Bitwise-manipulation" href="#Pre_002dScheme-bitwise-manipulation">1.3.3 Bitwise manipulation</a></li>
<li><a name="toc-Compound-data-manipulation" href="#Compound-Pre_002dScheme-data-manipulation">1.3.4 Compound data manipulation</a></li>
<li><a name="toc-Error-handling" href="#Pre_002dScheme-error-handling">1.3.5 Error handling</a></li>
<li><a name="toc-Input-_0026-output" href="#Input-_0026-output-in-Pre_002dScheme">1.3.6 Input &amp; output</a></li>
<li><a name="toc-Access-to-C-functions-and-macros" href="#Pre_002dScheme-access-to-C-functions-and-macros">1.3.7 Access to C functions and macros</a></li>
</ul></li>
<li><a name="toc-More-Pre_002dScheme-packages-1" href="#More-Pre_002dScheme-packages">1.4 More Pre-Scheme packages</a>
<ul class="no-bullet">
<li><a name="toc-Floating-point-operation" href="#Pre_002dScheme-floating-point-operation">1.4.1 Floating point operation</a></li>
<li><a name="toc-Record-types" href="#Pre_002dScheme-record-types">1.4.2 Record types</a></li>
<li><a name="toc-Multiple-return-values" href="#Multiple-return-values-in-Pre_002dScheme">1.4.3 Multiple return values</a></li>
<li><a name="toc-Low_002dlevel-memory-manipulation" href="#Low_002dlevel-Pre_002dScheme-memory-manipulation">1.4.4 Low-level memory manipulation</a></li>
</ul></li>
<li><a name="toc-Invoking-the-Pre_002dScheme-compiler-1" href="#Invoking-the-Pre_002dScheme-compiler">1.5 Invoking the Pre-Scheme compiler</a>
<ul class="no-bullet">
<li><a name="toc-Loading-the-compiler" href="#Loading-the-compiler">1.5.1 Loading the compiler</a></li>
<li><a name="toc-Calling-the-compiler" href="#Calling-the-compiler">1.5.2 Calling the compiler</a></li>
</ul></li>
<li><a name="toc-Example-Pre_002dScheme-compiler-usage-1" href="#Example-Pre_002dScheme-compiler-usage">1.6 Example Pre-Scheme compiler usage</a></li>
<li><a name="toc-Running-Pre_002dScheme-as-Scheme-1" href="#Running-Pre_002dScheme-as-Scheme">1.7 Running Pre-Scheme as Scheme</a></li>
</ul></li>
</ul>
</div>
<a name="Top"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme" accesskey="n" rel="next">Pre-Scheme</a>, Up: <a href="dir.html#Top" accesskey="u" rel="up">(dir)</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="The-Nearly-Complete-Scheme48-PreScheme-Reference-Manual"></a>
<h1 class="top">The Nearly Complete Scheme48 PreScheme Reference Manual</h1>
<p>This manual is for Scheme48 version 1.3.
</p>
<p>Copyright &copy; 2004, 2005, 2006 Taylor Campbell.
All rights reserved.
</p>
<p>This manual includes material derived from works bearing the following
notice:
</p>
<p>Copyright &copy; 1993&ndash;2005 Richard Kelsey, Jonathan Rees, and
Mike Sperber.
All rights reserved.
</p>
<blockquote>
<p>Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
</p>
<ul>
<li> Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
</li><li> Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
</li><li> The name of the authors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
</li></ul>
</blockquote>
<p>THIS SOFTWARE IS PROVIDED BY THE AUTHORS &ldquo;AS IS&rdquo; AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><th colspan="3" align="left" valign="top"></th></tr><tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme" accesskey="1">Pre-Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">A low-level dialect of Scheme
</td></tr>
<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment">
</pre></th></tr></table>
<hr>
<a name="Pre_002dScheme"></a>
<div class="header">
<p>
Previous: <a href="#Top" accesskey="p" rel="prev">Top</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Pre_002dScheme_003a-A-low_002dlevel-dialect-of-Scheme"></a>
<h2 class="chapter">1 Pre-Scheme: A low-level dialect of Scheme</h2>
<p>Pre-Scheme [Kelsey 97] is a low-level dialect of Scheme, designed for
systems programming with higher-level abstractions. For example, the
Scheme48 virtual machine is written in Pre-Scheme. Pre-Scheme is a
particularly interesting alternative to C for many systems programming
tasks, because not only does it operate at about the same level as C,
but it also may be run in a regular high-level Scheme development with
no changes to the source, without resorting to low-level stack munging
with tools such as gdb. Pre-Scheme also supports two <em>extremely</em>
important high-level abstractions of Scheme: macros and higher-order,
anonymous functions. Richard Kelsey&rsquo;s Pre-Scheme compiler, based on
his PhD research on transformational compilation [Kelsey 89], compiles
Pre-Scheme to efficient C, applying numerous intermediate source
transformations in the process.
</p>
<p>This chapter describes details of the differences between Scheme and
Pre-Scheme, listings of the default environment and other packages
available to Pre-Scheme, the operation of Richard Kelsey&rsquo;s Pre-Scheme
compiler, and how to run Pre-Scheme code as if it were Scheme in a
regular Scheme environment.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><th colspan="3" align="left" valign="top"></th></tr><tr><td align="left" valign="top">&bull; <a href="#Differences-between-Pre_002dScheme-_0026-Scheme" accesskey="1">Differences between Pre-Scheme &amp; Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-type-specifiers" accesskey="2">Pre-Scheme type specifiers</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Standard-Pre_002dScheme-environment" accesskey="3">Standard Pre-Scheme environment</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#More-Pre_002dScheme-packages" accesskey="4">More Pre-Scheme packages</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Invoking-the-Pre_002dScheme-compiler" accesskey="5">Invoking the Pre-Scheme compiler</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Example-Pre_002dScheme-compiler-usage" accesskey="6">Example Pre-Scheme compiler usage</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Running-Pre_002dScheme-as-Scheme" accesskey="7">Running Pre-Scheme as Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
</table>
<hr>
<a name="Differences-between-Pre_002dScheme-_0026-Scheme"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme-type-specifiers" accesskey="n" rel="next">Pre-Scheme type specifiers</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Differences-between-Pre_002dScheme-_0026-Scheme-1"></a>
<h3 class="section">1.1 Differences between Pre-Scheme &amp; Scheme</h3>
<p>Pre-Scheme is often considered either a dialect of Scheme or a subset
of Scheme. However, there are several very important fundamental
differences between the semantics of Pre-Scheme &amp; Scheme to detail.
</p>
<dl compact="compact">
<dd><a name="index-Pre_002dScheme-memory-management"></a>
<a name="index-Pre_002dScheme-garbage-collection"></a>
<a name="index-memory-management-in-Pre_002dScheme"></a>
<a name="index-garbage-collection-in-Pre_002dScheme"></a>
</dd>
<dt><strong>There is no garbage collector in Pre-Scheme.</strong></dt>
<dd><p>All memory management is manual, as in C, although there are two levels
to memory management, for higher- and lower-level purposes: pointers &amp;
addresses. Pointers represent higher-level data that are statically
checked for type coherency, such as vectors of a certain element type,
or strings. Addresses represent direct, low-level memory indices.
</p>
<a name="index-closures-in-Pre_002dScheme"></a>
<a name="index-Pre_002dScheme-closures"></a>
</dd>
<dt><strong>Pre-Scheme has no closures.</strong></dt>
<dd><p><code>Lambda</code> expressions that would require full closures at run-time
&mdash; <i>e.g.</i>, those whose values are stored in the heap &mdash; are not
permitted in Pre-Scheme. However, the Pre-Scheme compiler can hoist
many <code>lambda</code> expressions to the top level, removing the need of
closures for them. (Closures would be much less useful in the absence
of garbage collection, in any case.) If the Pre-Scheme compiler is
unable to move a <code>lambda</code> to a place where it requires no closure,
it signals an error to the user.
</p>
<a name="index-Pre_002dScheme-tail-call-optimization"></a>
<a name="index-tail-call-optimization-in-Pre_002dScheme"></a>
<a name="index-tail-recursion-in-Pre_002dScheme"></a>
</dd>
<dt><strong>Tail call optimization is not universal.</strong></dt>
<dd><p>The Pre-Scheme compiler optimizes tail calls where it is possible &mdash;
typically, just in local loops and top-level procedures that are not
exported from the package, but there are other heuristics &mdash;, but it
is not universal. Programmers may force tail call optimization with
Pre-Scheme&rsquo;s <code>goto</code> special form (see <a href="#Tail-call-optimization-in-Pre_002dScheme">Tail call optimization in Pre-Scheme</a>), but, in situations where the compiler would not have
optimized the tail call, this can make the generated code have to jump
through many hoops to be a tail call &mdash; often necessitating code bloat,
because the code of the tail-called procedure is integrated into the
caller&rsquo;s driver loop &mdash;; and, where the compiler would have otherwise
optimized the tail call, <code>goto</code> has no effect anyway.
</p>
<a name="index-Pre_002dScheme-type-inference"></a>
<a name="index-static-types-in-Pre_002dScheme"></a>
</dd>
<dt><strong>Types are strictly verified with Hindley-Milner type inference.</strong></dt>
<dd><p>The types of Pre-Scheme programs are statically verified based on
Hindley-Milner type inference, with some modifications specific to
Pre-Scheme. Type information is <em>not</em> retained at run-time; any
tagging must be performed explicitly.
</p>
<a name="index-continuations-in-Pre_002dScheme"></a>
</dd>
<dt><strong>Pre-Scheme does not support first-class continuations.</strong></dt>
<dd><p>There is no <code>call-with-current-continuation</code> or other continuation
manipulation interface. It has been suggested that downward-only
continuations, based on C&rsquo;s <code>setjmp</code> &amp; <code>longjmp</code>, might be
implemented in the future, but this is not yet the case.<a name="DOCF1" href="#FOOT1"><sup>1</sup></a>
</p>
<a name="index-Pre_002dScheme-numbers"></a>
<a name="index-numbers-in-Pre_002dScheme"></a>
</dd>
<dt><strong>The full numeric tower of R5RS is not supported by Pre-Scheme.</strong></dt>
<dd><p>Pre-Scheme&rsquo;s only numeric types are fixnums and flonums, with precision
determined by the architecture on which the Pre-Scheme code runs.
Fixnums are translated to C as the <code>long</code> type; flonums are
translated as the <code>float</code> type.
</p>
<a name="index-top_002dlevel-evaluation-in-Pre_002dScheme"></a>
<a name="index-evaluation-of-top_002dlevel-code-in-Pre_002dScheme"></a>
<a name="index-Pre_002dScheme-top_002dlevel-evaluation"></a>
<a name="index-compile_002dtime-evaluation-in-Pre_002dScheme"></a>
</dd>
<dt><strong>Top-level Pre-Scheme code is evaluated at compile-time.</strong></dt>
<dd><p>Closures actually <em>are</em> available, as long as they may be
eliminated before run-time. Code evaluated at compile-time also does
not require satisfaction of strict static typing. Moreover, certain
procedures, such as <code>vector-length</code>, are available only at
compile-time.
</p></dd>
</dl>
<hr>
<a name="Pre_002dScheme-type-specifiers"></a>
<div class="header">
<p>
Next: <a href="#Standard-Pre_002dScheme-environment" accesskey="n" rel="next">Standard Pre-Scheme environment</a>, Previous: <a href="#Differences-between-Pre_002dScheme-_0026-Scheme" accesskey="p" rel="prev">Differences between Pre-Scheme &amp; Scheme</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Type-specifiers"></a>
<h3 class="section">1.2 Type specifiers</h3>
<a name="index-Pre_002dScheme-type-inference-1"></a>
<a name="index-static-types-in-Pre_002dScheme-1"></a>
<p>Although Pre-Scheme&rsquo;s static type system is based mostly on
Hindley-Milner type inference, with as little explicit type information
as possible, there are still places where it is necessary to specify
types explicitly; for example, see <a href="#Pre_002dScheme-access-to-C-functions-and-macros">Pre-Scheme access to C functions and macros</a>. There are several different kinds of types with different
syntax:
</p>
<dl compact="compact">
<dt><code><var>type-name</var></code></dt>
<dd><p>Symbols denote either record type or base types. Record types are
defined with the <code>define-record-type</code> special form described
later; the following base types are defined:
</p>
<dl compact="compact">
<dt><code>integer</code></dt>
<dd><p>Fixed-size integers (fixnums). This type is translated into C as
<code>long</code>. The actual size depends on the size of C&rsquo;s <code>long</code>,
which on most architectures is 32 bits.
</p>
</dd>
<dt><code>float</code></dt>
<dd><p>Floating-point data. This type translates to C as <code>double</code>.
</p>
</dd>
<dt><code>null</code></dt>
<dd><p>Type which has no value. The <code>null</code> type translates to the C
<code>void</code> type.
</p>
</dd>
<dt><code>unit</code></dt>
<dd><p>Type which has one value. Actually, this, too, translates to C&rsquo;s
<code>void</code>, so that it has one value is not strictly true.
</p>
</dd>
<dt><code>boolean</code></dt>
<dd><p>Booleans translate to the C <code>char</code> type. <code>#t</code> is emitted as
<code>TRUE</code>, and <code>#f</code>, as <code>FALSE</code>; these are usually the same
as <code>1</code> &amp; <code>0</code>, respectively.
</p>
</dd>
<dt><code>input-port</code></dt>
<dt><code>output-port</code></dt>
<dd><p>I/O ports. On Unix, since Pre-Scheme uses <code>stdio</code>, these are
translated to <code>FILE *</code>s, <code>stdio</code> file streams.
</p>
</dd>
<dt><code>char</code></dt>
<dd><p>Characters. The size of characters is dependent on the underlying C
compiler&rsquo;s implementation of the <code>char</code> type.
</p>
</dd>
<dt><code>address</code></dt>
<dd><p>Simple addresses for use in <a href="#Low_002dlevel-Pre_002dScheme-memory-manipulation">Pre-Scheme&rsquo;s low-level memory manipulation primitives</a>;
see that section for more details.
</p></dd>
</dl>
</dd>
<dt><code>(=&gt; (<var>argument-type</var> &hellip;) <var>return-type</var> &hellip;)</code></dt>
<dd><p>The types of procedures, known as &lsquo;arrow&rsquo; types.
</p>
</dd>
<dt><code>(^ <var>type</var>)</code></dt>
<dd><p>The type of pointers that point to <var>type</var>. Note that these are
distinct from the address type. Pointer types are statically verified
to be coherent data, with no defined operations except for accessing
offsets in memory from the pointer &mdash; <i>i.e.</i> operations such as
<code>vector-ref</code> &mdash;; addresses simply index bytes, on which only
direct dereferencing, but also arbitrary address arithmetic, is
available. Pointers and addresses are <em>not</em> interchangeable, and
and there is no way to convert between them, as that would break the
type safety of Pre-Scheme pointers.
</p>
</dd>
<dt><code>(tuple <var>type</var> &hellip;)</code></dt>
<dd><p>Multiple value types, internally used for argument &amp; return types.
</p></dd>
</dl>
<hr>
<a name="Standard-Pre_002dScheme-environment"></a>
<div class="header">
<p>
Next: <a href="#More-Pre_002dScheme-packages" accesskey="n" rel="next">More Pre-Scheme packages</a>, Previous: <a href="#Pre_002dScheme-type-specifiers" accesskey="p" rel="prev">Pre-Scheme type specifiers</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Standard-environment"></a>
<h3 class="section">1.3 Standard environment</h3>
<a name="index-prescheme"></a>
<p>Pre-Scheme programs usually open the <code>prescheme</code> structure. There
are several other structures built-in to Pre-Scheme as well, described
in the next section. This section describes the <code>prescheme</code>
structure.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment">
</pre></th></tr><tr><td align="left" valign="top">&bull; <a href="#Scheme-bindings-in-Pre_002dScheme" accesskey="1">Scheme bindings in Pre-Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">Bindings from R5RS
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Tail-call-optimization-in-Pre_002dScheme" accesskey="2">Tail call optimization in Pre-Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-bitwise-manipulation" accesskey="3">Pre-Scheme bitwise manipulation</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Compound-Pre_002dScheme-data-manipulation" accesskey="4">Compound Pre-Scheme data manipulation</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-error-handling" accesskey="5">Pre-Scheme error handling</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Input-_0026-output-in-Pre_002dScheme" accesskey="6">Input &amp; output in Pre-Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-access-to-C-functions-and-macros" accesskey="7">Pre-Scheme access to C functions and macros</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment">
</pre></th></tr></table>
<hr>
<a name="Scheme-bindings-in-Pre_002dScheme"></a>
<div class="header">
<p>
Next: <a href="#Tail-call-optimization-in-Pre_002dScheme" accesskey="n" rel="next">Tail call optimization in Pre-Scheme</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Scheme-bindings"></a>
<h4 class="subsection">1.3.1 Scheme bindings</h4>
<p>Bindings for all the names specified here from R5RS Scheme are
available in Pre-Scheme. The remainder of the sections after this one
detail Pre-Scheme specifics that are not a part of Scheme.
</p>
<dl>
<dt><a name="index-define"></a>syntax: <strong>define</strong> <em>name value</em></dt>
<dt><a name="index-define-1"></a>syntax: <strong>define</strong> <em>(name . argument-list) value</em></dt>
<dt><a name="index-if"></a>syntax: <strong>if</strong> <em>condition consequent [alternate]</em></dt>
<dt><a name="index-let"></a>syntax: <strong>let</strong> <em>((name expression) &hellip;) body</em></dt>
<dt><a name="index-let_002a"></a>syntax: <strong>let*</strong> <em>((name expression) &hellip;) body</em></dt>
<dt><a name="index-and"></a>syntax: <strong>and</strong> <em>conjunct &hellip;</em></dt>
<dt><a name="index-or"></a>syntax: <strong>or</strong> <em>disjunct &hellip;</em></dt>
<dt><a name="index-cond"></a>syntax: <strong>cond</strong> <em>cond-clause &hellip;</em></dt>
<dt><a name="index-do"></a>syntax: <strong>do</strong> <em>((name init-exp [step-exp]) &hellip;) (test-exp [return-exp]) body</em></dt>
<dd><p>These special forms &amp; macros are all unchanged from their R5RS
specifications.
</p></dd></dl>
<dl>
<dt><a name="index-define_002dsyntax"></a>syntax: <strong>define-syntax</strong> <em>name transformer-expression [aux-names]</em></dt>
<dt><a name="index-let_002dsyntax"></a>syntax: <strong>let-syntax</strong> <em>((name transformer-expression) &hellip;) body</em></dt>
<dt><a name="index-letrec_002dsyntax"></a>syntax: <strong>letrec-syntax</strong> <em>((name transformer-expression) &hellip;) body</em></dt>
<dd><p>Pre-Scheme&rsquo;s macro facility is exactly the same as Scheme48&rsquo;s.
<var>Transformer-expression</var> may be either a <code>syntax-rules</code> or an
explicit renaming transformer, just as in Scheme48; in the latter case,
it is evaluated either in a standard Scheme environment or however the
<code>for-syntax</code> clause specified of the package in whose code the
transformer appeared. For details on the extra <var>aux-names</var> operand
to <code>define-syntax</code>, see &lsquo;Explicit renaming macros&rsquo;.
</p></dd></dl>
<dl>
<dt><a name="index-not"></a>procedure: <strong>not</strong> <em>boolean --&gt; boolean</em></dt>
<dt><a name="index-eq_003f"></a>procedure: <strong>eq?</strong> <em>value<i><sub>a</sub></i></em></dt>
<dt><a name="index-char_003d_003f"></a>procedure: <strong>char=?</strong> <em>char<i><sub>a</sub></i></em></dt>
<dt><a name="index-char_003c_003f"></a>procedure: <strong>char&lt;?</strong> <em>char<i><sub>a</sub></i></em></dt>
<dt><a name="index-values"></a>procedure: <strong>values</strong> <em>value &hellip; --&gt; values</em></dt>
<dt><a name="index-call_002dwith_002dvalues"></a>procedure: <strong>call-with-values</strong> <em>producer consumer --&gt; values</em></dt>
<dt><a name="index-current_002dinput_002dport"></a>procedure: <strong>current-input-port</strong> <em>--&gt; input-port</em></dt>
<dt><a name="index-current_002doutput_002dport"></a>procedure: <strong>current-output-port</strong> <em>--&gt; output-port</em></dt>
<dd><p>These procedures are all unchanged from their R5RS specifications.
</p></dd></dl>
<dl>
<dt><a name="index-_002b"></a>procedure: <strong>+</strong> <em>addend &hellip; --&gt; integer</em></dt>
<dt><a name="index-_002d"></a>procedure: <strong>-</strong> <em>integer --&gt; integer</em></dt>
<dt><a name="index-_002d-1"></a>procedure: <strong>-</strong> <em>minuend subtrahend --&gt; integer</em></dt>
<dt><a name="index-_002a"></a>procedure: <strong>*</strong> <em>multiplicand &hellip; --&gt; integer</em></dt>
<dt><a name="index-_003d"></a>procedure: <strong>=</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-_003c"></a>procedure: <strong>&lt;</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-_003e"></a>procedure: <strong>&gt;</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-_003c_003d"></a>procedure: <strong>&lt;=</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-_003e_003d"></a>procedure: <strong>&gt;=</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-min"></a>procedure: <strong>min</strong> <em>integer<i><sub>1</sub></i></em></dt>
<dt><a name="index-max"></a>procedure: <strong>max</strong> <em>integer<i><sub>1</sub></i></em></dt>
<dt><a name="index-abs"></a>procedure: <strong>abs</strong> <em>integer --&gt; integer</em></dt>
<dt><a name="index-quotient"></a>procedure: <strong>quotient</strong> <em>divisor dividend --&gt; integer</em></dt>
<dt><a name="index-remainder"></a>procedure: <strong>remainder</strong> <em>divisor dividend --&gt; integer</em></dt>
<dt><a name="index-expt"></a>procedure: <strong>expt</strong> <em>base exponent --&gt; integer</em></dt>
<dd><p>These numerical operations are all unchanged from their R5RS
counterparts, except that they are applicable only to fixnums, not to
flonums, and they always return fixnums.
</p></dd></dl>
<hr>
<a name="Tail-call-optimization-in-Pre_002dScheme"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme-bitwise-manipulation" accesskey="n" rel="next">Pre-Scheme bitwise manipulation</a>, Previous: <a href="#Scheme-bindings-in-Pre_002dScheme" accesskey="p" rel="prev">Scheme bindings in Pre-Scheme</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Tail-call-optimization"></a>
<h4 class="subsection">1.3.2 Tail call optimization</h4>
<a name="index-Pre_002dScheme-tail-call-optimization-1"></a>
<a name="index-tail-call-optimization-in-Pre_002dScheme-1"></a>
<a name="index-tail-recursion-in-Pre_002dScheme-1"></a>
<dl>
<dt><a name="index-goto"></a>syntax: <strong>goto</strong> <em>procedure argument &hellip;</em></dt>
<dd><p>The Pre-Scheme compiler can be forced to optimize tail calls, even
those it would not have otherwise optimized, by use of the <code>goto</code>
special form, rather than simple procedure calls. In every respect
other than tail call optimization, this is equivalent to calling
<var>procedure</var> with the given arguments. Note, however, that uses of
<code>goto</code> may cause code to blow up if the Pre-Scheme compiler had
reason not to optimize the tail call were it not for the <code>goto</code>:
it may need to merge the tail-called procedure into the caller&rsquo;s code.
</p></dd></dl>
<hr>
<a name="Pre_002dScheme-bitwise-manipulation"></a>
<div class="header">
<p>
Next: <a href="#Compound-Pre_002dScheme-data-manipulation" accesskey="n" rel="next">Compound Pre-Scheme data manipulation</a>, Previous: <a href="#Tail-call-optimization-in-Pre_002dScheme" accesskey="p" rel="prev">Tail call optimization in Pre-Scheme</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Bitwise-manipulation"></a>
<h4 class="subsection">1.3.3 Bitwise manipulation</h4>
<p>Pre-Scheme provides basic bitwise manipulation operators.
</p>
<dl>
<dt><a name="index-bitwise_002dand"></a>procedure: <strong>bitwise-and</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-bitwise_002dior"></a>procedure: <strong>bitwise-ior</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-bitwise_002dxor"></a>procedure: <strong>bitwise-xor</strong> <em>integer<i><sub>a</sub></i></em></dt>
<dt><a name="index-bitwise_002dnot"></a>procedure: <strong>bitwise-not</strong> <em>integer --&gt; integer</em></dt>
<dd><p>Bitwise boolean logical operations.
</p></dd></dl>
<dl>
<dt><a name="index-shift_002dleft"></a>procedure: <strong>shift-left</strong> <em>integer count --&gt; integer</em></dt>
<dt><a name="index-arithmetic_002dshift_002dright"></a>procedure: <strong>arithmetic-shift-right</strong> <em>integer count --&gt; integer</em></dt>
<dt><a name="index-logical_002dshift_002dright"></a>procedure: <strong>logical-shift-right</strong> <em>integer count --&gt; integer</em></dt>
<dd><p>Three ways to shift bit strings: <code>shift-left</code> shifts <var>integer</var>
left by <var>count</var>, <code>arithmetic-shift-right</code> shifts <var>integer</var>
right by <var>count</var> arithmetically, and <code>logical-shift-right</code>
shifts <var>integer</var> right by <var>count</var> logically.
</p></dd></dl>
<hr>
<a name="Compound-Pre_002dScheme-data-manipulation"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme-error-handling" accesskey="n" rel="next">Pre-Scheme error handling</a>, Previous: <a href="#Pre_002dScheme-bitwise-manipulation" accesskey="p" rel="prev">Pre-Scheme bitwise manipulation</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Compound-data-manipulation"></a>
<h4 class="subsection">1.3.4 Compound data manipulation</h4>
<a name="index-vectors-in-Pre_002dScheme"></a>
<a name="index-Pre_002dScheme-vectors"></a>
<a name="index-strings-in-Pre_002dScheme"></a>
<a name="index-Pre_002dScheme-strings"></a>
<a name="index-Pre_002dScheme-memory-management-1"></a>
<a name="index-memory-management-in-Pre_002dScheme-1"></a>
<p>Pre-Scheme has somewhat lower-level vector &amp; string facilities than
Scheme, with more orientation towards static typing. It also provides
a statically typed record facility, which translates to C structs,
though not described here, as it is not in the <code>prescheme</code>
structure; see <a href="#Pre_002dScheme-record-types">Pre-Scheme record types</a>.
</p>
<dl>
<dt><a name="index-make_002dvector"></a>procedure: <strong>make-vector</strong> <em>length init --&gt; vector</em></dt>
<dt><a name="index-vector_002dlength"></a>procedure: <strong>vector-length</strong> <em>vector --&gt; integer</em></dt>
<dt><a name="index-vector_002dref"></a>procedure: <strong>vector-ref</strong> <em>vector index --&gt; value</em></dt>
<dt><a name="index-vector_002dset_0021"></a>procedure: <strong>vector-set!</strong> <em>vector index value --&gt; unit</em></dt>
<dd><p>Vectors in Pre-Scheme are almost the same as vectors in regular Scheme,
but with a few differences. <code>Make-vector</code> initializes what it
returns with null pointers (see below); it uses the <em>required</em>
(unlike Scheme) <var>init</var> argument only to determine the type of the
vector: vectors are statically typed; they can contain only values that
have the same static type as <var>init</var>. <code>Vector-length</code> is
available only at the top level, where calls to it can be evaluated at
compile-time; vectors do not at run-time store their lengths. Vectors
must also be explicitly deallocated.
</p>
<p><strong>Warning:</strong> As in C, there is <em>no</em> vector bounds checking at
run-time.
</p></dd></dl>
<dl>
<dt><a name="index-make_002dstring"></a>procedure: <strong>make-string</strong> <em>length --&gt; string</em></dt>
<dt><a name="index-string_002dlength"></a>procedure: <strong>string-length</strong> <em>string --&gt; integer</em></dt>
<dt><a name="index-string_002dref"></a>procedure: <strong>string-ref</strong> <em>string index --&gt; char</em></dt>
<dt><a name="index-string_002dset_0021"></a>procedure: <strong>string-set!</strong> <em>string index char --&gt; unit</em></dt>
<dd><p>Strings in Pre-Scheme are the nearly same as strings in R5RS Scheme.
The only three differences here are that <code>make-string</code> accepts
exactly one argument, strings must be explicitly deallocated, and
strings are <code>nul</code>-terminated: <code>string-length</code> operates by
scanning for the first ASCII <code>nul</code> character in a string.
</p>
<p><strong>Warning:</strong> As in C, there is <em>no</em> string bounds checking at
run-time.
</p></dd></dl>
<dl>
<dt><a name="index-deallocate"></a>procedure: <strong>deallocate</strong> <em>pointer --&gt; unit</em></dt>
<dd><p>Deallocates the memory pointed to by <code>pointer</code>. This is necessary
at the end of a string, vector, or record&rsquo;s life, as Pre-Scheme data
are not automatically garbage-collected.
</p></dd></dl>
<dl>
<dt><a name="index-null_002dpointer"></a>procedure: <strong>null-pointer</strong> <em>--&gt; null-pointer</em></dt>
<dt><a name="index-null_002dpointer_003f"></a>procedure: <strong>null-pointer?</strong> <em>pointer --&gt; boolean</em></dt>
<dd><p><code>Null-pointer</code> returns the distinguished null pointer object. It
corresponds with <code>0</code> in a pointer context or <code>NULL</code> in C.
<code>Null-pointer?</code> returns true if <var>pointer</var> is a null pointer,
or false if not.
</p></dd></dl>
<hr>
<a name="Pre_002dScheme-error-handling"></a>
<div class="header">
<p>
Next: <a href="#Input-_0026-output-in-Pre_002dScheme" accesskey="n" rel="next">Input &amp; output in Pre-Scheme</a>, Previous: <a href="#Compound-Pre_002dScheme-data-manipulation" accesskey="p" rel="prev">Compound Pre-Scheme data manipulation</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Error-handling"></a>
<h4 class="subsection">1.3.5 Error handling</h4>
<p>Pre-Scheme&rsquo;s method of error handling is similar to the most common one
in C: error codes. There is an enumeration <code>errors</code> of some error
codes commonly and portably encountered in Pre-Scheme.
</p>
<dl>
<dt><a name="index-errors"></a>enumeration: <strong>errors</strong></dt>
<dd><div class="lisp">
<pre class="lisp">(define-enumeration errors
(no-errors
parse-error
file-not-found
out-of-memory
invalid-port))</pre></div>
<p>Each enumerand has the following meaning:
</p>
<dl compact="compact">
<dt>no-errors</dt>
<dd><p>Absence of error: success.
</p>
</dd>
<dt>parse-error</dt>
<dd><p>Any kind of parsing error. The Scheme48 VM uses this when someone
attempts to resume a malformed suspended heap image.
</p>
</dd>
<dt>file-not-found</dt>
<dd><p>Used when an operation that operates on a file given a string filename
found that the file for that filename was absent.
</p>
</dd>
<dt>out-of-memory</dt>
<dd><p>When there is no more memory to allocate.
</p>
</dd>
<dt>invalid-port</dt>
<dd><p>Unused.
</p></dd>
</dl>
</dd></dl>
<dl>
<dt><a name="index-error_002dstring"></a>procedure: <strong>error-string</strong> <em>error-status --&gt; string</em></dt>
<dd><p>Returns a string describing the meaning of the <code>errors</code> enumerand
<var>error-status</var>.
</p></dd></dl>
<dl>
<dt><a name="index-error"></a>procedure: <strong>error</strong> <em>message irritant &hellip;</em></dt>
<dd><p>Signals a fatal error with the given message &amp; related irritants and
halts the program. On Unix, the program&rsquo;s exit code is -1.
</p></dd></dl>
<hr>
<a name="Input-_0026-output-in-Pre_002dScheme"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme-access-to-C-functions-and-macros" accesskey="n" rel="next">Pre-Scheme access to C functions and macros</a>, Previous: <a href="#Pre_002dScheme-error-handling" accesskey="p" rel="prev">Pre-Scheme error handling</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Input-_0026-output"></a>
<h4 class="subsection">1.3.6 Input &amp; output</h4>
<p>Pre-Scheme&rsquo;s I/O facilities are somewhat different from Scheme&rsquo;s, given
the low level and the static type strictness. There is no exception
mechanism in Pre-Scheme; everything is maintained by returning a status
token, as in C. Pre-Scheme&rsquo;s built-in I/O facilities are buffered.
<a name="DOCF2" href="#FOOT2"><sup>2</sup></a>
(see <a href="#Low_002dlevel-Pre_002dScheme-memory-manipulation">Low-level Pre-Scheme memory manipulation</a>, for two other I/O
primitives, <code>read-block</code> &amp; <code>write-block</code>, for reading &amp;
writing blocks of direct memory.)
</p>
<dl>
<dt><a name="index-open_002dinput_002dfile"></a>procedure: <strong>open-input-file</strong> <em>filename --&gt; [port status]</em></dt>
<dt><a name="index-open_002doutput_002dfile"></a>procedure: <strong>open-output-file</strong> <em>filename --&gt; [port status]</em></dt>
<dt><a name="index-close_002dinput_002dport"></a>procedure: <strong>close-input-port</strong> <em>input-port --&gt; status</em></dt>
<dt><a name="index-close_002doutput_002dport"></a>procedure: <strong>close-output-port</strong> <em>output-port --&gt; status</em></dt>
<dd><p><code>Open-input-file</code> &amp; <code>open-output-file</code> open ports for the
given filenames. They each return two values: the newly open port and
an <code>errors</code> enumerand status. Users of these procedures should
always check the error status before proceeding to operate with the
port. <code>Close-input-port</code> &amp; <code>close-output-port</code> close their
port arguments and return the <code>errors</code> enumerand status of the
closing.
</p></dd></dl>
<dl>
<dt><a name="index-read_002dchar"></a>procedure: <strong>read-char</strong> <em>input-port --&gt; [char eof? status]</em></dt>
<dt><a name="index-peek_002dchar"></a>procedure: <strong>peek-char</strong> <em>input-port --&gt; [char eof? status]</em></dt>
<dt><a name="index-read_002dinteger"></a>procedure: <strong>read-integer</strong> <em>input-port --&gt; [integer eof? status]</em></dt>
<dd><p><code>Read-char</code> reads &amp; consumes a single character from its
<var>input-port</var> argument. <code>Peek-char</code> reads, but does not
consume, a single character from <var>input-port</var>. <code>Read-integer</code>
parses an integer literal, including sign. All of these also return
two other values: whether or not the file is at the end and any
<code>errors</code> enumerand status. If any error occurred, the first two
values returned should be ignored. If <var>status</var> is <code>(enum
errors no-errors)</code>, users of these three procedures should then check
<var>eof?</var>; it is true if <var>input-port</var> was at the end of the file
with nothing more left to read and false otherwise. Finally, if both
<var>status</var> is <code>(enum errors no-errors)</code> and <var>eof?</var> is false,
the first value returned may be safely used.
</p></dd></dl>
<dl>
<dt><a name="index-write_002dchar"></a>procedure: <strong>write-char</strong> <em>char output-port --&gt; status</em></dt>
<dt><a name="index-newline"></a>procedure: <strong>newline</strong> <em>output-port --&gt; status</em></dt>
<dt><a name="index-write_002dstring"></a>procedure: <strong>write-string</strong> <em>string output-port --&gt; status</em></dt>
<dt><a name="index-write_002dinteger"></a>procedure: <strong>write-integer</strong> <em>integer output-port --&gt; status</em></dt>
<dd><p>These all write particular elements to their <var>output-port</var>
arguments. <code>Write-char</code> writes individual characters.
<code>Newline</code> writes newlines (line-feed, or ASCII codepoint 10, on
Unix). <code>Write-string</code> writes the contents of <var>string</var>.
<code>Write-integer</code> writes an ASCII representation of <var>integer</var> to
port, suitable to be read by <code>read-integer</code>. These all return an
<code>errors</code> enumerand status. If it is <code>no-errors</code>, the write
succeeded.
</p></dd></dl>
<dl>
<dt><a name="index-force_002doutput"></a>procedure: <strong>force-output</strong> <em>output-port --&gt; status</em></dt>
<dd><p>Forces all buffered output in <var>output-port</var>. <var>Status</var> tells
whether or not the operation was successful.
</p></dd></dl>
<hr>
<a name="Pre_002dScheme-access-to-C-functions-and-macros"></a>
<div class="header">
<p>
Previous: <a href="#Input-_0026-output-in-Pre_002dScheme" accesskey="p" rel="prev">Input &amp; output in Pre-Scheme</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Access-to-C-functions-and-macros"></a>
<h4 class="subsection">1.3.7 Access to C functions and macros</h4>
<dl>
<dt><a name="index-external"></a>syntax: <strong>external</strong> <em>c-name ps-type --&gt; procedure</em></dt>
<dd><p>Special form for accessing C functions &amp; macros. Calls in Pre-Scheme to
the resulting procedure are compiled to calls in C to the function or
macro named by <var>c-name</var>, which should be a string. <var>PS-type</var> is
the <a href="#Pre_002dScheme-type-specifiers">Pre-Scheme type</a> that the
procedure should have, which is necessary for type inference.
</p></dd></dl>
<hr>
<a name="More-Pre_002dScheme-packages"></a>
<div class="header">
<p>
Next: <a href="#Invoking-the-Pre_002dScheme-compiler" accesskey="n" rel="next">Invoking the Pre-Scheme compiler</a>, Previous: <a href="#Standard-Pre_002dScheme-environment" accesskey="p" rel="prev">Standard Pre-Scheme environment</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="More-Pre_002dScheme-packages-1"></a>
<h3 class="section">1.4 More Pre-Scheme packages</h3>
<p>Along with the <code>prescheme</code> structure, there are several other
structures built-in to Pre-Scheme.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment">
</pre></th></tr><tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-floating-point-operation" accesskey="1">Pre-Scheme floating point operation</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Pre_002dScheme-record-types" accesskey="2">Pre-Scheme record types</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Multiple-return-values-in-Pre_002dScheme" accesskey="3">Multiple return values in Pre-Scheme</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top">&bull; <a href="#Low_002dlevel-Pre_002dScheme-memory-manipulation" accesskey="4">Low-level Pre-Scheme memory manipulation</a>:</td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment">
</pre></th></tr></table>
<hr>
<a name="Pre_002dScheme-floating-point-operation"></a>
<div class="header">
<p>
Next: <a href="#Pre_002dScheme-record-types" accesskey="n" rel="next">Pre-Scheme record types</a>, Up: <a href="#More-Pre_002dScheme-packages" accesskey="u" rel="up">More Pre-Scheme packages</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Floating-point-operation"></a>
<h4 class="subsection">1.4.1 Floating point operation</h4>
<a name="index-ps_002dflonums"></a>
<p>Since Pre-Scheme&rsquo;s strict static type system would not permit
overloading of the arithmetic operators for integers &amp; floats, it
provides a different set of operators for floats. These names are all
exported by the <code>ps-flonums</code> structure.
</p>
<dl>
<dt><a name="index-fl_002b"></a>procedure: <strong>fl+</strong> <em>augend addend &hellip; --&gt; float</em></dt>
<dt><a name="index-fl_002d"></a>procedure: <strong>fl-</strong> <em>float --&gt; float</em></dt>
<dt><a name="index-fl_002d-1"></a>procedure: <strong>fl-</strong> <em>minuend subtrahend --&gt; float</em></dt>
<dt><a name="index-fl_002a"></a>procedure: <strong>fl*</strong> <em>multiplier multiplicand &hellip; --&gt; float</em></dt>
<dt><a name="index-fl_002f"></a>procedure: <strong>fl/</strong> <em>divisor dividend --&gt; float</em></dt>
<dt><a name="index-fl_003d"></a>procedure: <strong>fl=</strong> <em>float<i><sub>a</sub></i></em></dt>
<dt><a name="index-fl_003c"></a>procedure: <strong>fl&lt;</strong> <em>float<i><sub>a</sub></i></em></dt>
<dt><a name="index-fl_003e"></a>procedure: <strong>fl&gt;</strong> <em>float<i><sub>a</sub></i></em></dt>
<dt><a name="index-fl_003c_003d"></a>procedure: <strong>fl&lt;=</strong> <em>float<i><sub>a</sub></i></em></dt>
<dt><a name="index-fl_003e_003d"></a>procedure: <strong>fl&gt;=</strong> <em>float<i><sub>a</sub></i></em></dt>
<dd><p>All of these operations <code>fl<var>op</var></code> correspond as floating point
variations of their <var>op</var> integer equivalents.
</p></dd></dl>
<hr>
<a name="Pre_002dScheme-record-types"></a>
<div class="header">
<p>
Next: <a href="#Multiple-return-values-in-Pre_002dScheme" accesskey="n" rel="next">Multiple return values in Pre-Scheme</a>, Previous: <a href="#Pre_002dScheme-floating-point-operation" accesskey="p" rel="prev">Pre-Scheme floating point operation</a>, Up: <a href="#More-Pre_002dScheme-packages" accesskey="u" rel="up">More Pre-Scheme packages</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Record-types"></a>
<h4 class="subsection">1.4.2 Record types</h4>
<a name="index-ps_002drecord_002dtypes"></a>
<p>The <code>ps-record-types</code> structure defines the following special form
for introducing record types. Pre-Scheme record types are translated
to C as structs.
</p>
<dl>
<dt><a name="index-define_002drecord_002dtype"></a>syntax: <strong>define-record-type</strong></dt>
<dd><div class="lisp">
<pre class="lisp">(define-record-type <var>type</var> <var>type-descriptor</var>
(<var>constructor</var> <var>argument-field-tag</var> &hellip;)
(<var>field-tag&lt;1&gt;</var> <var>field-type-spec&lt;1&gt;</var>
<var>field-accessor&lt;1&gt;</var> [<var>field-modifier&lt;1&gt;</var>])
(<var>field-tag&lt;2&gt;</var> <var>field-type-spec&lt;2&gt;</var>
<var>field-accessor&lt;2&gt;</var> [<var>field-modifier&lt;2&gt;</var>])
&hellip;
(<var>field-tag&lt;n&gt;</var> <var>field-type-spec&lt;n&gt;</var>
<var>field-accessor&lt;n&gt;</var> [<var>field-modifier&lt;n&gt;</var>])</pre></div>
<p>Defines a record type. <var>Type</var> is mangled to the C struct type name
(<var>type-descriptor-name</var> is unused unless running Pre-Scheme as
Scheme). <var>Constructor</var> is defined to construct a record of the new
type and initialize the fields <var>argument-type-field</var> &hellip; with
its arguments, respectively. If it cannot allocate a sufficient
quantity of memory, <var>constructor</var> returns a null pointer. The
initial values of fields that are not passed to the constructor are
undefined. For each field <var>field&lt;i&gt;</var> specified,
</p>
<ul>
<li> <var>field&lt;i&gt;</var> is specified to have the type
<var>field-type-spec&lt;i&gt;</var>;
</li><li> <var>field-accessor&lt;i&gt;</var> is defined to be a procedure of one
argument, a record of type <var>type-name</var>, that returns the value of
the field <var>field&lt;i&gt;</var> of that record &mdash; its type is defined to
be <code>(=&gt; (<var>type-name</var>) <var>field-type-spec&lt;i&gt;</var>)</code>; and
</li><li> if present, <var>field-modifier&lt;i&gt;</var> is defined to be a
procedure of two arguments, a record of type <var>type-name</var> and a
value of type <var>field-type-spec</var>, that assigns the value of the
field <var>field&lt;i&gt;</var> in its first argument to be the value of its
second argument; its type is <code>(=&gt; (<var>type-name</var>
<var>field-type-spec</var>) unit)</code>.
</li></ul>
<p>Records must be deallocated explicitly when their lifetime has expired
with <code>deallocate</code>.
</p></dd></dl>
<hr>
<a name="Multiple-return-values-in-Pre_002dScheme"></a>
<div class="header">
<p>
Next: <a href="#Low_002dlevel-Pre_002dScheme-memory-manipulation" accesskey="n" rel="next">Low-level Pre-Scheme memory manipulation</a>, Previous: <a href="#Pre_002dScheme-record-types" accesskey="p" rel="prev">Pre-Scheme record types</a>, Up: <a href="#More-Pre_002dScheme-packages" accesskey="u" rel="up">More Pre-Scheme packages</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Multiple-return-values"></a>
<h4 class="subsection">1.4.3 Multiple return values</h4>
<a name="index-ps_002dreceive"></a>
<p>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</code> structure exports the two
multiple return value primitives, <code>call-with-values</code> and
<code>values</code>, but the <code>ps-receive</code> structure exports this macro
for more conveniently binding multiple return values.
</p>
<dl>
<dt><a name="index-receive"></a>syntax: <strong>receive</strong> <em>formals producer body</em></dt>
<dd><p>Binds the <code>lambda</code> parameter list <var>formals</var> to the multiple
values that <var>producer</var> returns, and evaluates <var>body</var> with the
new variables bound.
</p>
<div class="lisp">
<pre class="lisp">(receive <var>formals</var>
<var>producer</var>
<var>body</var>)
&equiv;
(call-with-values
(lambda () <var>producer</var>)
(lambda <var>formals</var>
<var>body</var>))</pre></div>
</dd></dl>
<hr>
<a name="Low_002dlevel-Pre_002dScheme-memory-manipulation"></a>
<div class="header">
<p>
Previous: <a href="#Multiple-return-values-in-Pre_002dScheme" accesskey="p" rel="prev">Multiple return values in Pre-Scheme</a>, Up: <a href="#More-Pre_002dScheme-packages" accesskey="u" rel="up">More Pre-Scheme packages</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Low_002dlevel-memory-manipulation"></a>
<h4 class="subsection">1.4.4 Low-level memory manipulation</h4>
<a name="index-Pre_002dScheme-memory-management-2"></a>
<a name="index-memory-management-in-Pre_002dScheme-2"></a>
<a name="index-ps_002dmemory"></a>
<p>Pre-Scheme is a low-level language. It provides very low-level, direct
memory manipulation. &lsquo;Addresses&rsquo; index a flat store of sequences of
bytes. While Pre-Scheme &lsquo;pointers&rsquo; 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 &mdash; the values an address represents are
selected by what operation used to read or write from it &mdash;, permit
arbitrary address arithmetic, and are a much more concrete interface
into direct memory. The <code>ps-memory</code> structure exports these
direct memory manipulation primitives.
</p>
<dl>
<dt><a name="index-allocate_002dmemory"></a>procedure: <strong>allocate-memory</strong> <em>size --&gt; address</em></dt>
<dt><a name="index-deallocate_002dmemory"></a>procedure: <strong>deallocate-memory</strong> <em>address --&gt; unit</em></dt>
<dd><p><code>Allocate-memory</code> reserves a sequence of <var>size</var> bytes in the
store and returns an address to the first byte in the sequence.
<code>Deallocate-memory</code> releases the memory at <var>address</var>, which
should have been the initial address of a contiguous byte sequence, as
<code>allocate-memory</code> would return, not an offset address from such an
initial address.
</p></dd></dl>
<dl>
<dt><a name="index-unsigned_002dbyte_002dref"></a>procedure: <strong>unsigned-byte-ref</strong> <em>address --&gt; unsigned-byte</em></dt>
<dt><a name="index-unsigned_002dbyte_002dset_0021"></a>procedure: <strong>unsigned-byte-set!</strong> <em>address unsigned-byte --&gt; unit</em></dt>
<dt><a name="index-word_002dref"></a>procedure: <strong>word-ref</strong> <em>address --&gt; word</em></dt>
<dt><a name="index-word_002dset_0021"></a>procedure: <strong>word-set!</strong> <em>address word --&gt; unit</em></dt>
<dt><a name="index-flonum_002dref"></a>procedure: <strong>flonum-ref</strong> <em>address --&gt; float</em></dt>
<dt><a name="index-flonum_002dset_0021"></a>procedure: <strong>flonum-set!</strong> <em>address float --&gt; unit</em></dt>
<dd><p>Procedures for reading from &amp; storing to memory.
<code>Unsigned-byte-ref</code> &amp; <code>unsigned-byte-set!</code> access &amp; store the
first unsigned byte at <var>address</var>. <code>Word-ref</code> &amp;
<code>word-set!</code> access &amp; store the first word &mdash; Pre-Scheme integer
&mdash; beginning at <var>address</var>. <code>Flonum-ref</code> &amp; <code>flonum-set!</code>
access &amp; store 64-bit floats beginning at <var>address</var>..
</p>
<p><strong>Bug:</strong> <code>Flonum-ref</code> &amp; <code>flonum-set!</code> are unimplemented
in the Pre-Scheme-as-Scheme layer (see <a href="#Running-Pre_002dScheme-as-Scheme">Running Pre-Scheme as Scheme</a>).
</p></dd></dl>
<dl>
<dt><a name="index-address_003f"></a>procedure: <strong>address?</strong> <em>value --&gt; boolean</em></dt>
<dd><p>Disjoint type predicate for addresses.
</p>
<p><strong>Note:</strong> <code>Address?</code> is available <em>only</em> 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.
</p></dd></dl>
<dl>
<dt><a name="index-null_002daddress"></a>constant: <strong>null-address</strong> <em>--&gt; address</em></dt>
<dd><p>The null address. This is somewhat similar to the null pointer, except
that it is an address.
</p>
<p><strong>Note:</strong> One acquires the null <em>pointer</em> by calling the
<em>procedure</em> <code>null-pointer</code>, whereas the constant value of the
<em>binding</em> named <code>null-address</code> is the null <em>address</em>.
</p></dd></dl>
<dl>
<dt><a name="index-null_002daddress_003f"></a>procedure: <strong>null-address?</strong> <em>address --&gt; boolean</em></dt>
<dd><p><code>Null-address?</code> returns true if <var>address</var> is the null
address and false if not.
</p></dd></dl>
<dl>
<dt><a name="index-address_002b"></a>procedure: <strong>address+</strong> <em>address increment --&gt; address</em></dt>
<dt><a name="index-address_002d"></a>procedure: <strong>address-</strong> <em>address decrement --&gt; address</em></dt>
<dt><a name="index-address_002ddifference"></a>procedure: <strong>address-difference</strong> <em>address<i><sub>a</sub></i></em></dt>
<dd><p>Address arithmetic operators. <code>Address+</code> adds <var>increment</var> to
<var>address</var>; <code>address-</code> subtracts <var>decrement</var> from
<var>address</var>; and <code>address-difference</code> returns the integer
difference between <var>address&lt;a&gt;</var> and <var>address&lt;b&gt;</var>.
For any <var>address&lt;p&gt;</var> &amp; <var>address&lt;q&gt;</var>, <code>(address+
<var>address&lt;p&gt;</var> (address-difference <var>address&lt;p&gt;</var>
<var>address&lt;q&gt;</var>))</code> is equal to <var>address&lt;q&gt;</var>.
</p></dd></dl>
<dl>
<dt><a name="index-address_003d"></a>procedure: <strong>address=</strong> <em>address<i><sub>a</sub></i></em></dt>
<dt><a name="index-address_003c"></a>procedure: <strong>address&lt;</strong> <em>address<i><sub>a</sub></i></em></dt>
<dt><a name="index-address_003e"></a>procedure: <strong>address&gt;</strong> <em>address<i><sub>a</sub></i></em></dt>
<dt><a name="index-address_003c_003d"></a>procedure: <strong>address&lt;=</strong> <em>address<i><sub>a</sub></i></em></dt>
<dt><a name="index-address_003e_003d"></a>procedure: <strong>address&gt;=</strong> <em>address<i><sub>a</sub></i></em></dt>
<dd><p>Address comparators.
</p></dd></dl>
<dl>
<dt><a name="index-integer_002d_003eaddress"></a>procedure: <strong>integer-&gt;address</strong> <em>integer --&gt; address</em></dt>
<dt><a name="index-address_002d_003einteger"></a>procedure: <strong>address-&gt;integer</strong> <em>address --&gt; integer</em></dt>
<dd><p>Integers and addresses, although not the same type, may be converted to
and from each other; <code>integer-&gt;address</code> &amp; <code>address-&gt;integer</code>
perform this conversion. Note that Pre-Scheme <em>pointers</em> may not
be converted to addresses or integers, and the converse is also true.
</p></dd></dl>
<dl>
<dt><a name="index-copy_002dmemory_0021"></a>procedure: <strong>copy-memory!</strong> <em>source-address target-address count --&gt; unit</em></dt>
<dd><p>Copies <var>count</var> bytes starting at <var>source-address</var> to
<var>target-address</var>. This is similar to C&rsquo;s <code>memcpy</code>.
</p></dd></dl>
<dl>
<dt><a name="index-memory_002dequal_003f"></a>procedure: <strong>memory-equal?</strong> <em>address<i><sub>a</sub></i></em></dt>
<dd><p>Compares the two sequences of <var>count</var> bytes starting at addresses
<var>address&lt;a&gt;</var> &amp; <var>address&lt;b&gt;</var>. It returns true if every
byte is equal and false if not.
</p></dd></dl>
<dl>
<dt><a name="index-char_002dpointer_002d_003estring"></a>procedure: <strong>char-pointer-&gt;string</strong> <em>address size --&gt; string</em></dt>
<dt><a name="index-char_002dpointer_002d_003enul_002dterminated_002dstring"></a>procedure: <strong>char-pointer-&gt;nul-terminated-string</strong> <em>address --&gt; string</em></dt>
<dd><p><code>Char-pointer-&gt;string</code> returns a string with <var>size</var> bytes from
the contiguous sequence of bytes starting at <var>address</var>.
<code>Char-pointer-&gt;nul-terminated-string</code> does similarly, but it
returns a string whose contents include every byte starting at
<var>address</var> until, but not including, the first 0 byte, <i>i.e.</i> ASCII
nul character, following <var>address</var>.
</p></dd></dl>
<dl>
<dt><a name="index-read_002dblock"></a>procedure: <strong>read-block</strong> <em>port address count --&gt; [count-read eof? status]</em></dt>
<dt><a name="index-write_002dblock"></a>procedure: <strong>write-block</strong> <em>port address count --&gt; status</em></dt>
<dd><p><code>Read-block</code> attempts to read <var>count</var> bytes from <var>port</var>
into memory starting at <var>address</var>. <code>Write-block</code> attempts to
write <var>count</var> bytes to <var>port</var> from the contiguous sequence in
memory starting at <var>address</var>. <code>Read-block</code> 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 <a href="#Pre_002dScheme-error-handling">Pre-Scheme error handling</a>). <code>Write-block</code> returns the error status.
</p></dd></dl>
<hr>
<a name="Invoking-the-Pre_002dScheme-compiler"></a>
<div class="header">
<p>
Next: <a href="#Example-Pre_002dScheme-compiler-usage" accesskey="n" rel="next">Example Pre-Scheme compiler usage</a>, Previous: <a href="#More-Pre_002dScheme-packages" accesskey="p" rel="prev">More Pre-Scheme packages</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Invoking-the-Pre_002dScheme-compiler-1"></a>
<h3 class="section">1.5 Invoking the Pre-Scheme compiler</h3>
<p>Richard Kelsey&rsquo;s Pre-Scheme compiler is a whole-program compiler based
on techniques from his research in transformational compilation
[Kelsey 89]. It compiles the restricted dialect of Scheme to efficient
C, and provides facilities for programmer direction in several
optimizations.
</p>
<a name="Loading-the-compiler"></a>
<h4 class="subsection">1.5.1 Loading the compiler</h4>
<p>There is a script, a Scheme48 &lsquo;command
program&rsquo;, that comes with Scheme48 to load the Pre-Scheme compiler,
which is in the file <samp>ps-compiler/load-ps-compiler.scm</samp>. It must
be loaded from the <samp>ps-compiler/</samp> directory, from Scheme48&rsquo;s main
distribution, into the <code>exec</code> package, after having loaded
<samp>../scheme/prescheme/interface.scm</samp> &amp;
<samp>../scheme/prescheme/package-defs.scm</samp> into the <code>config</code>
package. The Pre-Scheme compiler takes some time to load, so it may be
easier to load it once and dump a heap image of the suspended command
processor after having loaded everything; see &lsquo;Image-building
commands&rsquo;.
</p>
<p>To load the Pre-Scheme compiler and dump an image to the file
<samp>ps-compiler.image</samp> that contains <code>prescheme-compiler</code> in the
user package, send this sequence of commands to the command processor
while in the <samp>ps-compiler/</samp> directory of Scheme48&rsquo;s distribution:
</p>
<div class="lisp">
<pre class="lisp">,config ,load ../scheme/prescheme/interface.scm
,config ,load ../scheme/prescheme/package-defs.scm
,exec ,load load-ps-compiler.scm
,in prescheme-compiler prescheme-compiler
,user (define prescheme-compiler ##)
,dump ps-compiler.image &quot;(Pre-Scheme)&quot;</pre></div>
<a name="Calling-the-compiler"></a>
<h4 class="subsection">1.5.2 Calling the compiler</h4>
<a name="index-prescheme_002dcompiler-1"></a>
<p>After having loaded the Pre-Scheme compiler, the
<code>prescheme-compiler</code> structure is the front end to the compiler
that exports the <code>prescheme-compiler</code> procedure.
</p>
<dl>
<dt><a name="index-prescheme_002dcompiler"></a>procedure: <strong>prescheme-compiler</strong> <em>structure-spec config-filenames init-name c-filename command &hellip;</em></dt>
<dd><p>Invokes the Pre-Scheme compiler. <var>Config-filenames</var> contain module
descriptions (see &lsquo;Module system&rsquo;) for the components of the program.
<var>Structure-spec</var> may be a symbol or a list of symbols, naming the
important structure or structures. All structures that it relies/they
rely on are traced in the packages&rsquo; <code>open</code> clauses. Modules that
are not traced in the dependency graph with root vertices of the given
structure[s] are omitted from the output. <var>C-filename</var> is a string
naming the file to which the C code generated by the Pre-Scheme
compiler should be emitted. <var>Init-name</var> is the name for an
initialization routine, generated automatically by the Pre-Scheme
compiler to initialize some top-level variables. The <var>command</var>
arguments are used to control certain aspects of the compilation. The
following commands are defined:
</p>
<dl compact="compact">
<dt><code>(copy (<var>structure</var> <var>copyable-procedure</var>) &hellip;)</code></dt>
<dd><p>Specifies that each the body of each <var>copyable-procedure</var> from the
respective <var>structure</var> (from one of <var>config-filenames</var>) may be
integrated &amp; duplicated.
</p>
</dd>
<dt><code>(no-copy (<var>structure</var> <var>uncopyable-procedure</var>) &hellip;)</code></dt>
<dd><p>Specifies that the given procedures may not be integrated.
</p>
</dd>
<dt><code>(shadow ((<var>proc-structure</var> <var>procedure</var>) (<var>var-structure</var> <var>variable-to-shadow</var>) &hellip;) &hellip;)</code></dt>
<dd><p>Specifies that, in <var>procedure</var> from <var>proc-structure</var>, the
global variables <var>variable-to-shadow</var> from their respective
<var>var-structure</var>s should be shadowed with local variables, which
are more likely to be kept in registers for faster operation on them.
</p>
</dd>
<dt><code>(integrate (<var>client-procedure</var> <var>integrable-procedure</var>) &hellip;)</code></dt>
<dd><p>Forces <var>integrable-procedure</var> to be integrated in
<var>client-procedure</var>.
</p>
<p><strong>Note:</strong> The <code>integrate</code> command operates on the global
program, not on one particular module; each <var>client-procedure</var> and
<var>integrable-procedure</var> is chosen from all variables defined in the
entirety of the program, across all modules. It is advised that there
be only one of each.
</p>
</dd>
<dt><code>(header <var>header-line</var> &hellip;)</code></dt>
<dd><p>Each <var>header-line</var> is added to the top of the generated C file,
after a cpp inclusion of <code>&lt;stdio.h&gt;</code> and <code>&quot;prescheme.h&quot;</code>.
</p></dd>
</dl>
<p>The command arguments to <code>prescheme-compiler</code> are optional; they
are used only to optimize the compiled program at the programmer&rsquo;s
request.
</p></dd></dl>
<hr>
<a name="Example-Pre_002dScheme-compiler-usage"></a>
<div class="header">
<p>
Next: <a href="#Running-Pre_002dScheme-as-Scheme" accesskey="n" rel="next">Running Pre-Scheme as Scheme</a>, Previous: <a href="#Invoking-the-Pre_002dScheme-compiler" accesskey="p" rel="prev">Invoking the Pre-Scheme compiler</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Example-Pre_002dScheme-compiler-usage-1"></a>
<h3 class="section">1.6 Example Pre-Scheme compiler usage</h3>
<p>The <samp>ps-compiler/compile-vm.scm</samp>,
<samp>ps-compiler/compile-gc.scm</samp>, and
<samp>ps-compiler/compile-vm-no-gc.scm</samp> files give examples of running
the Pre-Scheme compiler. They are Scheme48 &lsquo;command programs&rsquo;, to be loaded into the <code>exec</code> package after
having already loaded the Pre-Scheme compiler. <samp>compile-vm.scm</samp> &amp;
<samp>compile-vm-no-gc.scm</samp> generate a new <samp>scheme48vm.c</samp> in the
<samp>scheme/vm/</samp> directory &mdash; <samp>compile-vm.scm</samp> includes the
garbage collector, while <samp>compile-vm-no-gc.scm</samp> does not
<a name="DOCF3" href="#FOOT3"><sup>3</sup></a> &mdash;, and <samp>compile-gc.scm</samp>
generates a new <samp>scheme48heap.c</samp>, <samp>scheme48read-image.c</samp>, &amp;
<samp>scheme48write-image.c</samp> in the <samp>scheme/vm/</samp> directory.
</p>
<p>Here is a somewhat simpler example. It assumes a pre-built image with
the Pre-Scheme compiler loaded is in the <samp>ps-compiler.image</samp> file
in the current directory (see <a href="#Invoking-the-Pre_002dScheme-compiler">Invoking the Pre-Scheme compiler</a>,
where there is a description of how to dump an image with the
Pre-Scheme compiler loaded).
</p>
<div class="example">
<pre class="example">% ls
hello.scm packages.scm ps-compiler.image
% cat hello.scm
(define (main argc argv)
(if (= argc 2)
(let ((out (current-output-port)))
(write-string &quot;Hello, world, &quot; out)
(write-string (vector-ref argv 1) out)
(write-char #\! out)
(newline out)
0)
(let ((out (current-error-port)))
(write-string &quot;Usage: &quot; out)
(write-string (vector-ref argv 0) out)
(write-string &quot; &lt;user&gt;&quot; out)
(newline out)
(write-string &quot; Greets the world &amp; &lt;user&gt;.&quot; out)
(newline out)
-1)))
% cat packages.scm
(define-structure hello (export main)
(open prescheme)
(files hello))
% scheme48 -i ps-compiler.image
heap size 3000000 is too small, using 4770088
Welcome to Scheme 48 1.3 (Pre-Scheme)
Copyright (c) 1993-2005 by Richard Kelsey and Jonathan Rees.
Please report bugs to scheme-48-bugs@s48.org.
Get more information at http://www.s48.org/.
Type ,? (comma question-mark) for help.
&gt; (prescheme-compiler 'hello '(&quot;packages.scm&quot;) 'hello-init &quot;hello.c&quot;)
packages.scm
hello.scmChecking types
main : ((integer **char) -&gt; integer)
In-lining single-use procedures
Call Graph:
&lt;procedure name&gt;
&lt;called non-tail-recursively&gt;
&lt;called tail-recursively&gt;
main (exported)
Merging forms
Translating
main
#{Unspecific}
&gt; ,exit
% cat hello.c
#include &lt;stdio.h&gt;
#include &quot;prescheme.h&quot;
long main(long, char**);
long main(long argc_0X, char **argv_1X)
{
FILE * out_3X;
FILE * out_2X;
{ if ((1 == argc_0X)) {
out_2X = stdout;
ps_write_string(&quot;Hello, world, &quot;, out_2X);
ps_write_string((*(argv_1X + 1)), out_2X);
{ long ignoreXX;
PS_WRITE_CHAR(33, out_2X, ignoreXX) }
{ long ignoreXX;
PS_WRITE_CHAR(10, out_2X, ignoreXX) }
return 0;}
else {
out_3X = stderr;
ps_write_string(&quot;Usage: &quot;, out_3X);
ps_write_string((*(argv_1X + 0)), out_3X);
ps_write_string(&quot; &lt;user&gt;&quot;, out_3X);
{ long ignoreXX;
PS_WRITE_CHAR(10, out_3X, ignoreXX) }
ps_write_string(&quot; Greets the world &amp; &lt;user&gt;.&quot;, out_3X);
{ long ignoreXX;
PS_WRITE_CHAR(10, out_3X, ignoreXX) }
return -1;}}
}
% </pre></div>
<hr>
<a name="Running-Pre_002dScheme-as-Scheme"></a>
<div class="header">
<p>
Previous: <a href="#Example-Pre_002dScheme-compiler-usage" accesskey="p" rel="prev">Example Pre-Scheme compiler usage</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> &nbsp; [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
</div>
<a name="Running-Pre_002dScheme-as-Scheme-1"></a>
<h3 class="section">1.7 Running Pre-Scheme as Scheme</h3>
<a name="index-prescheme-1"></a>
<a name="index-ps_002dmemory-1"></a>
<a name="index-ps_002dreceive-1"></a>
<a name="index-ps_002drecord_002dtypes-1"></a>
<a name="index-ps_002dflonums-1"></a>
<p>To facilitate the operation of Pre-Scheme systems within a high-level
Scheme development environment, Scheme48 simply defines the
<code>prescheme</code>, <code>ps-memory</code>, <code>ps-record-types</code>,
<code>ps-flonums</code>, and <code>ps-receive</code> structures in terms of Scheme;
Pre-Scheme structures can be loaded as regular Scheme structures
because of this. Those structures and the interfaces they implement
are defined in the files <samp>scheme/prescheme/interface.scm</samp> and
<samp>scheme/prescheme/package-defs.scm</samp> from the main Scheme48
distribution; simply load these files into the &lsquo;config package&rsquo; before loading any Pre-Scheme configuration
files.
</p>
<p>The Pre-Scheme emulation layer in Scheme has some shortcomings:
</p>
<ul>
<li> No more than sixteen megabytes can be allocated at once.
</li><li> More than thirty-two or sixty-four or so allocations result in
addresses overflowing bignums, which deallocations does not affect.
</li><li> Flonum memory access is unimplemented. (Flonum arithmetic works,
though.)
</li><li> The layer is very slow.
</li></ul>
<div class="footnote">
<hr>
<h4 class="footnotes-heading">Footnotes</h4>
<h3><a name="FOOT1" href="#DOCF1">(1)</a></h3>
<p>It
may be possible to use Pre-Scheme&rsquo;s C FFI to manually use <code>setjmp</code>
&amp; <code>longjmp</code>, but the author of this manual cannot attest to this
working.</p>
<h3><a name="FOOT2" href="#DOCF2">(2)</a></h3>
<p>Scheme48&rsquo;s VM does not use Pre-Scheme&rsquo;s built-in I/O
facilities to implement &lsquo;channels&rsquo; &mdash; it builds its
own lower-level facilities that are still OS-independent, but, because
they&rsquo;re written individually for different OSs, they integrate better
as low-level I/O channels with the OS. On Unix, the Scheme48 VM uses
file descriptors; Pre-Scheme&rsquo;s built-in I/O uses <code>stdio</code>.
Scheme48&rsquo;s VM uses Pre-Scheme&rsquo;s built-in I/O only to read heap images.</p>
<h3><a name="FOOT3" href="#DOCF3">(3)</a></h3>
<p>The actual distribution of Scheme48 separates the garbage
collector and the main virtual machine.</p>
</div>
<hr>
</body>
</html>