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)
(APPLY function args environment)
Despatcher for APPLY, selects beteen traced-apply
and apply-internal
based on the value of :trace
in *options*
. Apply this function
to these arguments
and return the result. If environment
is not passed, if defaults to the current value of the global object list.
apply-internal
(apply-internal function args environment)
Internal guts of both APPLY
and traced-apply
. Apply this function
to these arguments
in this environment
and return the result.
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.
DEFINE
(DEFINE args)
Bootstrap-only version of DEFINE
which, post boostrap, can be overwritten in LISP.
The single argument to DEFINE
should be an assoc list which should be nconc’ed onto the front of the oblist. Broadly, (SETQ OBLIST (NCONC ARG1 OBLIST))
EQUAL
(EQUAL x y)
This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate EQ
is defined only for atomic arguments.) The definition of EQUAL
is an example of a conditional expression inside a conditional expression.
NOTE: returns F
on failure, not NIL
EVAL
(EVAL expr)
(EVAL expr env)
Despatcher for EVAL, selects beteen traced-eval
and eval-internal
based on the value of :trace
in *options*
. Evaluate this expr
and return the result. If environment
is not passed, if defaults to the current value of the global object list. All args are assumed to be symbols or beowulf.cons-cell/ConsCell
objects.
INTEROP
(INTEROP fn-symbol args)
Clojure (or other host environment) interoperation API. fn-symbol
is expected to be either
- a symbol bound in the host environment to a function; or
- a sequence (list) of symbols forming a qualified path name bound to a function.
Lower case characters cannot normally be represented in Lisp 1.5, so both the upper case and lower case variants of fn-symbol
will be tried. If the function you’re looking for has a mixed case name, that is not currently accessible.
args
is expected to be a Lisp 1.5 list of arguments to be passed to that function. Return value must be something acceptable to Lisp 1.5, so either a symbol, a number, or a Lisp 1.5 list.
If fn-symbol
is not found (even when cast to lower case), or is not a function, or the value returned cannot be represented in Lisp 1.5, an exception is thrown with :cause
bound to :interop
and :detail
set to a value representing the actual problem.
interop-interpret-q-name
(interop-interpret-q-name l)
For interoperation with Clojure, it will often be necessary to pass qualified names that are not representable in Lisp 1.5. This function takes a sequence in the form (PART PART PART... NAME)
and returns a symbol in the form PART.PART.PART/NAME
. This symbol will then be tried in both that form and lower-cased. Names with hyphens or underscores cannot be represented with this scheme.
MEMBER
(MEMBER x y)
This predicate is true if the S-expression x
occurs among the elements of the list y
.
All args are assumed to be symbols or beowulf.cons-cell/ConsCell
objects. See page 11 of the Lisp 1.5 Programmers Manual.
OBLIST
(OBLIST)
Not certain whether or not this is part of LISP 1.5; adapted from PSL. return the current value of the object list. Note that in PSL this function returns a list of the symbols bound, not the whole association list.
PAIRLIS
(PAIRLIS x y a)
This function gives the list of pairs of corresponding elements of the lists x
and y
, and APPENDs this to the list a
. The resultant list of pairs, which is like a table with two columns, is called an association list.
Eessentially, it builds the environment on the stack, implementing shallow binding.
All args are assumed to be beowulf.cons-cell/ConsCell
objects. See page 12 of the Lisp 1.5 Programmers Manual.
SET
(SET symbol val)
Implementation of SET in Clojure. Add to the oblist
a binding of the value of var
to the value of val
. NOTE WELL: this is not SETQ!
SUBLIS
(SUBLIS a y)
Here a
is assumed to be an association list of the form ((ul . vl)...(un . vn))
, where the u
s are atomic, and y
is any S-expression. What SUBLIS
does, is to treat the u
s as variables when they occur in y
, and to SUBSTitute the corresponding v
s from the pair list.
My interpretation is that this is variable binding in the stack frame.
All args are assumed to be beowulf.cons-cell/ConsCell
objects. See page 12 of the Lisp 1.5 Programmers Manual.
SUBST
(SUBST x y z)
This function gives the result of substituting the S-expression x
for all occurrences of the atomic symbol y
in the S-expression z
.
to-beowulf
(to-beowulf o)
Return a beowulf-native representation of the Clojure object o
. Numbers and symbols are unaffected. Collections have to be converted; strings must be converted to symbols.
to-clojure
(to-clojure l)
If l is a beowulf.cons_cell.ConsCell
, return a Clojure list having the same members in the same order.
traced-apply
(traced-apply & args__3196__auto__)
Traced wrapper for internal-apply
, q.v. Apply this function
to these arguments
in this environment
and return the result.
traced-eval
(traced-eval & args__3196__auto__)
Essentially, identical to EVAL except traced.
uaf
(uaf l path)
Universal access function; l
is expected to be an arbitrary LISP list, path
a (clojure) list of the characters a
and d
. Intended to make declaring all those fiddly #'c[ad]+r'
functions a bit easier