Functional Programming Language.
Everything in "s-expressions" -- symbolic expressions
All uppercase letters
S-Expressions
Atoms
Integer or symbolic identifier
e.g. 42 XYZ T NIL
T -- true
NIL -- false
Non-atomic
i.e. Binary trees
- Children can be atom or non-atom
- Left-half: car
- Right-half: cdr
e.g. (42.NIL) (NIL.42) (42.(NIL.42)) ((NIL.42).42)
How are s-expressions stored and used?
- Atoms: one word of memory storing the int value or name of the atom; accessed by a pointer to that memory loaction
- Non-atoms: one block of two words of memory storing the car & cdr of the non-atom. Accessed by a pointer to the block of two words.
- car: content of the address register -- the left child
- cdr: content of the displacement register -- the right child
Primary Functions
- CAR -- return car of a non-atom, error if param is an atom
- CDR -- return cdr of a non-atom, error if param is an atom
- CONS -- combine two atom/non-atom into one non-atom, e.g. CONS[se1, se2] = (se1 . se2)
-
Grab a two-word block of memory from the heap
-
Copy se1 into the first word
-
Copy se2 into the second word
-
Return a pointer to the two-word block of memory
- EQ -- compare two atoms, return T if the same, NIL otherwise
-
EQ [ ae1, ae2 ] -- ae1, ae2 must both be atomic, otherwise error
-
Compare pointers but not values
-
-
ATOM [se] -- T if se is atomic, NIL otherwise
-
NULL [se] -- T if se is NIL, NIL otherwise.
Customized Functions
-
cadaar[se] = car[cdr[car[car[se]]]] -- [se] is the param decl instead of an actual variable
** Note, everything in lisp should be s-expressions, but the above is not written in that format. Therefore, the above is actually a pseudo code, and it has to be converted into formal lisp.