Spectrum 2.0

Review of 'LISP Interpreter'

Rating:4 User: smartgenes

Francisco Leon's reverse-engineered Spanish instructions, translated into English:

LISP 1.3

By way of introduction:

The Lisp programming language was born in 1960, its name derives from 'list processing', ie 'list processing', but also can be understood as 'list programming' or 'programming with lists'. It was designed for symbolic data processing and any other field of AI (artificial intelligence).

Lisp expressions work with 'S', ie symbolic expressions of indefinite length and a type of tree branch structure. Invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT), it is the second oldest language in the world of programming; the first is the language Fortran. Over time a family of Lisp dialects was formed which shared a very special syntax.

Currently the most used dialects are Common Lisp and Scheme. The first version most widely disseminated was LISP 1.5, followed by Stanford LISP 1.6. The version on the Spectrum, Lisp 1.3, can be considered a sub set of the Stanford LISP with which it shares a lot, as much in its names of primitives as its syntax; but it is a limited sub-set in comparison. Spec-lisp instead has a type of turtle graphics commands. No known version of Lisp has this feature, excepting only Emac-Lisp for the Macintosh machines.

For the creation of this manual, since I do not own the original, nor have I found it, I was forced to use the information in the following texts:
The Elements of Artificial Intelligence (An Introduction using LISP), LISP 1.5 Programmers Manual, Sailon-28.6, On Lisp, various web pages and book 7 of Applied Informatics: Intelligent Games within Microcomputers.

To begin just Load "" and once done, the following message appears:

SpecLisp 1.3
© 1983 Serious Software
Made in England
*

Now Lisp is ready and is waiting for you enter something.

Syntax: (primitive [argument (s)])

Lisp primitives:
Add1, And, Apply, Atom, Border, Car, Cadr, Cdr, Cddr, Cls, Cond, Cons, Cset,
Csetq, De, Diff, Div, Eq, Equal, Eval, Exit, Function, Fwd, Get, Greaterp, Gc,
Ink, Left, Lessp, List, Load, Member, Minusp, Nill, Not, Null, Numberp, Oblist,
Or, Paper, Pch, Pend, Penu, Plus, Print, Progn, Prt, Putprop, Quote, Right, Read,
Rem, Remprop, Reverse, Rnd, Rplaca, Rplacd, Save, Set, setq, Stack, Sub1, Times,
Trace, Verify, While, Zerop.

It accepts as valid the following symbols:
;? @: <> ^ _ = and £.

Dan illegal numeric format error the following symbols:
/ '! "* => $ <= # and %.

There is no way to type the following symbols without EXT:
~ | [{}] © y \.

The comma is also accepted as a separator of elements, like space.
Example: '1,2,3 'is equivalent to '1 2 3'.

No cursor keys are supported, so it is impossible to correct or edit a line
of text without erasing with DELETE to get to the letter you want to correct.
It only supports cursor left unless you provoke the action [CANCEL].
- Hide quoted text -

A Lisp list is made up of: values 'apval' expressions 'expr', subroutines
'Subr', lambda functions, and pname (names of primitives).

Evaluators:

EVAL (evaluate-)
syntax: (eval x)
Simply run it executes xy if valid, otherwise it will fail.
Examples: (eval 1) - is accepted but:
(eval (1 3 4)) - seeks to evaluate the first element of the list and generates the error '1 IS NOT A FUNCTION' instead:
(eval (car (1 3)) - executes the function car and evaluates its syntax.

QUOTE
syntax: (quote x)
special form that permits you to enter an expression x without Lisp evaluating it.
Quote only supports an argument that is an atom, number or list.
Example: (eval (quote (1 3 4))) - evaluates and returns as valid (1 3 4)
Note:
Other versions of Lisp accept the abbreviated form 'x; this is not supported by Spectrum Lisp.

SET
syntax: (set v x)
where v = a symbol and x = the value to set. Set always evaluates v.
It is equivalent to LET v = x in Basic.
Example: (set var 1) - will give the error 'var IS AN UNBOUND VARIABLE' but:
(Set (quote var) 1) - will be allowed and give var = 1.

SETQ
syntax: (setq v x)
equals (set (quote v) x)
Examples: (setq xs (quote alpha)) - creates the variable xs with value 'alpha'
(Set xs 65) - because xs already contains alpha, set creates the variable alpha = 65.
(Setq xs 65) - rewrites xs instead and converts it to a number.

APPLY
syntax: (apply f la)
Applies a function f to an argument la.
Example: (apply plus 2 3) - gives an error of incorrect arguments.
(Apply (quote plus) (pend 2 3)) - executes the function and returns 5.

FUNCTION
syntax: (function s)
where s = a function defined by the user.
returns a list containing all the data that makes up the function created by the user.
Example: (function fact) - the function must exist, otherwise it will give an error.

Manipulating lists structures:

CAR
syntax: (car l)
returns the first item in the list l. Returns an error if l is not in a list.
Car means "Contents of the Address part of Register number".
It is equivalent to First in the language LOGO.
Examples: (car (1 2 3)) - returns an error but:
(Car (quote (1 2 3))) and
(Car (pend 1 2 3)) are ok. They result in 1.

CDR
syntax: (cdr l)
Decreases and generates a list containing all the elements of 'l' minus the first.
Cdr means "Contents of the Decrement part of Register number".
Equivalent to BF (butfirst) from LOGO.
Example: (cdr (quote (1 2 3 4))) - returns (2 3 4) as a result.

CADR
Syntax: (cadr x)
is equivalent to (car (cdr x))
Example: (cadr (pend 1 2 3 4 5)) - gives 2 as a result.

CDDR
Syntax: (cddr x)
is equivalent to (cdr (cdr x))
Example: (cddr (pend 1 2 3 4 5)) - gives (3 4 5) as a result.

CONS (construct)
syntax: (cons n l)
generates a list, adding n to the top of the list l given.
Examples: (cons 1 2) - is accepted and gives 1.2 in response, but:
(Cons 1 2 3 4) returns an error as it supports only two arguments. Instead:
(Cons 1 (cons 2 (cons 3 (cons 4 nil)))) - returns (1 2 3 4)

LIST
Syntax: (list l)
generates a list joining the lists that are passed as an argument l.
example: (list (quote (1 3)) (quote (4 5 6)) (quote alpha))
generates the list: ((1 3) (4 5 6) alpha)

RPLACA
Syntax: (rplaca x y)
returns x but replaces the first element with y. X is modified as a result
directly into memory.
Example: lists are a = (1 2 3 4) and b = (6 7 8 9)
(rplaca to b) - for a = ((6 7 8 9) 2 3 4)
is equivalent to: (setq a (cons b (cdr a)))

RPLACD
Syntax: (rplacd x y)
Similar to rplaca. Modifies x replacing the decrement of x by y.
Example: (rplacd b a) - for b = (6 1 2 3 4)
This is equivalent to: (setq b (cons (car b)))

REVERSE
Syntax: (reverse ls)
puts in reverse order all the components from a list ls.
Example: (reverse (pend 1 3 5 7)) - returns (7 5 3 1)

Arithmetic functions:

PLUS
syntax: (plus x y)
adds two values. A third value causes an error message.
(+ X1 ... xn) is supported by other Lisps, but not by Spec-lisp.

DIFF (difference)
Syntax: (diff x y)
subtracts two values giving their difference.
(- X1 ... xn) is supported by other Lisps, but not by Spec-lisp.

TIMES
syntax (x times y)
allows the multiplication of two values.
(* X1 ... xn) is supported by other Lisps, but not by Spec-lisp.

DIV
syntax: (div x y)
does integer division of two values.
(/ X1 ... xn) is supported by other Lisps, but not by Spec-lisp.

REM (remainder)
syntax: (rem x y)
Equivalent to the operator MOD in other languages and gives the rest of the division as integer.

ADD1
Syntax: (add1 x)
Add or sum 1 to the value x.
Equivalent to (1 + x) in other Lisps.

SUB1
Syntax: (sub1 x)
Subtract or take away 1 from the value x
Equivalent to (1 - x) in other Lisps.

Predicates:

ATOM
syntax: (atom x)
checks whether the argument x is, or is not an atom.

ZEROP
Syntax: (zerop x)
checks if x is zero.

Numberp
Syntax: (numberp x)
checks whether the argument x is, or is not a number.

MINUSP
Syntax: (minusp x)
Gives T if x is a negative number.
[Edit: T means True]

GREATERP
Syntax: (greaterp x y)
Returns T if x is greater than y. In case of the contrary it gives Nil.
Equivalent to (> x y) of other Lisps.

LESSP
Syntax: (lessp x y)
Returns T if x is less than y. Nil or no.
Equivalent to (<x y) of other Lisps.

NULL
syntax: (null x)
Gives T if x is an empty list (). Nil for any other case.

EQ
Syntax: (eq x y)
As EQUAL. Gives T, but only if 'x' and 'y' are literal atoms. Gives Nil
if data or numbers are not atomic.
Examples: (eq 1 1) - returns nil.
(Eq ab) - gives error if a and b are not previously defined atoms.
(Eq (alpha quote) (quote alpha)) - returns T.

EQUAL
syntax: (equal x y)
Returns T if x is equal to y, regardless of whether it is an atom or a number.
Equivalent to (= x y) of other Lisps. Other versions however limit '=' to a numeric value, giving an error with any other data.

MEMBER
syntax: (member x ls)
Checks if the atom x belongs in the list ls. Returns T in case of itself being a member, and Nil if not.

Logical operators:

NOT
Syntax: (not x)
negates the argument x.

AND
syntax: (and x y)
Returns T if both arguments are true, otherwise Nil.

OR
syntax: (or x y)
Returns T if at least one of the arguments is true.

Control:

COND (condition)
syntax: (cond (x1 y1)(x2 y2) ... (xx yy))
where x = the condition to evaluate, y = the action to take or result to give.
The arguments of cond are called clauses and consist of lists of two elements.
Example: (cond (nil 1)(t 2)(t 3)) - gives 2 as a result.
(cond ((read)(print 1))((read)(print 2))) - prints 1 or 2, or even both,
depending on what the user enters, if it is () for both, it doesn`t return anything.

PROGN (progression)
syntax: (progn [n])
Accepts n arguments and returns the value of the final assessment after all evaluations.
Gives Nil if you have no argument. The first argument must be a symbol.
Example: (progn (x)(setq x 10)(add1 4)) - gives 5, the value of the last expression.
(Progn nil 1 (print (quote No))
(print (quote local))
(Setq x (add1 4))) - executes print and returns 5, but ignores 'setq x' and will not give a value.

WHILE
syntax: (while c (a1...ax))
where c = the condition to evaluate, a = the action to take.
performs x actions while the given condition is met.
Example: (while (read)(print (quote ok?))) - terminates upon typing ()

DE (define)
syntax (de nf(p1...px)(a1)(a2)...(ax))
where:
nf = name of function or procedure to define
p = parameter(s)
a = action to perform
allows the definition of new procedures or functions to be added to the
original primitive library of Lisp and will treat and invoke them in the same way.
Equivalent to (defun ...) of other Lisps.
Example: a recursive factorial function.
(de factorial (n)
(cond ((equal n 0) 1)
(t (times n (factorial (diff n 1)))) ))

-Defining properties:
Lisp offers the possibility of creating associative lists, which consist of lists of
lists, one of which is the property, while the other is the data associated with that property.

CSET
syntax: (cset v x)
as set, but for constant values and in some versions of Lisp it is used to
add a value x to a list of properties v. Cset always evaluates its arguments.

CSETQ
syntax: (csetq v x)
equivalent to (cset (quote v)x).
A constant created by cset/csetq which cannot be modified by set or setq, only
by another order of cset/csetq. A set variable may instead be modified by cset.
Example: (csetq car (quote b)) - initializes the list of properties with any initial data, in this case: b.

PUTPROP
syntax: (putprop n w p)
where n = name of the symbol or list of the properties
w = the element to add
p = the name of the property to create
adds an element w at the list of properties, and if there is already one in existence, replaces it.
Example: (putprop car (quote green)(quote colour))
(putprop car (quote seat)(quote make))
(putprop car 127 (quote type))
this gives a 'car' the properties: (green) (make seat) and (type 127).
In other Lisps instead, the syntax is (putprop 'car 'colour 'green).
Note: other versions of Lisp allow the entry of data in the following way:
(Setq car '((colour green)(make seat)(Type 127)))

GET
syntax: (get n p)
searches and displays the property 'p' in the list of properties 'n'. Gives nil if none, or if so it types a nonexistent property.
Examples: (get car (quote colour)) - returns 'green', but:
(Get car (quote tyre)) - will give nil if it has nothing added before with putprop.
Note: Some Lisps lack the primitive Putprop but have instead:
(Setf (get 'x 'w)y)

REMPROP
syntax: (remprop n p)
removes a property p from a list of properties n.
Example: (remprop car (quote type)) - gives t if the property exists, nil if not.

Input/Output:

READ
syntax: (read)
Lisp waits for a data input from the keyboard and then ENTER.

PRINT
syntax: (print x)
evaluates the argument 'x' and prints it on a separate line.
Other versions support terpri, prin1 and princ, which are non-existent in
Spec-lisp.

PRT
syntax: (prt)
does all that is written; appears on the printer instead of the screen,
until you type "(exit)".

SAVE
syntax: (save n)
Saves information onto cassette under the name n.

LOAD
syntax: (load [n])
Programs loaded into memory are saved onto cassette.
If not given a name, it loads the first file found.

VERIFY
syntax: (verify [n])
verifies that the data is correctly saved comparing it with what exists
in RAM.

Other commands and functions:

TRACE
syntax: (trace [x])
A utility 'debugger'. Helps to debug functions that you define,
allowing monitoring of its implementation step by step.
The first trace is typed activates the tracer, do take another trace to disable
activity.

NILL
syntax: (nill)
Lisp does not support nill as a direct function or order, but nill exists.

GC (Garbage collector)
syntax: (ga)
free working space for variables, procedures and execution of
programs. Equivalent to Recycle in LOGO.

OBLIST
syntax: (oblist)
displays a list of all the reserved words in LISP, plus their
addresses in memory. It also shows the variables and functions that you create.

EXIT
syntax: (exit)
Stops any evaluation which is in course.

RND
syntax: (rnd)
gives a random value of integer type.

PCH
syntax: (pch x)
prints the ascii code corresponding to x when used directly. Returns x.
Equivalent to the function (tyo x) in other Lisps.

STACK
syntax: (stack x)
where x = a position in memory.
Displays the message that appears when loading Lisp for the first time after
clearing the display and all procedures and variables that exist in memory.

Color and turtle graphics:

CLS
syntax: (cls)
clears the screen like the CLS of Basic.

PAPER
Syntax: (paper x)
where x = a value from 0 to 7 for colour, 8 transparency, and 9 contrast.
Gives colour at the bottom of the screen.

INK
Syntax: (ink x)
sets the color of the ink in the foreground.

BORDER
syntax: (border x)
sets the outline color of the screen, as its equivalent in Basic.

FWD (forward)
syntax: (fwd x)
where x = a numerical argument, either positive or negative.
Returns x. Makes a drawing pen advance or go backwards (+/-)x steps.
The starting point is the same as the Spectrum. (fwd 50) from that point, is equal
to the following in Basic: DRAW 0,50. Fwd is like how FD in LOGO uses relative coord.
instead of absolute coordinates. Requires Left and right to turn its course.

LEFT
Syntax: (left x)
where x = a positive integer taken as angle between 0 and 360.
Returns x. It gives the drawing pen a turn towards the left.

RIGHT
Syntax: (right x)
As LEFT, but turning to the right. Also returns x.

PENU
syntax: (penu [x])
Moves the drawing pen up, and returns the list x given as an argument.
No arguments gives nil. Must have an argument to activate.
Example> (penu 1) - Fwd and does not draw anything.

PEND
syntax: (pend [x])
moves drawing pen down and generates a list x as penu.
Without arguments returns nil. As penu, pend also needs at least one argument.
Example> (pend 1) - allows a Fwd draw.
(Progn 1 (cls)(pend 1)(right 45)(fwd 100)) - draws a diagonal.
(Progn 1 (cls)(penu 1)(right 45)(fwd 100)) - moves the cursor without drawing.
Note: Since penu & pend return the arguments as lists it can be used in the same format as a
quote in the vast majority of cases. Eg:
(pend friend of mine) is equivalent to (quote (my friend)).

Error messages:

PNAME NOT FOUND PROPERTY - property pname not found
ATOM OR - atom or ...
ILLEGAL NUMBER FORMAT - illegal numeric format
FOUND - ... found
'(' EXPECTED - expected a '('
ARITHMETIC OVERFLOW - has given or calculated a value outside the range of (+/-)32767
IS NOT A FUNCTION - ... not a function
ARGUMENTS ARE INCORRECT - the arguments are incorrect
CAN NOT TAKE CAR OF - Cannot make a car of ...
CDR CAN TAKE OF - Cannot make a cdr ...
IS NOT SYMBOLIC - ... not symbolic. It occurs whenever the argument does not satisfy the syntax.
IS AN UNBOUND VARIABLE - ... not a variable or recognised value
IS NOT A NUMBER - ... not a number
[WAITING FOR GARBAGE COLLECTOR] - [waiting for the recycling of garbage]
[DELETE ATOMS TO FREE MEMORY] - [removing atoms to free memory]
[EXIT] - [Exit]
IS NOT A FILE NAME - ... not a file name
[CANCEL] - [Cancel]
[WAITING FOR COMPACTER] - [waiting for compaction]
IS TOO LARGE AN ANGLE - ... is too great an angle

Francisco Leon (Spanish)
zx_if1@hotmail.com