Compare commits
No commits in common. "c06680375dcd4ecf9b3cdb18a9ac736a588c651c" and "cf147ff334968bcb17684d684b638db7b696529c" have entirely different histories.
c06680375d
...
cf147ff334
|
@ -1,27 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="css.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table class="doctable" border="0" cellspacing="0" summary=
|
|
||||||
"this table is just for layout">
|
|
||||||
<tr class="toprow"><td class=maintitle>the vx-scheme compiler
|
|
||||||
<p align="right">[ <a href="download.html">Download</a> ]</p>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td class=body>
|
|
||||||
|
|
||||||
<p><img align="right" src="benchmark.png"> This was interesting for
|
|
||||||
me: it's some benchmark data collected over all versions of this
|
|
||||||
program starting from version 0.4 and up to the compiler in version
|
|
||||||
0.7. Most of the effort in tuning the program has paid off. The
|
|
||||||
compilation occasionally loses vs. interpretation in very short
|
|
||||||
programs or those that don't loop much (you can see this effect
|
|
||||||
in <code>dynamic</code> and <code>dderiv</code>. </p>
|
|
||||||
<p>Otherwise, in die-hard computational scenarios
|
|
||||||
like <code>ack</code> and <code>puzzle</code>, the compiler is seen at
|
|
||||||
its best.</p>
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,62 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="css.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table class="doctable" border="0" cellspacing="0" summary=
|
|
||||||
"this table is just for layout">
|
|
||||||
<tr class="toprow"><td class=maintitle>the vx-scheme compiler
|
|
||||||
<p align="right">[ <a href="download.html">Download</a> ]</p>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td class=body>
|
|
||||||
|
|
||||||
<p><img align="right" src="compiler.png"> When I first started out to
|
|
||||||
write the compiler I was only interested in doing it for its own sake,
|
|
||||||
to get the system running as fast as possible. Naturally, getting the
|
|
||||||
compiler going to the point where it would work for the complete
|
|
||||||
language was more work than I bargained for, and presented some
|
|
||||||
head-scratching puzzles too. For one thing, there was no way for the
|
|
||||||
interpreter, for example, to invoke a compiled procedure safely: doing
|
|
||||||
so would split the current continuation between the interpreter's data
|
|
||||||
structures and the virtual machine in a way that would be pretty
|
|
||||||
difficult to reassemble in such a way as to
|
|
||||||
permit <code>call-with-current-continuation</code>.</p>
|
|
||||||
<p>That being the case, I was forced to complete the VM implementation
|
|
||||||
to the bitter end. But that opened the possibility of detaching the
|
|
||||||
interpreter in steps, leaving behind a system with the interpreter
|
|
||||||
shorn away and no scheme source to read in order to initialize. To do
|
|
||||||
this the bytecode had to be serialized in a form that could be
|
|
||||||
executed without any help from the interpreter. The compiler emits
|
|
||||||
code in the form of scheme vectors containing ordinary integer
|
|
||||||
opcodes; the VM code contains a
|
|
||||||
routine <code>write-compiled-procedure</code> that tranforms this
|
|
||||||
representation into a static C data structure.
|
|
||||||
<p><code>bootstrap.scm</code>, which runs in a special version of the
|
|
||||||
interpreter is linked with a dormant copy of the VM code (to gain
|
|
||||||
access to <code>write-compiled-procedure</code>), sequences the
|
|
||||||
compilation of the compiler Scheme source and a small library of
|
|
||||||
support routines to a C file, <code>_compiler.cpp</code>. At this
|
|
||||||
point, that file can be compiled and linked with the VM, and now you
|
|
||||||
have a Scheme REPL with no interpreter in sight.</p>
|
|
||||||
<p>For compute-bound tasks, compiled code is more or less twice as
|
|
||||||
fast as the interpreter. For very small programs, or programs that
|
|
||||||
don't loop much, the effort of compiling can outweigh the
|
|
||||||
benefit. (See examples of both behaviors on
|
|
||||||
the <a href="benchmark.html">benchmark page</a>.
|
|
||||||
<p>Note that the trick of loading only the compiler and REPL with the
|
|
||||||
VM can be repeated with any Scheme
|
|
||||||
source. <code>scheme-compiler</code> is essentially a precompiled
|
|
||||||
helper to do this: it will transform Scheme code into the C
|
|
||||||
representation of bytecode in one step. Link this with the VM, and
|
|
||||||
now you have compiled scheme code running without either the
|
|
||||||
interpreter or the compiler!</p>
|
|
||||||
<p>To see this in action, just type <code>make pi</code>. This will
|
|
||||||
take <code>pi.scm</code> from the testcases directory all the way
|
|
||||||
through this process.</p>
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
27
www/css.css
27
www/css.css
|
@ -1,27 +0,0 @@
|
||||||
H4 H3 H2 H1 { font-family: verdana, arial, helvetica; }
|
|
||||||
BLOCKQUOTE { width: 400px; }
|
|
||||||
P.item { width: 450px; margin: 0pt 0pt 10pt 0pt; }
|
|
||||||
P.section { color: #669980; font-style: italic; font-weight: bold;}
|
|
||||||
P.quiet { color: #cccccc; }
|
|
||||||
BODY { font-family: verdana, arial, helvetica;
|
|
||||||
font-size: 10pt; margin: 0pt; background:#ffffff;}
|
|
||||||
TABLE.doctable { }
|
|
||||||
TD { font-family: verdana, arial, helvetica;
|
|
||||||
font-size: 10pt; }
|
|
||||||
TD.leftcol { background: #996680; width: 100px; }
|
|
||||||
TD.maintitle { background: #669980; color: #ddffdd;
|
|
||||||
text-align: right; padding: 2px 5px 2px 5px; }
|
|
||||||
TD.leftedge { background: #999966; width: 100px; }
|
|
||||||
TD.body { padding: 5px 10px 5px 5px; }
|
|
||||||
TD.announce { background: #ffffcc; }
|
|
||||||
TR.toprow { height: 100; }
|
|
||||||
|
|
||||||
CODE { font-family: courier, courier new; color:#000088; }
|
|
||||||
FONT.output { font-family: courier, courier new; color:#AA0000; }
|
|
||||||
TABLE.db { background: #999999; }
|
|
||||||
A:link { text-decoration: none;
|
|
||||||
color: #cc0000; }
|
|
||||||
A:visited { text-decoration: none;
|
|
||||||
color: #880000; }
|
|
||||||
A:hover { text-decoration: underline;
|
|
||||||
color: #ff0000; }
|
|
|
@ -1,281 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta name="generator" content=
|
|
||||||
"HTML Tidy for FreeBSD (vers 1st March 2002), see www.w3.org">
|
|
||||||
<title>Vx-Scheme Download Page</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="css.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table class="doctable" border="0" cellspacing="0" summary=
|
|
||||||
"this table is just for layout">
|
|
||||||
<tr class="toprow">
|
|
||||||
<td class="leftcol"></td>
|
|
||||||
<td class="maintitle">
|
|
||||||
<h2>vx-scheme</h2>
|
|
||||||
|
|
||||||
<h4>A Scheme interpreter for VxWorks.</h4>
|
|
||||||
|
|
||||||
<p align="right">[ <a href="index.html">Home</a> ]</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="leftedge"></td> <td class="body">
|
|
||||||
|
|
||||||
<h3>Release History</h3>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table><tr><td class="announce">Announcing the fifth public release,
|
|
||||||
<b>0.7</b>. The long-awaited (by me, anyway) bytecode compiler is
|
|
||||||
here, with some cool featurs described on
|
|
||||||
the <a href="compiler.html">compiler page</a>. The compiler is
|
|
||||||
written in Scheme and bootstraps itself using the interpreter. By the
|
|
||||||
way, the 0.7 interpreter is faster too, as you can see on
|
|
||||||
the <a href="benchmark.html">benchmark page</a>. Other enhancements:
|
|
||||||
<ul>
|
|
||||||
<li><b><font color="#cc0000">14% faster</font> interpreter and
|
|
||||||
<font color="#cc0000">47% faster</font> compiler:</b> The interpreter
|
|
||||||
got faster due to just general tuning. The compiler helps a great
|
|
||||||
deal for computationally-bound programs.</li>
|
|
||||||
|
|
||||||
<li><b>New functions:</b> By analogy with Common LISP, <code>bound?</code>,
|
|
||||||
<code>nconc</code> and <code>symbol-value</code>. For utility purposes,
|
|
||||||
<code>getcwd</code>, <code>chdir</code>, <code>display*</code> (which
|
|
||||||
displays each of its arguments in turn,
|
|
||||||
and <code>primitive-procedure?</code> (for recognizing procedures
|
|
||||||
produced by compilation).</li>
|
|
||||||
<li><b>Hosted by Google!</b> I was maintaining the project with CVS,
|
|
||||||
but decided to try my current employer's new
|
|
||||||
<a href="http://code.google.com/hosting/"code hosting</a>ne facility,
|
|
||||||
based on <a href="http://subversion.tigris.org/">Subversion</a>.
|
|
||||||
Click for the <a href="http://code.google.com/p/vx-scheme/">vx-scheme
|
|
||||||
project page</a>. You can get my current working source from the
|
|
||||||
trunk or work with version 0.7, which as been tagged as
|
|
||||||
<a href="http://vx-scheme.googlecode.com/svn/tags/v0.7/">v0.7</a>.
|
|
||||||
<li><b>Compatibility?</b> I can't really say that this version runs
|
|
||||||
with VxWorks since I haven't tried
|
|
||||||
it. <a href="http://www.windriver.com/">Wind River</a>, my former
|
|
||||||
employer, used to have a Tornado Prototyper you could download to
|
|
||||||
experiment with things like this, but they haven't done that in a
|
|
||||||
while. Likewise, I don't have any Win32 machines in the house any
|
|
||||||
more, having switched to Mac. The code does run fine on Mac OS X,
|
|
||||||
Fedora, and Ubuntu.</li>
|
|
||||||
</ul>
|
|
||||||
Consult the change log for more information.
|
|
||||||
</td></tr></table>
|
|
||||||
<p><p>
|
|
||||||
<table><tr><td class="announce">Announcing the fourth public release,
|
|
||||||
<b>0.6</b>. Improvements from 0.5 involve some performance enhancements
|
|
||||||
achieved by tweaking the VM.
|
|
||||||
<ul>
|
|
||||||
<li><b><font color="#cc0000">39% faster</font>:</b> This release was
|
|
||||||
motivated by noticing that the test suite was spending most of its
|
|
||||||
time collecting garbage. Obviously, reducing garbage generation and
|
|
||||||
simplifying garbage collection would improve performance, and that was
|
|
||||||
done in this release, with the following two (internal) changes: </li>
|
|
||||||
|
|
||||||
<li><b>Win32 port:</b> Project files are provided so vx-scheme can
|
|
||||||
compile ith Visual Studio .NET.</li>
|
|
||||||
|
|
||||||
<li><b>Short Integers:</b> Internally, an integer that can fit in 24
|
|
||||||
bits is now stored as a special kind of pointer with no cell space
|
|
||||||
allocated. This means that computations with small integers can
|
|
||||||
proceed with much less garbage generated. (Many classic LISP systems
|
|
||||||
use this trick.) The short arithmetic automatically expands to 32
|
|
||||||
bits when necessary, preserving the full range of 32-bit arithmetic
|
|
||||||
with no programmer intervention needed. Still no arbitrary-precision
|
|
||||||
arithmetic, though.</li>
|
|
||||||
|
|
||||||
<li><b>Uniform cell-size:</b> Versions before this one had the
|
|
||||||
concept of single- and double-size cells. While this saved a
|
|
||||||
small amount of memory, it greatly complicated the garbage collector.</li>
|
|
||||||
</ul>
|
|
||||||
Consult the change log for more information.
|
|
||||||
</td></tr></table>
|
|
||||||
<p><p>
|
|
||||||
<table><tr><td class="announce">Changes from <b>0.4</b> to <b>0.5</b>:
|
|
||||||
<ul> <li><b>Property
|
|
||||||
lists:</b> You can now say <code>(put 'symbol 'key value)</code> to
|
|
||||||
make a property association "key->value" on the given symbol, and
|
|
||||||
<code>(get 'symbol 'key)</code> to retrieve the value. (NB: getting
|
|
||||||
a property that doesn't exist will return <code>#f</code>, rather
|
|
||||||
than <code>()</code> as in Common Lisp.)</li>
|
|
||||||
|
|
||||||
<li><b>Perl-style vector operations:</b> New functions
|
|
||||||
<code>vector-shift!, vector-unshift!, vector-push!,</code> and
|
|
||||||
<code>vector-pop!</code> are provided. Shift and unshift work at the
|
|
||||||
left side of a vector, push and pop at the right. Vectors will
|
|
||||||
grow and shrink as needed.</li>
|
|
||||||
|
|
||||||
<li><b>More testcases:</b>Three new testcases, adding 500 more lines
|
|
||||||
to the suite.</li>
|
|
||||||
</ul>
|
|
||||||
</td></tr></table>
|
|
||||||
|
|
||||||
<p>I've started writing a <b>bytecode compiler</b>, which has been an
|
|
||||||
interesting exercise. If that interests you drop me a
|
|
||||||
<a href="mailto:colin.smith@gmail.com">note</a>!</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Download</h3>
|
|
||||||
|
|
||||||
The easy-to-build source distribution is available here:
|
|
||||||
<ul>
|
|
||||||
<li>Tar/gzip format: <code><a href=
|
|
||||||
"http://colin-smith.net/vx-scheme/vx-scheme-0.7.tgz">vx-scheme-0.7.tgz</a></code></li>
|
|
||||||
|
|
||||||
<li>Zip format: <code><a href=
|
|
||||||
"http://colin-smith.net/vx-scheme/vx-scheme-0.7.zip">vx-scheme-0.7.zip</a></code></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
Previous versions can be downloaded as well, but I don't recommend
|
|
||||||
them. Newer releases always pass a stronger test suite than older
|
|
||||||
ones. The previous releases are 0.6
|
|
||||||
[<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.6.tgz">tgz</a>,
|
|
||||||
<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.6.zip">zip</a>],
|
|
||||||
0.5
|
|
||||||
[<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.5.tgz">tgz</a>,
|
|
||||||
<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.5.zip">zip</a>],
|
|
||||||
0.4
|
|
||||||
[<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.4.tgz">tgz</a>,
|
|
||||||
<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.4.zip">zip</a>],
|
|
||||||
and 0.3 (the first release)
|
|
||||||
[<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.3.tgz">tgz</a>,
|
|
||||||
<a href="http://colin-smith.net/vx-scheme/vx-scheme-0.3.zip">zip</a>].
|
|
||||||
|
|
||||||
<p>You can contact me at <a href=
|
|
||||||
"mailto:colin.smith@gmail.com">colin.smith@gmail.com</a> with any
|
|
||||||
questions or observations. For all I know, I'm the only person out
|
|
||||||
there who's interested in Scheme and VxWorks simultaneously. If you
|
|
||||||
are too, drop me a note!</p>
|
|
||||||
|
|
||||||
<h3>Documentation</h3>
|
|
||||||
<p>See the <a href="index.html">main page</a>.</p>
|
|
||||||
|
|
||||||
<h3>A word about the coding convention</h3>
|
|
||||||
|
|
||||||
<p>This code uses the VxWorks coding convention, used extensively at
|
|
||||||
Wind River. The brace indenting is a bit unorthodox. At Wind, the
|
|
||||||
party line was always "they're nobody's favorite indenting rules, but
|
|
||||||
we all use them, and therein lies the value." True enough. Now that
|
|
||||||
I've left WR to work at
|
|
||||||
<a href="http://www.google.com/"><font color="#0000ff"><b>G</font><font color="#ff0000">o</font><font color="#cccc00">o</font><font color="#0000ff">g</font><font color="#009900">l</font><font color="#ff0000">e</font></a></b>,
|
|
||||||
I've been tempted to reformat the code in a more mainstream style,
|
|
||||||
though. Maybe next version.</p>
|
|
||||||
|
|
||||||
<h3>Installation Notes</h3>
|
|
||||||
|
|
||||||
<p class="section">For VxWorks:</p>
|
|
||||||
|
|
||||||
<p>Just unpack the archive anywhere you like. A Tornado workspace
|
|
||||||
containing two projects is provided in tornado/vx-scheme.wsp. The
|
|
||||||
first project, "target-shell", will build a VxSim executable that
|
|
||||||
has enough C++ features selected to host the Scheme interpreter.
|
|
||||||
The second is the interpreter itself. Build them both.</p>
|
|
||||||
|
|
||||||
<p><b>Note:</b> For the present, vx-scheme only runs on the target
|
|
||||||
shell: starting it from <code>windsh</code> will only confuse
|
|
||||||
things.</p>
|
|
||||||
|
|
||||||
<p>Start the simulator you just built. Once it's launched you can
|
|
||||||
use a script in ../startup that will load the Scheme image. (The
|
|
||||||
startup script is in the parent directory of the directory where
|
|
||||||
the sim starts in case you define new builds on your own.)</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code><font class="output">-></font> <../startup
|
|
||||||
<font class="output">cd "../../vx-scheme/SIMNTgnu"
|
|
||||||
value = 0 = 0x0
|
|
||||||
ld < vx-scheme.out
|
|
||||||
value = 30727944 = 0x1d4df08 = _dtors + 0x14
|
|
||||||
cd "../../../testcases"
|
|
||||||
value = 0 = 0x0
|
|
||||||
-></font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p class="section">For UNIX:</p>
|
|
||||||
|
|
||||||
<p>For UNIX-like systems (FreeBSD, Cygwin, etc.) there's an
|
|
||||||
ordinary Makefile in the <code>src</code> directory of the
|
|
||||||
distribution. Just say make or gmake (whatever it takes to launch
|
|
||||||
GNU make on your system) in that directory. This will build a
|
|
||||||
"vx-scheme" executable configured for use on your host system.</p>
|
|
||||||
|
|
||||||
<h3>Test Suite</h3>
|
|
||||||
|
|
||||||
<p class="section">For VxWorks:</p>
|
|
||||||
|
|
||||||
<p>To run the test suite on VxWorks, follow the installation steps
|
|
||||||
above and then, in your simulator window, do</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code><font class="output">-></font> scheme
|
|
||||||
<font class="output">=></font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>The prompt changes to <code>=></code> when reading Scheme
|
|
||||||
expressions. The startup script set the working directory to the
|
|
||||||
place where the test suite lies so now we need only say:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code><font class="output">=></font> (load "vx-test.scm")
|
|
||||||
<font class="output">PASS: sort
|
|
||||||
PASS: factor
|
|
||||||
PASS: object->string
|
|
||||||
PASS: r4rstest
|
|
||||||
PASS: pi
|
|
||||||
PASS: sieve
|
|
||||||
PASS: cf
|
|
||||||
PASS: series
|
|
||||||
PASS: ack
|
|
||||||
PASS: scheme
|
|
||||||
PASS: dynamic
|
|
||||||
PASS: earley
|
|
||||||
PASS: maze
|
|
||||||
PASS: dderiv
|
|
||||||
PASS: boyer
|
|
||||||
PASS: puzzle
|
|
||||||
</font>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p><b>Note:</b> Running the test suite defines a lot of symbols. In
|
|
||||||
particular, "i" is defined, which masks the VxWorks definition.
|
|
||||||
It's probably best to ^X the simulator and start over after running
|
|
||||||
the suite.</p>
|
|
||||||
|
|
||||||
<p class="section">For UNIX:</p>
|
|
||||||
|
|
||||||
<p>To run the test suite for UNIX: after building with make (or
|
|
||||||
gmake) in the unix directory, just do a <code>"make test"</code>.
|
|
||||||
|
|
||||||
<p><b>Note:</b> The "good" files are slightly different for
|
|
||||||
VxWorks: in that case, expected to fail the "mult-float-print-test"
|
|
||||||
on VxWorks and the "good" file contains these failures, so the
|
|
||||||
suite will "pass". But as explained elsewhere we just take what the
|
|
||||||
native I/O system gives us.</p>
|
|
||||||
|
|
||||||
<h3>Roadmap</h3>
|
|
||||||
|
|
||||||
<p>Now that the bytecode compiler (whose design is
|
|
||||||
indebted to that given by Peter Norvig in <a
|
|
||||||
href="http://www.norvig.com/paip.html">Paradigms of Artificial
|
|
||||||
Intelligence Programming</a>) is complete, I don't have any big plans.
|
|
||||||
Feel free to write if you're thinking of using this code for anything
|
|
||||||
at all!
|
|
||||||
|
|
||||||
<p class="quiet">Copyright © 2002 Colin Smith.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.0 KiB |
602
www/index.html
602
www/index.html
|
@ -1,602 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta name="generator" content=
|
|
||||||
"HTML Tidy for FreeBSD (vers 1st March 2002), see www.w3.org">
|
|
||||||
<title>Vx-Scheme</title>
|
|
||||||
<meta name="Author"
|
|
||||||
content="Colin Smith">
|
|
||||||
<meta name="description"
|
|
||||||
content="An implementation of Scheme for VxWorks.">
|
|
||||||
<meta name="keywords"
|
|
||||||
content="Scheme, Colin Smith, Google, Lisp, VxWorks, Real-Time">
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="css.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table class="doctable" border="0" cellspacing="0" summary=
|
|
||||||
"this table is just for layout.">
|
|
||||||
<tr class="toprow">
|
|
||||||
<td class="leftcol"></td>
|
|
||||||
<td class="maintitle">
|
|
||||||
<h2>vx-scheme</h2>
|
|
||||||
|
|
||||||
<h4>A Scheme interpreter for VxWorks.</h4>
|
|
||||||
|
|
||||||
<p align="right">[ <a href="download.html">Download</a> ]</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="leftedge"></td>
|
|
||||||
<td class="body">
|
|
||||||
<h3>Introduction</h3>
|
|
||||||
|
|
||||||
<p>Vx-scheme is a compact, fairly efficient implementation of the
|
|
||||||
Scheme programming language. It has some special features designed
|
|
||||||
to allow it to integrate with the VxWorks real-time operating
|
|
||||||
system shell. It is very nearly compliant to the <a href=
|
|
||||||
"http://sicp.ai.mit.edu/Fall-2002/manuals/r4rs/r4rs_toc.html">R4RS</a>
|
|
||||||
language standard: in particular, it supports continuations with
|
|
||||||
infinite lifetimes and all the procedures mentioned in the
|
|
||||||
specification, including the optional ones (such as
|
|
||||||
<code>force</code> and <code>delay</code>). It can be used under
|
|
||||||
the terms of the <a href="../LICENSE">Artistic License</a>.</p>
|
|
||||||
|
|
||||||
<p>[<a href="download.html">download</a>]</p>
|
|
||||||
|
|
||||||
<h3>Uses</h3> VX-scheme was briefly used in a humanoid robotics
|
|
||||||
project. See <a
|
|
||||||
href="http://mirriwinni.it.jcu.edu.au/~cgaskett/thewiki/RoboticsLearningAndVision">Chris
|
|
||||||
Gaskett's page</a> at James Cook University in Cairns, Australia.
|
|
||||||
|
|
||||||
<h3>History</h3>
|
|
||||||
|
|
||||||
<p>Scheme is sort of a hobby of mine, as I'm a fan of Abelson, Sussman
|
|
||||||
and Sussman's seminal text <a href=
|
|
||||||
"http://www-mitpress.mit.edu/sicp/">Structure and Interpretation of
|
|
||||||
Computer Programs</a> <b>[SICP]</b>. This implementation was born as I
|
|
||||||
tried to follow the Scheme implementation experiments in chapters <a
|
|
||||||
href=
|
|
||||||
"http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-25.html#%_chap_4">
|
|
||||||
4</a> and <a href=
|
|
||||||
"http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-30.html#%_chap_5">
|
|
||||||
5</a> of that book using C as the implementation language. Once that
|
|
||||||
was working well enough, I then undertook to implement the complete <a
|
|
||||||
href=
|
|
||||||
"http://sicp.ai.mit.edu/Fall-2002/manuals/r4rs/r4rs_toc.html">R4</a>
|
|
||||||
standard of the language, thinking it looked pretty easy! The R4
|
|
||||||
standard is a marvel of concision, but still conceals within it about
|
|
||||||
200 procedures and special forms. I also considered how the Scheme
|
|
||||||
language might be integrated with
|
|
||||||
<a href="http://www.bluedonkey.org/cgi-bin/twiki/bin/view/Books/VxWorksCookBook">VxWorks</a>, an RTOS made by my former employer,
|
|
||||||
<a href="http://www.windriver.com">Wind River</a> (today I work at
|
|
||||||
<a href="http://www.google.com/"><font color="#0000ff"><b>G</font><font color="#ff0000">o</font><font color="#cccc00">o</font><font color="#0000ff">g</font><font color="#009900">l</font><font color="#ff0000">e</font></a></b>).
|
|
||||||
That RTOS has a simple control shell based on C syntax, that's integrated
|
|
||||||
with the runtime symbol table. Could Scheme do that as well? I wanted
|
|
||||||
to find out.</p>
|
|
||||||
|
|
||||||
<h3>Design Goals</h3>
|
|
||||||
|
|
||||||
<p>First of all I wanted to learn the concepts in Scheme language
|
|
||||||
implementation first-hand, so that I could grow as a programmer. To
|
|
||||||
that end, I restrained myself from peeking at other implementations
|
|
||||||
of Scheme on the net "to see how it should be done." That
|
|
||||||
temptation was very hard to resist with <a href=
|
|
||||||
"http://www.swiss.ai.mit.edu/~jaffer/SCM.html">Aubrey Jaffer's
|
|
||||||
SCM</a>, which is considerably faster than my implementation and
|
|
||||||
almost as small. I did use SCM as a "reference implementation" to
|
|
||||||
find out the "right behavior" in a number of tricky circumstances,
|
|
||||||
and I made extensive use of his R4 test suite during the
|
|
||||||
project.</p>
|
|
||||||
|
|
||||||
<p>(My first version model had the special forms implemented as C
|
|
||||||
functions. But this made complete support of
|
|
||||||
<code>call-with-current-continuation</code> very difficult, as the
|
|
||||||
continuation, at any moment, was "shared" between the C and Scheme
|
|
||||||
stacks. This caused me to move to a strict register-machine model
|
|
||||||
as described in SICP ch. 5. This was a lot of work just to get one
|
|
||||||
procedure working right!)</p>
|
|
||||||
|
|
||||||
<p>VxWorks programmers prize compact implementations, and this was
|
|
||||||
perhaps the one constraint I adhered to most strongly. The entire
|
|
||||||
executable code is less than 64Kb of code/data on VxWorks and
|
|
||||||
FreeBSD. The system allocates an initial budget of only 10000 cons
|
|
||||||
cells, and garbage collects when that budget is exhausted
|
|
||||||
(interestingly, most of my benchmarks can actually survive on that
|
|
||||||
small ration!) Whenever the code bloated over 64Kb, I would stop
|
|
||||||
work and wring out the fat. (While the interpreter is written in
|
|
||||||
C++ for notational convenience's sake, my tight size budget forbade
|
|
||||||
the use of STL classes, or indeed any sort of template. The program
|
|
||||||
uses a rather strict subset of C++'s features). Not having STL at
|
|
||||||
hand meant I had to implement an efficient symbol store for the
|
|
||||||
program (I like Knuth's implementation of AVL for jobs like this. A
|
|
||||||
hash table might have been better, but AVL never runs out of gas.
|
|
||||||
Knuth's implementation, which eschews recursion, is just about as
|
|
||||||
fast as a balanced tree can get, IMO.)</p>
|
|
||||||
|
|
||||||
<blockquote><p><b>Note:</b>While version 0.4 was 64144 bytes (text +
|
|
||||||
data + bss) when compiled for VxSim on Tornado 2.2, later versions
|
|
||||||
(and versions for other operatings systems) are not quite that svelte.
|
|
||||||
The current size on Linux is 85.6K.</p></blockquote>
|
|
||||||
|
|
||||||
|
|
||||||
<p>I also didn't want any time-consuming implementation shortcuts.
|
|
||||||
Each and every procedure mentioned in the <a href=
|
|
||||||
"http://sicp.ai.mit.edu/Fall-2002/manuals/r4rs/r4rs_toc.html">R4</a>
|
|
||||||
spec has its own natural, efficient C implementation. (For example,
|
|
||||||
we don't ever do syntactic transformation, e.g., transforming
|
|
||||||
<code>let*</code> into nested <code>let</code>s or
|
|
||||||
<code>cond</code>s into nested <code>if</code>s, etc.)</p>
|
|
||||||
|
|
||||||
<p>That said, it's still an interpreter, and doesn't attempt any
|
|
||||||
compilation (or even the kinds of syntactic transformation that
|
|
||||||
could save time rather than lose it). The "register machine" at the
|
|
||||||
heart of the evaluator is a fairly faithful implementation of the
|
|
||||||
design given in SICP.</p>
|
|
||||||
|
|
||||||
<h3>VxWorks Shell Integration</h3>
|
|
||||||
|
|
||||||
<p>In the VxWorks "C" shell, you can work with integer variables
|
|
||||||
and call functions with a mix of integer and string parameters.
|
|
||||||
VxScheme can do these things too. In the event that a symbol has no
|
|
||||||
value in any of the current execution context's enclosing
|
|
||||||
environments, vx-scheme will "fall through" to the VxWorks symbol
|
|
||||||
table. If it finds a data symbol, it returns the current value of
|
|
||||||
the variable as the value of the expression. If it finds a text
|
|
||||||
symbol, vx-scheme constructs a procedure that will marshal its
|
|
||||||
arguments into integer form and invoke the underlying function.
|
|
||||||
It's meant to seem simple on the user side:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> i
|
|
||||||
<font class="output">#<lambda args ...></font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>...of course, in Scheme syntax, the expression " i "
|
|
||||||
<i>would</i> have the value of a procedure object, right? To
|
|
||||||
actally call the procedure, we surround it with parens as usual
|
|
||||||
(yes, this takes getting used to).</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> (i)
|
|
||||||
|
|
||||||
<font class=
|
|
||||||
"output">NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
|
|
||||||
---------- ------------ -------- --- ---------- -------- -------- ------- -----
|
|
||||||
tExcTask _excTask 1d38d10 0 PEND 43a2d0 1d38c10 0 0
|
|
||||||
tLogTask _logTask 1d331e0 0 PEND 43a2d0 1d330e0 0 0
|
|
||||||
tShell _shell 1d28c68 1 READY 470d6c 1d27e74 1c0001 0
|
|
||||||
tWdbTask _wdbTask 1d2e028 3 PEND 43a2d0 1d2decc 0 0</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>VxWorks variables shine right through:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> vxTicks
|
|
||||||
<font class="output">42354</font>
|
|
||||||
=> (/ vxTicks (sysClkRateGet))
|
|
||||||
<font class="output">714.39999999999998</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>Vx-scheme converts string arguments by passing the address to
|
|
||||||
the underlying C function (just as the standard target shell would
|
|
||||||
do). This has the interesting side effect of letting us use
|
|
||||||
<code>printf</code> from Scheme: and a very useful addition to the
|
|
||||||
language it is! (if not in the proper spirit).</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> (define buf (malloc 0x100))
|
|
||||||
=> (sprintf buf "str=%s int=%d\n" "hello" 99)
|
|
||||||
<font class="output">17</font>
|
|
||||||
=> (printf "buf:%s\n" buf)
|
|
||||||
<font class="output">buf:str=hello int=99
|
|
||||||
|
|
||||||
22</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>Of course one thing we get out of this whole exercise is looping
|
|
||||||
and conditionals for the VxWorks shell, things it doesn't have under
|
|
||||||
its current C-expression syntax. Scheme also does a pretty good job of
|
|
||||||
working with files. A good example of these things is the code for the
|
|
||||||
<a href="../testcases/vx-test.scm">test suite driver</a>. Here's
|
|
||||||
another where we spawn a handful of tasks with different delays.</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> (for-each (lambda (d) (sp 'taskDelay d)) '(1000 2000 3000))
|
|
||||||
<font class="output">task spawned: id = 0x1cefaf0, name = t1
|
|
||||||
task spawned: id = 0x1ce7978, name = t2
|
|
||||||
task spawned: id = 0x1cdf800, name = t3</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>That quote-mark in front of taskDelay is to prevent the
|
|
||||||
evaluator from substituting a lambda value in place of the
|
|
||||||
variable. We don't want that this time; instead we want the address
|
|
||||||
of taskDelay to be passed to the 'sp' function! The quote allows
|
|
||||||
these two cases to be treated correctly (all in the same
|
|
||||||
S-expression).</p>
|
|
||||||
|
|
||||||
<p>This little bit of code creates three tasks and pends them all
|
|
||||||
on the same semaphore.</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>=> (let ((s (semBCreate 0 0)))
|
|
||||||
(do ((i 0 (+ i 1))) ((= i 3) 'ok) (sp 'semTake s -1)))
|
|
||||||
<font class="output">task spawned: id = 0x1cefaf8, name = t4
|
|
||||||
task spawned: id = 0x1ce7980, name = t5
|
|
||||||
task spawned: id = 0x1cdf808, name = t6
|
|
||||||
ok</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>This would be more interesting if we had a means of spawning a
|
|
||||||
task to compute a Scheme subexpression, which could then deliver
|
|
||||||
its value to a waiting continuation in the spawning environment.
|
|
||||||
But that's a story for another day...</p>
|
|
||||||
|
|
||||||
<h3>"Supported" Platforms</h3>
|
|
||||||
|
|
||||||
<p>These are the platforms that I habitually run the code on.
|
|
||||||
There's a shell script, "runtest", in the root of the distribution
|
|
||||||
that will run a modest test suite on FreeBSD and Cygwin. This
|
|
||||||
includes Jaffer's R4 compliance test as well as some things I
|
|
||||||
picked up off the net and from SICP.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><b><a href=
|
|
||||||
"http://www.windriver.com/products/tornado2/tornado22_info.html">Tornado
|
|
||||||
2.2 (VxWorks 5.5)</a></b><br>
|
|
||||||
<p class="item">A Tornado project file is provided that will build
|
|
||||||
vx-scheme for the Tornado 2.2 simulator. It should be easy to adapt
|
|
||||||
for the architecture of your choice.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><b><a href="http://fedora.redhat.com/">Fedora</a></b><br>
|
|
||||||
<p class="item">I've recently installed Fedora Core 2 and I'm
|
|
||||||
pretty happy with it. VxScheme works just fine on it.</p></li>
|
|
||||||
|
|
||||||
<li><b><a href="http://www.cygwin.com/">Cygwin</a></b><br>
|
|
||||||
<p class="item">Similarly, just saying "make" in the
|
|
||||||
<code>unix</code> directory on Cygwin should produce a working
|
|
||||||
executable.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><b><a href="http://msdn.microsoft.com/">Win32</a></b><br>
|
|
||||||
<p class="item">Visual Studio C++ .NET project files are provided. </p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Memory and Garbage Collection</h3>
|
|
||||||
|
|
||||||
<p>This implementation uses a fairly standard cons cell structure.
|
|
||||||
The fundamental cell is a struct of two machine pointers, car and
|
|
||||||
cdr. They are required to contain 8-byte aligned addresses, leaving
|
|
||||||
the lower three bits free for tagging. The LSB is the "atom" tag,
|
|
||||||
and the other two are for GC marking/freelist management.</p>
|
|
||||||
|
|
||||||
<p>Integers that will fit in 24 bits are stored directly "in the
|
|
||||||
pointer" with no heap allocation. No special syntax is required
|
|
||||||
to access this feature and spillover to 32-bit arithmetic is
|
|
||||||
automatic (though such numbers come from cell storage).</p>
|
|
||||||
|
|
||||||
<p>Garbage collection is straight mark & sweep. We start with a
|
|
||||||
budget of 10000 conses. When an allocation fails, GC is attempted
|
|
||||||
at that moment. If we succeed in leaving at least 20% of the slab
|
|
||||||
free, we're happy. Otherwise, we note that our GC attempt wasn't
|
|
||||||
very successful, and arrange to allocate another slab at the next
|
|
||||||
allocation failure.</p>
|
|
||||||
|
|
||||||
<h3>Deficiencies, and Deviations from the R4 standard</h3>
|
|
||||||
|
|
||||||
<p>The R4 standard insists that hardware integer overflow must be
|
|
||||||
handled "correctly": either by spilling over into a
|
|
||||||
multiple-precision format, or raising an error. Vx-scheme does the
|
|
||||||
one thing that is forbidden: silently returning the wrong answer!
|
|
||||||
Integer arithmetic in vx-scheme is essentially a "front-end" for
|
|
||||||
the integer arithmetic provided by the C compiler and the hardware,
|
|
||||||
and no apologies are made for it.</p>
|
|
||||||
|
|
||||||
<p>Similarly, Scheme insists that when an object is written out, this
|
|
||||||
should be done so that when it is read back in, the exact same object
|
|
||||||
is produced. This is tricky for real numbers. In vx-scheme, again, the
|
|
||||||
floating point I/O is a "front end" for that provided by
|
|
||||||
"<code>strtod</code>" and "<code>printf %.15g</code>" respectively.
|
|
||||||
These don't always produce perfectly inverse behavior. Jaffer's SCM
|
|
||||||
takes the trouble to supply a custom FP I/O package that does have
|
|
||||||
this desirable behavior, but I decided not to bother. (Perhaps not
|
|
||||||
coincidentally, Guy L. Steele Jr., one of the inventors of Scheme,
|
|
||||||
published a <a
|
|
||||||
href="http://portal.acm.org/citation.cfm?doid=93542.93559">paper</a>
|
|
||||||
on stable floating point I/O.)</p>
|
|
||||||
|
|
||||||
<p>While the R4 standard doesn't require any better, perhaps now is
|
|
||||||
the time to point out that we only support 32-bit integers and
|
|
||||||
64-bit reals as numeric data types, declining to implement support
|
|
||||||
for rationals, arbitrary-precision integers, and complex numbers.
|
|
||||||
If Scheme itself seems an odd thing to run atop an RTOS, these
|
|
||||||
features would make it even more so!</p>
|
|
||||||
|
|
||||||
<p>Error handling in vx-scheme is weak. There's no backtrace
|
|
||||||
facility or debugger. When error conditions arise (typically
|
|
||||||
finding the wrong type of atom in an argument list) we print a
|
|
||||||
message indicating the type of atom expected and longjmp back to
|
|
||||||
the top of the read-eval-print loop.</p>
|
|
||||||
|
|
||||||
<p>Vx-Scheme is lazy about checking argument lists. If a call to a
|
|
||||||
standard procedure supplies extra arguments, these are typically
|
|
||||||
ignored. Other examples of slothfulness (like letting cond's have
|
|
||||||
multiple else's, etc.) abound. Vx-Scheme is of course interested in
|
|
||||||
giving the correct result for correctly-formed expressions, but is
|
|
||||||
amazingly indulgent of ill-formed ones.</p>
|
|
||||||
|
|
||||||
<p>Vx-Scheme is not quite reentrant. While there are very few
|
|
||||||
global variables (and most of those have invariant values that
|
|
||||||
could be shared among multiple threads), some aspects of vx-scheme
|
|
||||||
(such as memory management) have not yet been made MT-safe. Part of
|
|
||||||
the reason for this: how to implement a multi-threaded scheme on an
|
|
||||||
RTOS is actually an interesting question! One way to do it would be
|
|
||||||
to have separate Scheme name/evaluation spaces running in different
|
|
||||||
VxWorks tasks. But another way to do it would share the namespace
|
|
||||||
and allow the "spawning" of threads to evaluate Scheme
|
|
||||||
subexpressions and return the resulting values to the waiting
|
|
||||||
tasks. I haven't decided which (if any) of these models to
|
|
||||||
attempt.</p>
|
|
||||||
|
|
||||||
<h3>Extra Goodies</h3>
|
|
||||||
|
|
||||||
<p>If I were willing to learn about and implement R5's
|
|
||||||
syntax-extension facility, this implementation would be within
|
|
||||||
striking distance of R5 compliance. R4 requires no support for
|
|
||||||
defining new special forms whatsoever. But I decided to add support
|
|
||||||
for defmacro, a very handy tool. It's strong enough to implement
|
|
||||||
the stream processing features detailed in SICP's <a href=
|
|
||||||
"http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5">
|
|
||||||
§3.5</a>. Here's a more pedestrian example, the
|
|
||||||
<code>while</code> special form:</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>(defmacro (while test . body)
|
|
||||||
`(let loop ()
|
|
||||||
(if ,test
|
|
||||||
(begin ,@body (loop))
|
|
||||||
'ok)))
|
|
||||||
|
|
||||||
(define i 0)
|
|
||||||
|
|
||||||
(while (< i 5)
|
|
||||||
(display i)
|
|
||||||
(set! i (+ i 1)))
|
|
||||||
<font class="output">--> 01234ok</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>(I include this example because I think Scheme's <code>do</code>
|
|
||||||
iteration construct is actually a bit of sly humor directed at
|
|
||||||
procedural programming partisans: a kitchen-sink iteration model
|
|
||||||
that is very difficult to read!)</p>
|
|
||||||
|
|
||||||
<p>Benchmarking is facilitated by the <code>time</code> special
|
|
||||||
form, which evaluates its argument(s) (as if it were
|
|
||||||
<code>begin</code>), but returns a pair whose car is the elapsed
|
|
||||||
time in microseconds and whose cdr is the value of the last
|
|
||||||
expression in the sequence (just as <code>begin</code> would have
|
|
||||||
returned).</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
<code>(define (count n)
|
|
||||||
(let loop ((i 1))
|
|
||||||
(if (= i n) #t (loop (+ i 1)))))
|
|
||||||
|
|
||||||
(time (count 100000))
|
|
||||||
<font class="output">--> (628424 . #t)</font>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>The <code>gc</code> procedure can be used to force a garbage
|
|
||||||
collection.</p>
|
|
||||||
|
|
||||||
<h3>SLIB integration</h3>
|
|
||||||
|
|
||||||
<p>Chris Gaskett generously contributed an init file for Aubrey
|
|
||||||
Jaffer's SLIB. This is integrated into the test suite (on Linux
|
|
||||||
and Cygwin).</p>
|
|
||||||
|
|
||||||
<h3>Magic Cells</h3>
|
|
||||||
|
|
||||||
<p>This scheme interpreter has a facility wherein the evaluator
|
|
||||||
will call out to an OS layer just before it is about report that a
|
|
||||||
symbol has no binding. This gives the OS a chance to supply a
|
|
||||||
binding using its own resources (in the case of VxWorks, the C
|
|
||||||
symbol table).</p>
|
|
||||||
|
|
||||||
<p>How this works is the OS returns a <i>magic cell</i>, which is a
|
|
||||||
kind of atom that has two function pointers in it, <code>set</code>
|
|
||||||
and <code>get</code>. The Scheme system stores the magic cell in
|
|
||||||
the binding table. When VxWorks finds that an unbound Scheme symbol
|
|
||||||
matches a C variable, it returns one of these cells, which allows
|
|
||||||
the current value of the variable to be probed whenever Scheme code
|
|
||||||
calls for the variable to be evaulated.</p>
|
|
||||||
|
|
||||||
<p>VxWorks functions are a little more complicated: they actually
|
|
||||||
return a lambda expression which delegates to a special function
|
|
||||||
called "vx-invoke" whose job is to dispatch a call to the VxWorks
|
|
||||||
function after converting the arguments.</p>
|
|
||||||
|
|
||||||
<p>But I think magic cells are a neat hack: kind of like java bean
|
|
||||||
or COM “properties.” I'm sure it's been done before, of
|
|
||||||
course, but it's interesting to speculate on other uses for this
|
|
||||||
trick.</p>
|
|
||||||
|
|
||||||
<h3>Debugging Hacks</h3>
|
|
||||||
|
|
||||||
<p>There's an interface to supply a “flag word” to the
|
|
||||||
Scheme process. On UNIX/Cygwin, the environment variable
|
|
||||||
‘T’ can be set to an integer which sets any of the bits
|
|
||||||
in the following table. On VxWorks, the global variable
|
|
||||||
vxSchemeDebug can be set to the desired value using the C shell.
|
|
||||||
The bit values are:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>0x1:TRACE_EVAL.</code><br>
|
|
||||||
<p class="item">This shows every step of the register machine in
|
|
||||||
evaluating its input. This was very useful debugging my
|
|
||||||
implementation of SICP's register machine. For trenchant problems,
|
|
||||||
this can create a <i>lot</i> of output.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><code>0x2: TRACE_GC.</code><br>
|
|
||||||
<p class="item">This one prints out a message when garbage is
|
|
||||||
collected. The first line shows the state of memory at the start in
|
|
||||||
the form m/n (where m is the number of cells in use and n is the
|
|
||||||
number of cells allocated). After GC is finished, these statistics
|
|
||||||
are printed again.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><code>0x4: DEBUG_NO_INLINE_GC.</code><br>
|
|
||||||
<p class="item">Garbage collection is a tricky thing. Everything
|
|
||||||
depends on every useful cell being "reachable" from a "root set" of
|
|
||||||
machine registers. This implementation of Scheme takes pains to
|
|
||||||
organize all the computation around a set of abstract machine
|
|
||||||
registers (unlike other implementations of Scheme which allow the C
|
|
||||||
stack to contain references to Scheme objects). I know of no GC
|
|
||||||
bugs at the moment, but setting this flag is helpful to help
|
|
||||||
implicate/exculpate GC in a debug session: when set, the flag
|
|
||||||
prevents GC from occurring at memory exhaustion time (it is still
|
|
||||||
allowed when the top-level expression is complete).</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><code>0x8: DEBUG_MEMSTATS_AT_EXIT.</code><br>
|
|
||||||
<p class="item">The Scheme standard insists on a strict
|
|
||||||
implementation of tail recursion. Setting this flag causes a
|
|
||||||
one-line printout of the number of cells in-use/allocated at the
|
|
||||||
end of execution. This can be used to verify that tail-recursion
|
|
||||||
and garbage collection are working correctly.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><code>0x10: DEBUG_PRINT_PROCEDURES</code><br>
|
|
||||||
<p class="item">Without this flag, when printing a value of
|
|
||||||
procedure type, the printer suppresses the body of the procedure,
|
|
||||||
but does print the argument list. Usually this is enough to remind
|
|
||||||
me what procedure is involved. The output looks like this:
|
|
||||||
<code>#<lambda (a b) ...></code>. With this flag set, the
|
|
||||||
body of the procedure is printed as well, instead of an
|
|
||||||
ellipsis.</p></li>
|
|
||||||
|
|
||||||
<li><code>0x20: TRACE_GC_ALL</code><br>
|
|
||||||
<p class="item">Trace all marking and sweeping activity. This is
|
|
||||||
only useful if you are tracking down a garbage collection bug. Having
|
|
||||||
done this a few times, I can only offer my wish that this fate never
|
|
||||||
befalls you. As of this writing (10 May 2003), I am not aware of
|
|
||||||
any garbage collection bugs in vx-scheme.</p></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
Example use:
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p class="item">UNIX: <code>T=1 ./vx-scheme <
|
|
||||||
../testcases/pi.scm</code></p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<p class="item">VxWorks: <code>vxSchemeDebug = 1;</code></p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>VxWorks Links</h3>
|
|
||||||
|
|
||||||
<p>Check out the <a
|
|
||||||
href="http://www.bluedonkey.org/cgi-bin/twiki/bin/view/Books/VxWorksCookBook">VxWorks
|
|
||||||
Cookbook</a> at John Gordon's site, <a
|
|
||||||
href="http://www.bluedonkey.org/">bluedonkey.org</a>. It's an
|
|
||||||
excellent collection of VxWorks (and related) embedded technique
|
|
||||||
assembled by one of the masters.</p>
|
|
||||||
|
|
||||||
<h3>Scheme Links</h3>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href=
|
|
||||||
"http://www.swiss.ai.mit.edu/projects/scheme/index.html">The MIT
|
|
||||||
Scheme Homepage</a><br>
|
|
||||||
<p class="item"><i>The MIT Scheme interpretation compiles directly
|
|
||||||
to x86 machine code, and is consequently very fast, and has an
|
|
||||||
integrated debugger and graphics support. Very professional. Runs
|
|
||||||
on Linux, FreeBSD and Win32.</i></p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="http://www-mitpress.mit.edu/sicp/">Online text for
|
|
||||||
SICP</a><br>
|
|
||||||
<p class="item"><i>Worth the effort to study in detail. The sly
|
|
||||||
postponement of the discussion of the humble assignment statement
|
|
||||||
to page 220 of the book is a pedagogic</i>
|
|
||||||
tour-de-force<i>unequaled in my experience.</i></p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="http://www.schemers.org">Schemers.org</a><br>
|
|
||||||
<p class="item"><i>A clearinghouse of net Scheme resources.
|
|
||||||
Recommended.</i></p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Acknowledgments</h3>
|
|
||||||
|
|
||||||
<p>Permit me to thank the following people who have helped with
|
|
||||||
this research:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p class="item">Benjamin S. Skrainka (Contact him if you need
|
|
||||||
<a href="http://www.skrainka.biz">VxWorks training</a>!)</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<p class="item">George V. Neville-Neil (<a href=
|
|
||||||
"http://www.neville-neil.com">internet consultant
|
|
||||||
extraordinaire</a>)</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<p class="item">Brendan Smith (Computer trouble in the Skagit
|
|
||||||
Valley? <a href="http://www.brendan-smith.net">Give him a
|
|
||||||
call!</a>)</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<p class="item">...and my lovely wife
|
|
||||||
<a href="http://www.juliebird.net/">Julia</a>, who often wondered what
|
|
||||||
the point of having a computer day job was if I was just going to
|
|
||||||
spend the rest of my time hacking in the garage.</p> </li> </ul>
|
|
||||||
|
|
||||||
<p class="quiet">Copyright © 2002-2003
|
|
||||||
<a href="http://colin-smith.net/">Colin Smith</a>.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<hr>
|
|
||||||
<img alt="Emacs powered" src="emacs-powered-orange.jpg">
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue