beowulf.bootstrap
Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual
; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host
, be sufficient to bootstrap the full Lisp 1.5 interpreter..
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.bootstrap
Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual
; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host
, be sufficient to bootstrap the full Lisp 1.5 interpreter..
The convention is adopted that functions in this file with names in ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that therefore all arguments must be numbers, symbols or beowulf.cons_cell.ConsCell
objects.
APPEND
(APPEND x y)
Append the the elements of y
to the elements of x
.
All args are assumed to be beowulf.cons-cell/ConsCell
objects. See page 11 of the Lisp 1.5 Programmers Manual.
APPLY
(APPLY function args environment)
For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or beowulf.cons-cell/ConsCell
objects. See page 13 of the Lisp 1.5 Programmers Manual.
ASSOC
(ASSOC x a)
If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function.
All args are assumed to be beowulf.cons-cell/ConsCell
objects. See page 12 of the Lisp 1.5 Programmers Manual.
ATOM
macro
(ATOM x)
Returns T
if and only if the argument x
is bound to an atom; else F
. It is not clear to me from the documentation whether (ATOM 7)
should return T
or F
. I’m going to assume T
.
ATOM?
macro
(ATOM? x)
The convention of returning F
from predicates, rather than NIL
, is going to tie me in knots. This is a variant of ATOM
which returns NIL
on failure.
CAR
(CAR x)
Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL.
CDR
(CDR x)
Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL.
DEFINE
(DEFINE args)
Bootstrap-only version of DEFINE
which, post boostrap, can be overwritten in LISP.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.cons-cell
The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.
F
The canonical false value - different from NIL
, which is not canonically false in Lisp 1.5.
make-beowulf-list
(make-beowulf-list x)
Construct a linked list of cons cells with the same content as the sequence x
.
make-cons-cell
(make-cons-cell car cdr)
Construct a new instance of cons cell with this car
and cdr
.
MutableSequence
protocol
Like a sequence, but mutable.
members
getCar
(getCar this)
Return the first element of this sequence.
getCdr
(getCdr this)
like more
, q.v., but returns List NIL
not Clojure nil
when empty.
getUid
(getUid this)
Returns a unique identifier for this object
rplaca
(rplaca this value)
replace the first element of this sequence with this value
rplacd
(rplacd this value)
replace the rest (but-first; cdr) of this sequence with this value
pretty-print
(pretty-print cell)
(pretty-print cell width level)
This isn’t the world’s best pretty printer but it sort of works.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.cons-cell
The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.
F
The canonical false value - different from NIL
, which is not canonically false in Lisp 1.5.
make-beowulf-list
(make-beowulf-list x)
Construct a linked list of cons cells with the same content as the sequence x
.
make-cons-cell
(make-cons-cell car cdr)
Construct a new instance of cons cell with this car
and cdr
.
MutableSequence
protocol
Like a sequence, but mutable.
members
getCar
(getCar this)
Return the first element of this sequence.
getCdr
(getCdr this)
like more
, q.v., but returns List NIL
not Clojure nil
when empty.
getUid
(getUid this)
Returns a unique identifier for this object
rplaca
(rplaca this value)
replace the first element of this sequence with this value
rplacd
(rplacd this value)
replace the rest (but-first; cdr) of this sequence with this value
pretty-print
(pretty-print cell)
(pretty-print cell width level)
This isn’t the world’s best pretty printer but it sort of works.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.core
Essentially, the -main
function and the bootstrap read-eval-print loop.
-main
(-main & opts)
Parse options, print the banner, read the init file if any, and enter the read/eval/print loop.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.core
Essentially, the -main
function and the bootstrap read-eval-print loop.
-main
(-main & opts)
Parse options, print the banner, read the init file if any, and enter the read/eval/print loop.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.host
provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.
PLUS2
(PLUS2 x y)
Lisp 1.5 PLUS
is varargs, and implementing varargs functions in Clojure is not an added complexity I want. So this is a two arg PLUS
, on which a varargs PLUS
can be built in the Lisp 1.5 layer using REDUCE
.
QUOTIENT
(QUOTIENT x y)
I’m not certain from the documentation whether Lisp 1.5 QUOTIENT
returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter.
RPLACA
(RPLACA cell value)
Replace the CAR pointer of this cell
with this value
. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
RPLACD
(RPLACD cell value)
Replace the CDR pointer of this cell
with this value
. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.host
provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.
PLUS2
(PLUS2 x y)
Lisp 1.5 PLUS
is varargs, and implementing varargs functions in Clojure is not an added complexity I want. So this is a two arg PLUS
, on which a varargs PLUS
can be built in the Lisp 1.5 layer using REDUCE
.
QUOTIENT
(QUOTIENT x y)
I’m not certain from the documentation whether Lisp 1.5 QUOTIENT
returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter.
RPLACA
(RPLACA cell value)
Replace the CAR pointer of this cell
with this value
. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
RPLACD
(RPLACD cell value)
Replace the CDR pointer of this cell
with this value
. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.io
Non-standard extensions to Lisp 1.5 to read and write to the filesystem.
+Lisp 1.5 had only READ
, which read one S-Expression at a time, and various forms of PRIN*
functions, which printed to the line printer. There was also PUNCH
, which wrote to a card punch. It does not seem that there was any concept of an interactive terminal.
See Appendix E, OVERLORD - THE MONITOR
, and Appendix F, LISP INPUT
+AND OUTPUT
.
For our purposes, to save the current state of the Lisp system it should be sufficient to print the current contents of the oblist to file; and to restore a previous state from file, to overwrite the contents of the oblist with data from that file.
+Hence functions SYSOUT and SYSIN, which do just that.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.read
This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.
+Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.read
This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.
Intended deviations from the behaviour of the real Lisp reader are as follows:
-
-
- It reads the meta-expression language
MEXPR
in addition to fLAMthe symbolic expression languageSEXPR
, which I do not believe the Lisp 1.5 reader ever did;
- - It treats everything between a semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature. +
- It reads the meta-expression language
MEXPR
in addition to the symbolic expression languageSEXPR
, which I do not believe the Lisp 1.5 reader ever did;
+ - It treats everything between a double semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.
Both these extensions can be disabled by using the --strict
command line switch.
gsp
(gsp s)
Shortcut macro - the internals of read; or, if you like, read-string. Argument s
should be a string representation of a valid Lisp expression.
READ
(READ)
(READ input)
An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. input
should be either a string representation of a LISP expression, or else an input stream. A single form will be read.
read-from-console
(read-from-console)
Attempt to read a complete lisp expression from the console.
strip-line-comments
(strip-line-comments s)
Strip blank lines and comment lines from this string s
, expected to be Lisp source.
Both these extensions can be disabled by using the --strict
command line switch.
gsp
(gsp s)
Shortcut macro - the internals of read; or, if you like, read-string. Argument s
should be a string representation of a valid Lisp expression.
READ
(READ)
(READ input)
An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. input
should be either a string representation of a LISP expression, or else an input stream. A single form will be read.
read-from-console
(read-from-console)
Attempt to read a complete lisp expression from the console. NOTE that this will only really work for S-Expressions, not M-Expressions.
strip-line-comments
(strip-line-comments s)
Strip blank lines and comment lines from this string s
, expected to be Lisp source.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.generate
Generating S-Expressions from parse trees.
+Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.generate
Generating S-Expressions from parse trees.
From Lisp 1.5 Programmers Manual, page 10
Note that I’ve retyped much of this, since copy/pasting out of PDF is less than reliable. Any typos are mine.
Quote starts:
diff --git a/docs/codox/beowulf.reader.macros.html b/docs/codox/beowulf.reader.macros.html index 5534744..3485d0e 100644 --- a/docs/codox/beowulf.reader.macros.html +++ b/docs/codox/beowulf.reader.macros.html @@ -1,3 +1,3 @@ -Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.macros
Can I implement reader macros? let’s see!
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.macros
Can I implement reader macros? let’s see!
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.parser
The actual parser, supporting both S-expression and M-expression syntax.
parse
Parse a string presented as argument into a parse tree which can then be operated upon further.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.parser
The actual parser, supporting both S-expression and M-expression syntax.
parse
Parse a string presented as argument into a parse tree which can then be operated upon further.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.simplify
Simplify parse trees. Be aware that this is very tightly coupled with the parser.
simplify
(simplify p)
(simplify p context)
Simplify this parse tree p
. If p
is an instaparse failure object, throw an ex-info
, with p
as the value of its :failure
key.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
beowulf.reader.simplify
Simplify parse trees. Be aware that this is very tightly coupled with the parser.
simplify
(simplify p)
(simplify p context)
Simplify this parse tree p
. If p
is an instaparse failure object, throw an ex-info
, with p
as the value of its :failure
key.
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
Beowulf 0.2.1-SNAPSHOT
Released under the GPL-2.0-or-later
An implementation of LISP 1.5 in Clojure.
Installation
To install, add the following dependency to your project or build file:
[beowulf "0.2.1-SNAPSHOT"]
Topics
Namespaces
beowulf.bootstrap
Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual
; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host
, be sufficient to bootstrap the full Lisp 1.5 interpreter..
Public variables and functions:
- *options*
- APPEND
- APPLY
- ASSOC
- ATOM
- ATOM?
- CAAAAR
- CAAADR
- CAAAR
- CAADAR
- CAADDR
- CAADR
- CAAR
- CADAAR
- CADADR
- CADAR
- CADDAR
- CADDDR
- CADDR
- CADR
- CAR
- CDAAAR
- CDAADR
- CDAAR
- CDADAR
- CDADDR
- CDADR
- CDAR
- CDDAAR
- CDDADR
- CDDAR
- CDDDAR
- CDDDDR
- CDDDR
- CDDR
- CDR
- CONS
- DEFINE
- EQ
- EQUAL
- EVAL
- eval-internal
- INTEROP
- interop-interpret-q-name
- MEMBER
- NILP
- NULL
- OBLIST
- oblist
- PAIRLIS
- QUOTE
- SET
- SUBLIS
- SUBST
- to-beowulf
- to-clojure
- traced-eval
- uaf
beowulf.cons-cell
The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.
Public variables and functions:
beowulf.core
Essentially, the -main
function and the bootstrap read-eval-print loop.
Public variables and functions:
beowulf.host
provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.
beowulf.read
This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.
Public variables and functions:
beowulf.reader.parser
The actual parser, supporting both S-expression and M-expression syntax.
Public variables and functions:
beowulf.reader.simplify
Simplify parse trees. Be aware that this is very tightly coupled with the parser.
Public variables and functions:
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
Beowulf 0.2.1-SNAPSHOT
Released under the GPL-2.0-or-later
An implementation of LISP 1.5 in Clojure.
Installation
To install, add the following dependency to your project or build file:
[beowulf "0.2.1-SNAPSHOT"]
Topics
Namespaces
beowulf.bootstrap
Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual
; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host
, be sufficient to bootstrap the full Lisp 1.5 interpreter..
Public variables and functions:
- *options*
- APPEND
- APPLY
- ASSOC
- ATOM
- ATOM?
- CAAAAR
- CAAADR
- CAAAR
- CAADAR
- CAADDR
- CAADR
- CAAR
- CADAAR
- CADADR
- CADAR
- CADDAR
- CADDDR
- CADDR
- CADR
- CAR
- CDAAAR
- CDAADR
- CDAAR
- CDADAR
- CDADDR
- CDADR
- CDAR
- CDDAAR
- CDDADR
- CDDAR
- CDDDAR
- CDDDDR
- CDDDR
- CDDR
- CDR
- CONS
- DEFINE
- EQ
- EQUAL
- EVAL
- eval-internal
- INTEROP
- interop-interpret-q-name
- MEMBER
- NILP
- NULL
- OBLIST
- oblist
- PAIRLIS
- QUOTE
- SET
- SUBLIS
- SUBST
- to-beowulf
- to-clojure
- traced-eval
- uaf
beowulf.cons-cell
The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.
Public variables and functions:
beowulf.core
Essentially, the -main
function and the bootstrap read-eval-print loop.
Public variables and functions:
beowulf.host
provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.
beowulf.io
Non-standard extensions to Lisp 1.5 to read and write to the filesystem.
Public variables and functions:
beowulf.read
This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.
Public variables and functions:
beowulf.reader.parser
The actual parser, supporting both S-expression and M-expression syntax.
Public variables and functions:
beowulf.reader.simplify
Simplify parse trees. Be aware that this is very tightly coupled with the parser.
Public variables and functions:
Generated by Codox
Beowulf 0.2.1-SNAPSHOT
Introduction to beowulf
+Generated by Codox
Beowulf 0.2.1-SNAPSHOT
Introduction to beowulf
TODO: write great documentation