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 depth)

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.

CAAAAR

macro

(CAAAAR x)

TODO: write docs

CAAADR

macro

(CAAADR x)

TODO: write docs

CAAAR

macro

(CAAAR x)

TODO: write docs

CAADAR

macro

(CAADAR x)

TODO: write docs

CAADDR

macro

(CAADDR x)

TODO: write docs

CAADR

macro

(CAADR x)

TODO: write docs

CAAR

macro

(CAAR x)

TODO: write docs

CADAAR

macro

(CADAAR x)

TODO: write docs

CADADR

macro

(CADADR x)

TODO: write docs

CADAR

macro

(CADAR x)

TODO: write docs

CADDAR

macro

(CADDAR x)

TODO: write docs

CADDDR

macro

(CADDDR x)

TODO: write docs

CADDR

macro

(CADDR x)

TODO: write docs

CADR

macro

(CADR x)

TODO: write docs

CDAAAR

macro

(CDAAAR x)

TODO: write docs

CDAADR

macro

(CDAADR x)

TODO: write docs

CDAAR

macro

(CDAAR x)

TODO: write docs

CDADAR

macro

(CDADAR x)

TODO: write docs

CDADDR

macro

(CDADDR x)

TODO: write docs

CDADR

macro

(CDADR x)

TODO: write docs

CDAR

macro

(CDAR x)

TODO: write docs

CDDAAR

macro

(CDDAAR x)

TODO: write docs

CDDADR

macro

(CDDADR x)

TODO: write docs

CDDAR

macro

(CDDAR x)

TODO: write docs

CDDDAR

macro

(CDDDAR x)

TODO: write docs

CDDDDR

macro

(CDDDDR x)

TODO: write docs

CDDDR

macro

(CDDDR x)

TODO: write docs

CDDR

macro

(CDDR x)

TODO: write docs

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))

EQ

(EQ x y)

Returns T if and only if both x and y are bound to the same atom, else NIL.

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 depth)

Evaluate this expr and return the result. If environment is not passed, it defaults to the current value of the global object list. The depth argument is part of the tracing system and should not be set by user code.

All args are assumed to be numbers, 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

  1. a symbol bound in the host environment to a function; or
  2. 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.

lax?

(lax? symbol)

Are we in lax mode? If so. return true; is not, throw an exception with this symbol.

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.

NILP

macro

(NILP x)

Not part of LISP 1.5: T if o is NIL, else NIL.

NULL

macro

(NULL x)

Returns T if and only if the argument x is bound to NIL; else F.

OBLIST

(OBLIST)

Return a list of the symbols currently bound on the object list.

NOTE THAT in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I’m not sure of the semantics of this.

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.

QUOTE

macro

(QUOTE f)

Quote, but in upper case for LISP 1.5

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 us are atomic, and y is any S-expression. What SUBLIS does, is to treat the us as variables when they occur in y, and to SUBSTitute the corresponding vs 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.

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