1422 lines
75 KiB
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 & 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 & 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> [<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 © 2004, 2005, 2006 Taylor Campbell.
|
|
All rights reserved.
|
|
</p>
|
|
<p>This manual includes material derived from works bearing the following
|
|
notice:
|
|
</p>
|
|
<p>Copyright © 1993–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 “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.
|
|
</p>
|
|
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><th colspan="3" align="left" valign="top"></th></tr><tr><td align="left" valign="top">• <a href="#Pre_002dScheme" accesskey="1">Pre-Scheme</a>:</td><td> </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> [<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’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’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">• <a href="#Differences-between-Pre_002dScheme-_0026-Scheme" accesskey="1">Differences between Pre-Scheme & Scheme</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Pre_002dScheme-type-specifiers" accesskey="2">Pre-Scheme type specifiers</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Standard-Pre_002dScheme-environment" accesskey="3">Standard Pre-Scheme environment</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#More-Pre_002dScheme-packages" accesskey="4">More Pre-Scheme packages</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Invoking-the-Pre_002dScheme-compiler" accesskey="5">Invoking the Pre-Scheme compiler</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Example-Pre_002dScheme-compiler-usage" accesskey="6">Example Pre-Scheme compiler usage</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Running-Pre_002dScheme-as-Scheme" accesskey="7">Running Pre-Scheme as Scheme</a>:</td><td> </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> [<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 & 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 & 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 &
|
|
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
|
|
— <i>e.g.</i>, those whose values are stored in the heap — 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 —
|
|
typically, just in local loops and top-level procedures that are not
|
|
exported from the package, but there are other heuristics —, but it
|
|
is not universal. Programmers may force tail call optimization with
|
|
Pre-Scheme’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 — often necessitating code bloat,
|
|
because the code of the tail-called procedure is integrated into the
|
|
caller’s driver loop —; 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’s <code>setjmp</code> & <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’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 & Scheme</a>, Up: <a href="#Pre_002dScheme" accesskey="u" rel="up">Pre-Scheme</a> [<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’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’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’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> & <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’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’s low-level memory manipulation primitives</a>;
|
|
see that section for more details.
|
|
</p></dd>
|
|
</dl>
|
|
|
|
</dd>
|
|
<dt><code>(=> (<var>argument-type</var> …) <var>return-type</var> …)</code></dt>
|
|
<dd><p>The types of procedures, known as ‘arrow’ 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 — <i>i.e.</i> operations such as
|
|
<code>vector-ref</code> —; 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> …)</code></dt>
|
|
<dd><p>Multiple value types, internally used for argument & 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> [<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">• <a href="#Scheme-bindings-in-Pre_002dScheme" accesskey="1">Scheme bindings in Pre-Scheme</a>:</td><td> </td><td align="left" valign="top">Bindings from R5RS
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Tail-call-optimization-in-Pre_002dScheme" accesskey="2">Tail call optimization in Pre-Scheme</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Pre_002dScheme-bitwise-manipulation" accesskey="3">Pre-Scheme bitwise manipulation</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Compound-Pre_002dScheme-data-manipulation" accesskey="4">Compound Pre-Scheme data manipulation</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Pre_002dScheme-error-handling" accesskey="5">Pre-Scheme error handling</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Input-_0026-output-in-Pre_002dScheme" accesskey="6">Input & output in Pre-Scheme</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Pre_002dScheme-access-to-C-functions-and-macros" accesskey="7">Pre-Scheme access to C functions and macros</a>:</td><td> </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> [<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) …) body</em></dt>
|
|
<dt><a name="index-let_002a"></a>syntax: <strong>let*</strong> <em>((name expression) …) body</em></dt>
|
|
<dt><a name="index-and"></a>syntax: <strong>and</strong> <em>conjunct …</em></dt>
|
|
<dt><a name="index-or"></a>syntax: <strong>or</strong> <em>disjunct …</em></dt>
|
|
<dt><a name="index-cond"></a>syntax: <strong>cond</strong> <em>cond-clause …</em></dt>
|
|
<dt><a name="index-do"></a>syntax: <strong>do</strong> <em>((name init-exp [step-exp]) …) (test-exp [return-exp]) body</em></dt>
|
|
<dd><p>These special forms & 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) …) body</em></dt>
|
|
<dt><a name="index-letrec_002dsyntax"></a>syntax: <strong>letrec-syntax</strong> <em>((name transformer-expression) …) body</em></dt>
|
|
<dd><p>Pre-Scheme’s macro facility is exactly the same as Scheme48’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 ‘Explicit renaming macros’.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt><a name="index-not"></a>procedure: <strong>not</strong> <em>boolean --> 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<?</strong> <em>char<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-values"></a>procedure: <strong>values</strong> <em>value … --> values</em></dt>
|
|
<dt><a name="index-call_002dwith_002dvalues"></a>procedure: <strong>call-with-values</strong> <em>producer consumer --> values</em></dt>
|
|
<dt><a name="index-current_002dinput_002dport"></a>procedure: <strong>current-input-port</strong> <em>--> input-port</em></dt>
|
|
<dt><a name="index-current_002doutput_002dport"></a>procedure: <strong>current-output-port</strong> <em>--> 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 … --> integer</em></dt>
|
|
<dt><a name="index-_002d"></a>procedure: <strong>-</strong> <em>integer --> integer</em></dt>
|
|
<dt><a name="index-_002d-1"></a>procedure: <strong>-</strong> <em>minuend subtrahend --> integer</em></dt>
|
|
<dt><a name="index-_002a"></a>procedure: <strong>*</strong> <em>multiplicand … --> 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><</strong> <em>integer<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-_003e"></a>procedure: <strong>></strong> <em>integer<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-_003c_003d"></a>procedure: <strong><=</strong> <em>integer<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-_003e_003d"></a>procedure: <strong>>=</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 --> integer</em></dt>
|
|
<dt><a name="index-quotient"></a>procedure: <strong>quotient</strong> <em>divisor dividend --> integer</em></dt>
|
|
<dt><a name="index-remainder"></a>procedure: <strong>remainder</strong> <em>divisor dividend --> integer</em></dt>
|
|
<dt><a name="index-expt"></a>procedure: <strong>expt</strong> <em>base exponent --> 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> [<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 …</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’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> [<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 --> 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 --> integer</em></dt>
|
|
<dt><a name="index-arithmetic_002dshift_002dright"></a>procedure: <strong>arithmetic-shift-right</strong> <em>integer count --> integer</em></dt>
|
|
<dt><a name="index-logical_002dshift_002dright"></a>procedure: <strong>logical-shift-right</strong> <em>integer count --> 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> [<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 & 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 --> vector</em></dt>
|
|
<dt><a name="index-vector_002dlength"></a>procedure: <strong>vector-length</strong> <em>vector --> integer</em></dt>
|
|
<dt><a name="index-vector_002dref"></a>procedure: <strong>vector-ref</strong> <em>vector index --> value</em></dt>
|
|
<dt><a name="index-vector_002dset_0021"></a>procedure: <strong>vector-set!</strong> <em>vector index value --> 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 --> string</em></dt>
|
|
<dt><a name="index-string_002dlength"></a>procedure: <strong>string-length</strong> <em>string --> integer</em></dt>
|
|
<dt><a name="index-string_002dref"></a>procedure: <strong>string-ref</strong> <em>string index --> char</em></dt>
|
|
<dt><a name="index-string_002dset_0021"></a>procedure: <strong>string-set!</strong> <em>string index char --> 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 --> 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’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>--> null-pointer</em></dt>
|
|
<dt><a name="index-null_002dpointer_003f"></a>procedure: <strong>null-pointer?</strong> <em>pointer --> 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 & 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> [<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’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 --> 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 …</em></dt>
|
|
<dd><p>Signals a fatal error with the given message & related irritants and
|
|
halts the program. On Unix, the program’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> [<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 & output</h4>
|
|
|
|
<p>Pre-Scheme’s I/O facilities are somewhat different from Scheme’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’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> & <code>write-block</code>, for reading &
|
|
writing blocks of direct memory.)
|
|
</p>
|
|
<dl>
|
|
<dt><a name="index-open_002dinput_002dfile"></a>procedure: <strong>open-input-file</strong> <em>filename --> [port status]</em></dt>
|
|
<dt><a name="index-open_002doutput_002dfile"></a>procedure: <strong>open-output-file</strong> <em>filename --> [port status]</em></dt>
|
|
<dt><a name="index-close_002dinput_002dport"></a>procedure: <strong>close-input-port</strong> <em>input-port --> status</em></dt>
|
|
<dt><a name="index-close_002doutput_002dport"></a>procedure: <strong>close-output-port</strong> <em>output-port --> status</em></dt>
|
|
<dd><p><code>Open-input-file</code> & <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> & <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 --> [char eof? status]</em></dt>
|
|
<dt><a name="index-peek_002dchar"></a>procedure: <strong>peek-char</strong> <em>input-port --> [char eof? status]</em></dt>
|
|
<dt><a name="index-read_002dinteger"></a>procedure: <strong>read-integer</strong> <em>input-port --> [integer eof? status]</em></dt>
|
|
<dd><p><code>Read-char</code> reads & 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 --> status</em></dt>
|
|
<dt><a name="index-newline"></a>procedure: <strong>newline</strong> <em>output-port --> status</em></dt>
|
|
<dt><a name="index-write_002dstring"></a>procedure: <strong>write-string</strong> <em>string output-port --> status</em></dt>
|
|
<dt><a name="index-write_002dinteger"></a>procedure: <strong>write-integer</strong> <em>integer output-port --> 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 --> 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 & output in Pre-Scheme</a>, Up: <a href="#Standard-Pre_002dScheme-environment" accesskey="u" rel="up">Standard Pre-Scheme environment</a> [<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 --> procedure</em></dt>
|
|
<dd><p>Special form for accessing C functions & 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> [<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">• <a href="#Pre_002dScheme-floating-point-operation" accesskey="1">Pre-Scheme floating point operation</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Pre_002dScheme-record-types" accesskey="2">Pre-Scheme record types</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Multiple-return-values-in-Pre_002dScheme" accesskey="3">Multiple return values in Pre-Scheme</a>:</td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="#Low_002dlevel-Pre_002dScheme-memory-manipulation" accesskey="4">Low-level Pre-Scheme memory manipulation</a>:</td><td> </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> [<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’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</code> structure.
|
|
</p>
|
|
<dl>
|
|
<dt><a name="index-fl_002b"></a>procedure: <strong>fl+</strong> <em>augend addend … --> float</em></dt>
|
|
<dt><a name="index-fl_002d"></a>procedure: <strong>fl-</strong> <em>float --> float</em></dt>
|
|
<dt><a name="index-fl_002d-1"></a>procedure: <strong>fl-</strong> <em>minuend subtrahend --> float</em></dt>
|
|
<dt><a name="index-fl_002a"></a>procedure: <strong>fl*</strong> <em>multiplier multiplicand … --> float</em></dt>
|
|
<dt><a name="index-fl_002f"></a>procedure: <strong>fl/</strong> <em>divisor dividend --> 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<</strong> <em>float<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-fl_003e"></a>procedure: <strong>fl></strong> <em>float<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-fl_003c_003d"></a>procedure: <strong>fl<=</strong> <em>float<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-fl_003e_003d"></a>procedure: <strong>fl>=</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> [<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> …)
|
|
(<var>field-tag<1></var> <var>field-type-spec<1></var>
|
|
<var>field-accessor<1></var> [<var>field-modifier<1></var>])
|
|
(<var>field-tag<2></var> <var>field-type-spec<2></var>
|
|
<var>field-accessor<2></var> [<var>field-modifier<2></var>])
|
|
…
|
|
(<var>field-tag<n></var> <var>field-type-spec<n></var>
|
|
<var>field-accessor<n></var> [<var>field-modifier<n></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> … 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<i></var> specified,
|
|
</p>
|
|
<ul>
|
|
<li> <var>field<i></var> is specified to have the type
|
|
<var>field-type-spec<i></var>;
|
|
|
|
</li><li> <var>field-accessor<i></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<i></var> of that record — its type is defined to
|
|
be <code>(=> (<var>type-name</var>) <var>field-type-spec<i></var>)</code>; and
|
|
|
|
</li><li> if present, <var>field-modifier<i></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<i></var> in its first argument to be the value of its
|
|
second argument; its type is <code>(=> (<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> [<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>)
|
|
≡
|
|
(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> [<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. ‘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</code> structure exports these
|
|
direct memory manipulation primitives.
|
|
</p>
|
|
<dl>
|
|
<dt><a name="index-allocate_002dmemory"></a>procedure: <strong>allocate-memory</strong> <em>size --> address</em></dt>
|
|
<dt><a name="index-deallocate_002dmemory"></a>procedure: <strong>deallocate-memory</strong> <em>address --> 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 --> unsigned-byte</em></dt>
|
|
<dt><a name="index-unsigned_002dbyte_002dset_0021"></a>procedure: <strong>unsigned-byte-set!</strong> <em>address unsigned-byte --> unit</em></dt>
|
|
<dt><a name="index-word_002dref"></a>procedure: <strong>word-ref</strong> <em>address --> word</em></dt>
|
|
<dt><a name="index-word_002dset_0021"></a>procedure: <strong>word-set!</strong> <em>address word --> unit</em></dt>
|
|
<dt><a name="index-flonum_002dref"></a>procedure: <strong>flonum-ref</strong> <em>address --> float</em></dt>
|
|
<dt><a name="index-flonum_002dset_0021"></a>procedure: <strong>flonum-set!</strong> <em>address float --> unit</em></dt>
|
|
<dd><p>Procedures for reading from & storing to memory.
|
|
<code>Unsigned-byte-ref</code> & <code>unsigned-byte-set!</code> access & store the
|
|
first unsigned byte at <var>address</var>. <code>Word-ref</code> &
|
|
<code>word-set!</code> access & store the first word — Pre-Scheme integer
|
|
— beginning at <var>address</var>. <code>Flonum-ref</code> & <code>flonum-set!</code>
|
|
access & store 64-bit floats beginning at <var>address</var>..
|
|
</p>
|
|
<p><strong>Bug:</strong> <code>Flonum-ref</code> & <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 --> 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>--> 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 --> 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 --> address</em></dt>
|
|
<dt><a name="index-address_002d"></a>procedure: <strong>address-</strong> <em>address decrement --> 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<a></var> and <var>address<b></var>.
|
|
For any <var>address<p></var> & <var>address<q></var>, <code>(address+
|
|
<var>address<p></var> (address-difference <var>address<p></var>
|
|
<var>address<q></var>))</code> is equal to <var>address<q></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<</strong> <em>address<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-address_003e"></a>procedure: <strong>address></strong> <em>address<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-address_003c_003d"></a>procedure: <strong>address<=</strong> <em>address<i><sub>a</sub></i></em></dt>
|
|
<dt><a name="index-address_003e_003d"></a>procedure: <strong>address>=</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->address</strong> <em>integer --> address</em></dt>
|
|
<dt><a name="index-address_002d_003einteger"></a>procedure: <strong>address->integer</strong> <em>address --> integer</em></dt>
|
|
<dd><p>Integers and addresses, although not the same type, may be converted to
|
|
and from each other; <code>integer->address</code> & <code>address->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 --> 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’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<a></var> & <var>address<b></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->string</strong> <em>address size --> string</em></dt>
|
|
<dt><a name="index-char_002dpointer_002d_003enul_002dterminated_002dstring"></a>procedure: <strong>char-pointer->nul-terminated-string</strong> <em>address --> string</em></dt>
|
|
<dd><p><code>Char-pointer->string</code> returns a string with <var>size</var> bytes from
|
|
the contiguous sequence of bytes starting at <var>address</var>.
|
|
<code>Char-pointer->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 --> [count-read eof? status]</em></dt>
|
|
<dt><a name="index-write_002dblock"></a>procedure: <strong>write-block</strong> <em>port address count --> 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> [<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’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 ‘command
|
|
program’, 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’s main
|
|
distribution, into the <code>exec</code> package, after having loaded
|
|
<samp>../scheme/prescheme/interface.scm</samp> &
|
|
<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 ‘Image-building
|
|
commands’.
|
|
</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’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 "(Pre-Scheme)"</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 …</em></dt>
|
|
<dd><p>Invokes the Pre-Scheme compiler. <var>Config-filenames</var> contain module
|
|
descriptions (see ‘Module system’) 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’ <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>) …)</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 & duplicated.
|
|
</p>
|
|
</dd>
|
|
<dt><code>(no-copy (<var>structure</var> <var>uncopyable-procedure</var>) …)</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>) …) …)</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>) …)</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> …)</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><stdio.h></code> and <code>"prescheme.h"</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’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> [<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 ‘command programs’, to be loaded into the <code>exec</code> package after
|
|
having already loaded the Pre-Scheme compiler. <samp>compile-vm.scm</samp> &
|
|
<samp>compile-vm-no-gc.scm</samp> generate a new <samp>scheme48vm.c</samp> in the
|
|
<samp>scheme/vm/</samp> directory — <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> —, and <samp>compile-gc.scm</samp>
|
|
generates a new <samp>scheme48heap.c</samp>, <samp>scheme48read-image.c</samp>, &
|
|
<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 "Hello, world, " out)
|
|
(write-string (vector-ref argv 1) out)
|
|
(write-char #\! out)
|
|
(newline out)
|
|
0)
|
|
(let ((out (current-error-port)))
|
|
(write-string "Usage: " out)
|
|
(write-string (vector-ref argv 0) out)
|
|
(write-string " <user>" out)
|
|
(newline out)
|
|
(write-string " Greets the world & <user>." 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.
|
|
> (prescheme-compiler 'hello '("packages.scm") 'hello-init "hello.c")
|
|
packages.scm
|
|
hello.scmChecking types
|
|
main : ((integer **char) -> integer)
|
|
In-lining single-use procedures
|
|
Call Graph:
|
|
<procedure name>
|
|
<called non-tail-recursively>
|
|
<called tail-recursively>
|
|
main (exported)
|
|
Merging forms
|
|
Translating
|
|
main
|
|
#{Unspecific}
|
|
> ,exit
|
|
% cat hello.c
|
|
#include <stdio.h>
|
|
#include "prescheme.h"
|
|
|
|
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("Hello, world, ", 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("Usage: ", out_3X);
|
|
ps_write_string((*(argv_1X + 0)), out_3X);
|
|
ps_write_string(" <user>", out_3X);
|
|
{ long ignoreXX;
|
|
PS_WRITE_CHAR(10, out_3X, ignoreXX) }
|
|
ps_write_string(" Greets the world & <user>.", 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> [<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 ‘config package’ 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’s C FFI to manually use <code>setjmp</code>
|
|
& <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’s VM does not use Pre-Scheme’s built-in I/O
|
|
facilities to implement ‘channels’ — it builds its
|
|
own lower-level facilities that are still OS-independent, but, because
|
|
they’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’s built-in I/O uses <code>stdio</code>.
|
|
Scheme48’s VM uses Pre-Scheme’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>
|