The accursed program feature. Written; not tested.

This commit is contained in:
Simon Brooke 2023-04-07 15:18:13 +01:00
parent dd6a9f7fbc
commit 022e409c51
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
24 changed files with 345 additions and 78 deletions

View file

@ -1,7 +1,16 @@
# Further Reading # Further Reading
1. [CODING for the MIT-IBM 704 COMPUTER, October 1957](http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf) 1. [CODING for the MIT-IBM 704 COMPUTER, October 1957](http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf)
This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.
2. [MIT AI Memo 1, John McCarthy, September 1958](https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf) 2. [MIT AI Memo 1, John McCarthy, September 1958](https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf)
This is, as far as I can find, the earliest specification document of the Lisp project.
3. [Lisp 1 Programmer's Manual, Phyllis Fox, March 1960](https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf) 3. [Lisp 1 Programmer's Manual, Phyllis Fox, March 1960](https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf)
4. [Lisp 1.5 Programmer's Manual, Michael I. Levin, August 1962](https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81) 4. [Lisp 1.5 Programmer's Manual, Michael I. Levin, August 1962](https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81)
This book is essential reading: it documents in some detail the first fully realised Lisp language system.
5. [Early LISP History (1956 - 1959), Herbert Stoyan, August 1984](https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3) 5. [Early LISP History (1956 - 1959), Herbert Stoyan, August 1984](https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3)
6. [The Roots of Lisp, Paul Graham, 2001](http://www.paulgraham.com/rootsoflisp.html)
6. [The Revenge of the Nerds, Paul Graham, 2002](http://www.paulgraham.com/icad.html)
This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.
> So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesn't get stale.

View file

@ -5,10 +5,10 @@
**Massachusetts Institute of Technology** **Massachusetts Institute of Technology**
> John McCarthy > [John McCarthy](https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist))
> Paul W. Abrahams > [Paul W. Abrahams](https://mitpress.mit.edu/author/paul-w-abrahams-31449/)
> Daniel J. Edwards > [Daniel J. Edwards](https://www.chessprogramming.org/Daniel_Edwards)
> Timothy P. Hart > [Timothy P. Hart](https://www.chessprogramming.org/Timothy_Hart)
> The M. I.T. Press > The M. I.T. Press
> Massachusetts Institute of Technology > Massachusetts Institute of Technology
@ -43,11 +43,11 @@ The over-all design of the LISP Programming System is the work of John McCarthy
This manual was written by Michael I. Levin. This manual was written by Michael I. Levin.
The interpreter was programmed by Stephen B. Russell and Daniel J. Edwards. The print and read programs were written by John McCarthy, Klim Maling, Daniel J. Edwards, and Paul W, Abrahams. The interpreter was programmed by [Stephen B. Russell](https://en.wikipedia.org/wiki/Steve_Russell_(computer_scientist)) and Daniel J. Edwards. The print and read programs were written by John McCarthy, Klim Maling, Daniel J. Edwards, and Paul W. Abrahams.
The garbage collector and arithmetic features Were written by Daniel J. Edwards. The compiler and assembler were written by Timothy P. Hart and Michael I. Levin. An earlier compiler was written by Robert Brayton. The garbage collector and arithmetic features Were written by Daniel J. Edwards. The compiler and assembler were written by Timothy P. Hart and Michael I. Levin. An earlier compiler was written by Robert Brayton.
The "LISP 1 Programmer's Manual" March 1, 1960, was written by Phyllis A. Fox. Additional programs and suggestions were contributed by the following members of the Artificial Intelligence Group of the Research Laboratory of Electronics: Marvin L. Minsky, Bertram Raphael, Louis Hodes, David M. R. Park, David C. Luckham, Daniel G. Bobrow, James R. Slagle, and Nathaniel Rochester. The "LISP 1 Programmer's Manual" March 1, 1960, was written by [Phyllis A. Fox](https://en.wikipedia.org/wiki/Phyllis_Fox). Additional programs and suggestions were contributed by the following members of the Artificial Intelligence Group of the Research Laboratory of Electronics: Marvin L. Minsky, Bertram Raphael, Louis Hodes, David M. R. Park, David C. Luckham, Daniel G. Bobrow, James R. Slagle, and Nathaniel Rochester.
August 17, 1962 August 17, 1962
@ -3347,7 +3347,7 @@ eval[form; a]= [
eq[car[form]; QUOTE] -> cadr[form]; eq[car[form]; QUOTE] -> cadr[form];
eq[car[form]; FUNCTION] -> list[FUNARG; cadr[form]; a]; eq[car[form]; FUNCTION] -> list[FUNARG; cadr[form]; a];
eq[car [form]; COND] -> evcon[cdr[form]; a]; eq[car [form]; COND] -> evcon[cdr[form]; a];
eq[car [form]; PROG] -> prog[cdr [form]; a]; eq[car [form]; PROG] -> prog[cdr[form]; a];
atom[car[form]] -> [get[car [form]; EXPR] -> atom[car[form]] -> [get[car [form]; EXPR] ->
apply[expr; evlis[cdr[form]; a]; a]; apply[expr; evlis[cdr[form]; a]; a];
get[car[form]; FEXPR] -> get[car[form]; FEXPR] ->
@ -3375,27 +3375,18 @@ The PROG feature is an FSUBR coded into the system. It can best be explained in
English, although it is possible to define it by using M-expressions. English, although it is possible to define it by using M-expressions.
1. As soon as the PROG feature is entered, the list of program variables is used 1. As soon as the PROG feature is entered, the list of program variables is used
to make a new list in which each one is paired with NIL. This is then appended to the to make a new list in which each one is paired with NIL. This is then appended to the current a-list. Thus each program variable is set to NIL at the entrance to the program.
current a-list. Thus each program variable is set to NIL at the entrance to the program.
2. The remainder of the program is searched for atomic symbols that are under- 2. The remainder of the program is searched for atomic symbols that are under-
stood to be location symbols. A go-list is formed in which each location symbol is stood to be location symbols. A go-list is formed in which each location symbol is paired with a pointer into the remainder of the program.
paired with a pointer into the remainder of the program. 3. When a set or a setq - is encountered, the name of the variable is located on the a-list. The value of the variable (or cdr of the pair) is actually replaced with the new value.
3. When a set or a setq - is encountered, the name of the variable is located on the
a-list. The value of the variable (or cs of the pair) is actually replaced with the new
value.
----- -----
1. The value of get is set aside. This is the meaning of the apparent free or unde- 1. The value of get is set aside. This is the meaning of the apparent free or undefined variable.
fined variable- 2. In the actual system this is handled by an FSUBR rather than as the separate special case as shown here.
2. In the actual system this is handled by an FSUBR rather than as the separate special
case as shown here.
<a name="page72">page 72</a> <a name="page72">page 72</a>
If the variable is bound several times on the a-list, only the first or most recent If the variable is bound several times on the a-list, only the first or most recent occurrence is changed. If the current binding of the variable is at a higher level than the entrance to the prog, then the change will remain in effect throughout the scope of that binding, and the old value will be lost.
occurrence is changed. If the current binding of the variable is at a higher level than
the entrance to the prog, then the change will remain in effect throughout the scope
of that binding, and the old value will be lost.
If the variable does not occur on the a-list, then error diagnostic `A4` or `A5` will occur. If the variable does not occur on the a-list, then error diagnostic `A4` or `A5` will occur.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Further Reading</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values: here be dragons</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#further-reading" name="further-reading"></a>Further Reading</h1>
<ol>
<li><a href="http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf">CODING for the MIT-IBM 704 COMPUTER, October 1957</a> This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.</li>
<li><a href="https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf">MIT AI Memo 1, John McCarthy, September 1958</a> This is, as far as I can find, the earliest specification document of the Lisp project.</li>
<li><a href="https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf">Lisp 1 Programmers Manual, Phyllis Fox, March 1960</a></li>
<li><a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81">Lisp 1.5 Programmers Manual, Michael I. Levin, August 1962</a> This book is essential reading: it documents in some detail the first fully realised Lisp language system.</li>
<li><a href="https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3">Early LISP History (1956 - 1959), Herbert Stoyan, August 1984</a></li>
<li>
<p><a href="http://www.paulgraham.com/rootsoflisp.html">The Roots of Lisp, Paul Graham, 2001</a></p></li>
<li>
<p><a href="http://www.paulgraham.com/icad.html">The Revenge of the Nerds, Paul Graham, 2002</a> This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.</p>
<blockquote>
<p>So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesnt get stale.</p>
</blockquote></li>
</ol></div></div></div></body></html>

File diff suppressed because one or more lines are too long

View file

@ -1,11 +1,11 @@
<!DOCTYPE html PUBLIC "" <!DOCTYPE html PUBLIC ""
""> "">
<html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>Understanding values and properties</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" name="beowulf"></a>beowulf</h1> <html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values: here be dragons</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" name="beowulf"></a>beowulf</h1>
<p>LISP 1.5 is to all Lisp dialects as Beowulf is to English literature.</p> <p>LISP 1.5 is to all Lisp dialects as Beowulf is to English literature.</p>
<h2><a href="#what-this-is" name="what-this-is"></a>What this is</h2> <h2><a href="#what-this-is" name="what-this-is"></a>What this is</h2>
<p>A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the same bahaviour - except as documented below.</p> <p>A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the same bahaviour - except as documented below.</p>
<h3><a href="#status" name="status"></a>Status</h3> <h3><a href="#status" name="status"></a>Status</h3>
<p>Boots to REPL, but few functions yet available.</p> <p>Working Lisp interpreter, but some key features not yet implemented.</p>
<ul> <ul>
<li><a href="https://simon-brooke.github.io/beowulf/">Project website</a>.</li> <li><a href="https://simon-brooke.github.io/beowulf/">Project website</a>.</li>
<li><a href="https://simon-brooke.github.io/beowulf/docs/codox/index.html">Source code documentation</a>.</li> <li><a href="https://simon-brooke.github.io/beowulf/docs/codox/index.html">Source code documentation</a>.</li>
@ -15,7 +15,7 @@
<pre><code>lein uberjar <pre><code>lein uberjar
</code></pre> </code></pre>
<p>Invoke with</p> <p>Invoke with</p>
<pre><code>java -jar target/uberjar/beowulf-0.2.1-SNAPSHOT-standalone.jar --help <pre><code>java -jar target/uberjar/beowulf-0.3.0-SNAPSHOT-standalone.jar --help
</code></pre> </code></pre>
<p>(Obviously, check your version number)</p> <p>(Obviously, check your version number)</p>
<p>Command line arguments as follows:</p> <p>Command line arguments as follows:</p>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html PUBLIC "" <!DOCTYPE html PUBLIC ""
""> "">
<html><head><meta charset="UTF-8" /><title>Interpreting M-Expressions</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 current"><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>Understanding values and properties</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#interpreting-m-expressions" name="interpreting-m-expressions"></a>Interpreting M-Expressions</h1> <html><head><meta charset="UTF-8" /><title>Interpreting M-Expressions</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 current"><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values: here be dragons</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#interpreting-m-expressions" name="interpreting-m-expressions"></a>Interpreting M-Expressions</h1>
<p>M-Expressions (mexprs) are the grammar which John McCarthy origininally used to write Lisp, and the grammar in which many of the function definitions in the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">Lisp 1.5 Programmers Manual</a> are stated. However, I have not seen anywhere a claim that Lisp 1.5 could <em>read</em> M-Expressions, and it is not clear to me whether it was even planned that it should do so, although the discussion on <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=18">page 10</a> suggests that it was.</p> <p>M-Expressions (mexprs) are the grammar which John McCarthy origininally used to write Lisp, and the grammar in which many of the function definitions in the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">Lisp 1.5 Programmers Manual</a> are stated. However, I have not seen anywhere a claim that Lisp 1.5 could <em>read</em> M-Expressions, and it is not clear to me whether it was even planned that it should do so, although the discussion on <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=18">page 10</a> suggests that it was.</p>
<p>Rather, it seems to me possible that M-Expressions were only ever a grammar intended to be written on paper, like <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">Backus Naur Form</a>, to describe and to reason about algorithms. I think at the point at which the M-Expression grammar was written, the idea of the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=18">universal Lisp function</a></p> <p>Rather, it seems to me possible that M-Expressions were only ever a grammar intended to be written on paper, like <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">Backus Naur Form</a>, to describe and to reason about algorithms. I think at the point at which the M-Expression grammar was written, the idea of the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=18">universal Lisp function</a></p>
<p>I set out to make Beowulf read M-Expressions essentially out of curiousity, to see whether it could be done. I had this idea that if it could be done, I could implement most of Lisp 1.5 simply by copying in the M-Expression definitions out of the manual.</p> <p>I set out to make Beowulf read M-Expressions essentially out of curiousity, to see whether it could be done. I had this idea that if it could be done, I could implement most of Lisp 1.5 simply by copying in the M-Expression definitions out of the manual.</p>

File diff suppressed because one or more lines are too long

View file

@ -34,6 +34,5 @@
["uberjar"] ["uberjar"]
["change" "version" "leiningen.release/bump-version"] ["change" "version" "leiningen.release/bump-version"]
["vcs" "commit"]] ["vcs" "commit"]]
:target-path "target/%s" :target-path "target/%s"
:url "https://github.com/simon-brooke/the-great-game") :url "https://github.com/simon-brooke/the-great-game")

View file

@ -9,7 +9,8 @@
ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell` therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
objects." objects."
(:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell T]] (:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell
pretty-print T]]
[beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET [beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET
LIST NUMBERP PAIRLIS traced?]] LIST NUMBERP PAIRLIS traced?]]
[beowulf.oblist :refer [*options* NIL oblist]]) [beowulf.oblist :refer [*options* NIL oblist]])
@ -36,7 +37,147 @@
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare APPLY EVAL) (declare APPLY EVAL prog-eval)
(def find-target
(memoize
(fn [target body]
(loop [body' body]
(cond
(= body' NIL) (throw (ex-info "Invalid GO target"
{:phase :lisp
:function 'PROG
:type :lisp
:code :A6}))
(= (.getCar body') target) body'
:else (recur (.getCdr body')))))))
(defn- prog-cond
"Like `EVCON`, q.v. except using `prog-eval` instead of `EVAL` and not
throwing an error if no clause matches."
[clauses vars env depth]
(loop [clauses' clauses]
(if-not (= clauses' NIL)
(let [test (prog-eval (CAAR clauses') vars env depth)]
(if (not (#{NIL F} test))
(prog-eval (CADAR clauses') vars env depth)
(recur (.getCdr clauses'))))
NIL)))
(defn prog-eval
"Like `EVAL`, q.v., except handling symbols, and expressions starting
`GO`, `RETURN`, `SET` and `SETQ` specially."
[expr vars env depth]
(cond
(number? expr) expr
(symbol? expr) (@vars expr)
(instance? ConsCell expr) (case (.getCar expr)
COND (prog-cond (.getCdr expr)
vars env depth)
GO (make-cons-cell
'*PROGGO* (.getCdr expr))
RETURN (make-cons-cell
'*PROGRETURN*
(EVAL (.getCdr expr) env depth))
SET (swap! vars
assoc
(prog-eval (CADR expr)
vars env depth)
(prog-eval (CADDR expr)
vars env depth))
SETQ (swap! vars
assoc
(CADR expr)
(prog-eval (CADDR expr)
vars env depth))
;; else
(beowulf.bootstrap/EVAL expr env depth))))
(defn PROG
"The accursed `PROG` feature. See page 71 of the manual.
Lisp 1.5 introduced `PROG`, and most Lisps have been stuck with it ever
since. It introduces imperative programming into what should be a pure
functional language, and consequently it's going to be a pig to implement.
Broadly, `PROG` is a variadic pseudo function called as a `FEXPR` (or
possibly an `FSUBR`, although I'm not presently sure that would even work.)
The arguments, which are unevaluated, are a list of forms, the first of
which is expected to be a list of symbols which will be treated as names
of variables within the program, and the rest of which (the 'program body')
are either lists or symbols. Lists are treated as Lisp expressions which
may be evaulated in turn. Symbols are treated as targets for the `GO`
statement.
**GO:**
A `GO` statement takes the form of `(GO target)`, where
`target` should be one of the symbols which occur at top level among that
particular invocation of `PROG`s arguments. A `GO` statement may occur at
top level in a PROG, or in a clause of a `COND` statement in a `PROG`, but
not in a function called from the `PROG` statement. When a `GO` statement
is evaluated, execution should transfer immediately to the expression which
is the argument list immediately following the symbol which is its target.
If the target is not found, an error with the code `A6` should be thrown.
**RETURN:**
A `RETURN` statement takes the form `(RETURN value)`, where
`value` is any value. Following the evaluation of a `RETURN` statement,
the `PROG` should immediately exit without executing any further
expressions, returning the value.
**SET and SETQ:**
In addition to the above, if a `SET` or `SETQ` expression is encountered
in any expression within the `PROG` body, it should affect not the global
object list but instead only the local variables of the program.
**COND:**
In **strict** mode, when in normal execution, a `COND` statement none of
whose clauses match should not return `NIL` but should throw an error with
the code `A3`... *except* that inside a `PROG` body, it should not do so.
*sigh*.
**Flow of control:**
Apart from the exceptions specified above, expressions in the program body
are evaluated sequentially. If execution reaches the end of the program
body, `NIL` is returned.
Got all that?
Good."
[program env depth]
(let [trace (traced? 'PROG)
vars (atom (reduce merge (map #(assoc {} % NIL) (.getCar program))))
body (.getCdr program)
targets (set (filter symbol? body))]
(when trace (do
(println "Program:")
(pretty-print program))) ;; for debugging
(loop [cursor body]
(let [step (.getCar cursor)]
(when trace (do (println "Executing step: " step)
(println " with vars: " vars)))
(cond (= cursor NIL) NIL
(symbol? step) (recur step)
:else (let [v (prog-eval (.getCar cursor) vars env depth)]
(if (instance? ConsCell v)
(case (.getCar v)
*PROGGO* (let [target (.getCdr v)]
(if (targets target)
(recur (find-target target body))
(throw (ex-info "Invalid GO target"
{:phase :lisp
:function 'PROG
:args program
:type :lisp
:code :A6}))))
*PROGRETURN* (.getCdr v)
;; else
(recur (.getCdr cursor)))
(recur (.getCdr cursor)))))))))
(defn try-resolve-subroutine (defn try-resolve-subroutine
"Attempt to resolve this `subr` with these `arg`." "Attempt to resolve this `subr` with these `arg`."
@ -143,15 +284,26 @@
(defn- EVCON (defn- EVCON
"Inner guts of primitive COND. All `clauses` are assumed to be "Inner guts of primitive COND. All `clauses` are assumed to be
`beowulf.cons-cell/ConsCell` objects. Note that tests in Lisp 1.5 `beowulf.cons-cell/ConsCell` objects. Note that tests in Lisp 1.5
often return `F`, not `NIL`, on failure. often return `F`, not `NIL`, on failure. If no clause matches,
then, strictly, we throw an error with code `:A3`.
See page 13 of the Lisp 1.5 Programmers Manual." See pages 13 and 71 of the Lisp 1.5 Programmers Manual."
[clauses env depth] [clauses env depth]
(let [test (EVAL (CAAR clauses) env depth)] (loop [clauses' clauses]
(if (if-not (= clauses' NIL)
(and (not= test NIL) (not= test 'F)) (let [test (EVAL (CAAR clauses') env depth)]
(EVAL (CADAR clauses) env depth) (if (not (#{NIL F} test))
(EVCON (CDR clauses) env depth)))) ;; (and (not= test NIL) (not= test F))
(EVAL (CADAR clauses') env depth)
(recur (.getCdr clauses'))))
(if (:strict *options*)
(throw (ex-info "No matching clause in COND"
{:phase :eval
:function 'COND
:args (list clauses)
:type :lisp
:code :A3}))
NIL))))
(defn- EVLIS (defn- EVLIS
"Map `EVAL` across this list of `args` in the context of this "Map `EVAL` across this list of `args` in the context of this
@ -214,9 +366,10 @@
:expr expr})) :expr expr}))
(symbol expr)) (symbol expr))
(= (ATOM (CAR expr)) T) (case (CAR expr) (= (ATOM (CAR expr)) T) (case (CAR expr)
QUOTE (CADR expr)
FUNCTION (LIST 'FUNARG (CADR expr))
COND (EVCON (CDR expr) env depth) COND (EVCON (CDR expr) env depth)
FUNCTION (LIST 'FUNARG (CADR expr))
PROG (PROG (CDR expr) env depth)
QUOTE (CADR expr)
;; else ;; else
(APPLY (APPLY
(CAR expr) (CAR expr)