Yesterday I shared a very minimalistic version for the 16K RAM ZX80.
I thought it could be of some interest also for the LAMBDA 8300 owners.
note this is still highly experimental, in example PROGN() does not work correctly
Campus LISP
Campus LISP
 Attachments

 clisp_lambda_16k_gfx.p
 (13.91 KiB) Downloaded 97 times

 clisp_lambda_16k.p
 (13.15 KiB) Downloaded 121 times
Last edited by stefano on Thu Aug 31, 2023 7:26 pm, edited 1 time in total.
Re: Campus LISP
What the difference between the standard and graphics version?
Re: Campus LISP
The standard version has more stack space, allowing bigger programs or in general giving the interpreter less reasons to crash than the one providing graphics
It's better to elaborate on what this CLiSP is and what it is not.
First of all, the Campus LIsP is a limited subset of the LISP language.
The reason for its existence is to teach how this kind of interpreter works and the programming basics for it, thus it is intentionally minimalistic, the LAMBDA declaration was intentionally excluded. ('lambda" is a crucial LISP keyword and we are not supporting it on the LAMBDA !)
Such dramatic simplification allows it to run it on a small computer. z88dk and a bit of crazy tricks did the rest.
By the way a 16K version in theory should't even boot!
It does at a high price, the 'atom' size is very small and the algebraic computation do easily overflow. I also reduced the (already minimal) number of predefined functions, but the missing ones can still be recreated in LISP:
; factorial, minimalistic mode example
(defun fact (n)
(cond ((< n 1)
1)
(t
(* n (fact ( n 1))))))
; print
(defun print (n) (progn (terpri) (princ n)))
; zero?
(defun zerop (n)
(eq n 0))
; greater than or equal to?
(defun >= (n1 n2)
(or (> n1 n2) (= n1 n2)))
; less than or equal to?
(defun <= (n1 n2)
(or (< n1 n2) (= n1 n2)))
; eq?
(defun = (n1 n2)
(eq n1 n2))
; increment
(defun 1+ (n)
(+ n 1))
; decrement
(defun 1 (n)
( n 1))
; remainder
(defun % (a b) ( a (* (/ a b) b)))
; sum
(defun sum (n)
(cond ((< n 1)
0)
(t
(+ n (sum ( n 1))))))
; power
(defun power (x n)
(cond ((< n 1)
1)
(t
(* x (power x ( n 1))))))
; equal
(defun equal (s1 s2)
(cond ((atom s1)
(eq s1 s2))
((not (atom s2))
(and (equal (car s1) (car s2))
(equal (cdr s1) (cdr s2))))
(t
nil)))
The idea of the turtle graphics functions was borrowed from SpecLISP, a good but buggy interpreter for the ZX Spectrum. I fixed some of the bugs on it too, but it is another story.
Besides the graphics, the syntax in Campus LIsP is very close to Common LISP (SpecLISP had a slightly different syntax, which I chose not to use here, but it's very easy to retrofit the Campus LIsP for anybody feeling nostalgic).
The available memory won't allow you very much, it's a bit like trying to type useful programs on a 1K Sinclair computer! I 'm sure you all get the point and understand it still can be fun.
SAVE and LOAD are not supported, but nowadays a snapshot in the emulator can help in freezing your environment and progress with your experiments later
It's better to elaborate on what this CLiSP is and what it is not.
First of all, the Campus LIsP is a limited subset of the LISP language.
The reason for its existence is to teach how this kind of interpreter works and the programming basics for it, thus it is intentionally minimalistic, the LAMBDA declaration was intentionally excluded. ('lambda" is a crucial LISP keyword and we are not supporting it on the LAMBDA !)
Such dramatic simplification allows it to run it on a small computer. z88dk and a bit of crazy tricks did the rest.
By the way a 16K version in theory should't even boot!
It does at a high price, the 'atom' size is very small and the algebraic computation do easily overflow. I also reduced the (already minimal) number of predefined functions, but the missing ones can still be recreated in LISP:
; factorial, minimalistic mode example
(defun fact (n)
(cond ((< n 1)
1)
(t
(* n (fact ( n 1))))))
(defun print (n) (progn (terpri) (princ n)))
; zero?
(defun zerop (n)
(eq n 0))
; greater than or equal to?
(defun >= (n1 n2)
(or (> n1 n2) (= n1 n2)))
; less than or equal to?
(defun <= (n1 n2)
(or (< n1 n2) (= n1 n2)))
; eq?
(defun = (n1 n2)
(eq n1 n2))
; increment
(defun 1+ (n)
(+ n 1))
; decrement
(defun 1 (n)
( n 1))
; remainder
(defun % (a b) ( a (* (/ a b) b)))
; sum
(defun sum (n)
(cond ((< n 1)
0)
(t
(+ n (sum ( n 1))))))
; power
(defun power (x n)
(cond ((< n 1)
1)
(t
(* x (power x ( n 1))))))
; equal
(defun equal (s1 s2)
(cond ((atom s1)
(eq s1 s2))
((not (atom s2))
(and (equal (car s1) (car s2))
(equal (cdr s1) (cdr s2))))
(t
nil)))
The idea of the turtle graphics functions was borrowed from SpecLISP, a good but buggy interpreter for the ZX Spectrum. I fixed some of the bugs on it too, but it is another story.
Besides the graphics, the syntax in Campus LIsP is very close to Common LISP (SpecLISP had a slightly different syntax, which I chose not to use here, but it's very easy to retrofit the Campus LIsP for anybody feeling nostalgic).
The available memory won't allow you very much, it's a bit like trying to type useful programs on a 1K Sinclair computer! I 'm sure you all get the point and understand it still can be fun.
SAVE and LOAD are not supported, but nowadays a snapshot in the emulator can help in freezing your environment and progress with your experiments later
Re: Campus LISP
This are the embedded functions:
=======================================
SpecLISP turtle graphics
 (cls)
Clears screen and reposition turtle
 (penu)
Pen up: turtle will move without drawing
 (pend)
Pen down: turtle will draw a line when moving
 (left n)
Turn left, n degrees
 (right n)
Turn right, n degrees
 (fwd n)
Move forward, n steps (pixels)
=======================================
CAPMUS LIsP (Lemon Version)
Language Specification
by Hirotsugu Kakugawa
1. The Interpreter
 dynamic binding
 with garbage collector
2. Syntax
 sexpression
 a semicolon (;) begins comment (until line end)
3. Data Type
 nil (boolean false / empty list)
 t (boolean true)
 integer
 symbol
 cons cell
 endoffile
4. Lisp Functions
 (read)
Read an sexpression from terminal.
 (eval S)
Evaluate an sexpression S.
 (print S)
print an s expression S on terminal
 (terpri)
Print newline.
 (gc)
Collect garbages.
 (quit)
Finish the interpreter.
 (defun F (A1 A2 ...Ak) S1 S2 ... Sn)
Define a function F whose body is a sequence of expressions
S1 S2 ... Sn with formal parameters A1 A2 ... Ak. Value of
Sn is the result of F. Special form.
 (quote S1 S2 ... Sn)
Suppress evaluation of a list of (S1 S2 ... Sn). Special form.
 'S
Same as (quote S)
 (setq V S)
Assign evaluated value of S to symbol V. Special form.
 (eq S1 S2)
Return t if and only if S1 is identical to S2.
 (cons S1 S2)
Construct a cons cell with S1 for Car part and S2 for Cdr part.
 (car S)
Return Car part of cons cell S.
 (cdr S)
Return Cdr part of cons cell S.
 (cond (P1 S11 S12 ...) (P2 S21 S22 ...) ... (Pn Sn1 Sn2 ...))
Conditional expression.
 (progn S1 S2 ... Sn)
Sequantially evaluate S1, S2, ... Sn. Return evaluated value of Sn.
 (rplaca S1 S2)
Replace Car part of cons cell S1 with S2.
 (rplacd S1 S2)
Replace Cdr part of cons cell S1 with S2.
 (null S)
Return t if S is nil; otherwise nil.
 (numberp S)
Return t if S is an integer; otherwise nil.
 (or S1 S2 ... )
Evaluate S1, S2, ... as long as evaluation result of Si is nil.
Special form.
 (not S)
Return t if S is nil; otherwise return nil.
 (list S1 S2 ...)
Return a list (S1 S2 ...)
 (+ n1 n2 ...)
Return an integer n1 + n2 + ...
 ( n)
Return an integer n.
 ( n1 n2 ...)
Return an integer n1  n2  ...
 (* n1 n2 ...)
Return an integer n1 * n2 * ...
 (/ n1 n2 ...)
Return an integer n1 / n2 / ...
 (/ n)
Return an integer 1/n.
 (> n1 n2)
Return t if n1 > n2; otherwise nil.
=======================================
=======================================
SpecLISP turtle graphics
 (cls)
Clears screen and reposition turtle
 (penu)
Pen up: turtle will move without drawing
 (pend)
Pen down: turtle will draw a line when moving
 (left n)
Turn left, n degrees
 (right n)
Turn right, n degrees
 (fwd n)
Move forward, n steps (pixels)
=======================================
CAPMUS LIsP (Lemon Version)
Language Specification
by Hirotsugu Kakugawa
1. The Interpreter
 dynamic binding
 with garbage collector
2. Syntax
 sexpression
 a semicolon (;) begins comment (until line end)
3. Data Type
 nil (boolean false / empty list)
 t (boolean true)
 integer
 symbol
 cons cell
 endoffile
4. Lisp Functions
 (read)
Read an sexpression from terminal.
 (eval S)
Evaluate an sexpression S.
 (print S)
print an s expression S on terminal
 (terpri)
Print newline.
 (gc)
Collect garbages.
 (quit)
Finish the interpreter.
 (defun F (A1 A2 ...Ak) S1 S2 ... Sn)
Define a function F whose body is a sequence of expressions
S1 S2 ... Sn with formal parameters A1 A2 ... Ak. Value of
Sn is the result of F. Special form.
 (quote S1 S2 ... Sn)
Suppress evaluation of a list of (S1 S2 ... Sn). Special form.
 'S
Same as (quote S)
 (setq V S)
Assign evaluated value of S to symbol V. Special form.
 (eq S1 S2)
Return t if and only if S1 is identical to S2.
 (cons S1 S2)
Construct a cons cell with S1 for Car part and S2 for Cdr part.
 (car S)
Return Car part of cons cell S.
 (cdr S)
Return Cdr part of cons cell S.
 (cond (P1 S11 S12 ...) (P2 S21 S22 ...) ... (Pn Sn1 Sn2 ...))
Conditional expression.
 (progn S1 S2 ... Sn)
Sequantially evaluate S1, S2, ... Sn. Return evaluated value of Sn.
 (rplaca S1 S2)
Replace Car part of cons cell S1 with S2.
 (rplacd S1 S2)
Replace Cdr part of cons cell S1 with S2.
 (null S)
Return t if S is nil; otherwise nil.
 (numberp S)
Return t if S is an integer; otherwise nil.
 (or S1 S2 ... )
Evaluate S1, S2, ... as long as evaluation result of Si is nil.
Special form.
 (not S)
Return t if S is nil; otherwise return nil.
 (list S1 S2 ...)
Return a list (S1 S2 ...)
 (+ n1 n2 ...)
Return an integer n1 + n2 + ...
 ( n)
Return an integer n.
 ( n1 n2 ...)
Return an integer n1  n2  ...
 (* n1 n2 ...)
Return an integer n1 * n2 * ...
 (/ n1 n2 ...)
Return an integer n1 / n2 / ...
 (/ n)
Return an integer 1/n.
 (> n1 n2)
Return t if n1 > n2; otherwise nil.
=======================================
Re: Campus LISP
The mentioned limits