Rainer Joswig <joswig@lisp.de> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) wrote:
| > Well, there's always Lisp500 <http://www.modeemi.fi/~chery/lisp500/>. ;-}
| > 88 initial defined symbols, float-only arithmetic, 500 LOC of *very*
| > dense C! Then loading "init500.lisp" adds another 761 symbols,
| > fleshing out the CL compatibility a *lot*.
|
| ... How readable is the C part of Lisp500?
+---------------
Almost totally *unreadable*, actually! ;-} It's full of
"obfuscated C"-style compressions to keep the LOC small, e.g.:
...
typedef int lval;
lval *o2c(lval o) { return (lval*)(o - 1); }
...
#define TRUE symi[1].sym
#define T g[-2]
#define U g[-3]
#define V g[-4]
#define W g[-5]
#define NF(n) lval *g; g=f+n+3; f[1]=0; g[-1]=(n<<5)|16; *g=*f;
#define E *f
#define NE *g
lval car(lval c) { return (c & 3) == 1 ? o2c(c)[0] : 0; }
lval cdr(lval c) { return (c & 3) == 1 ? o2c(c)[1] : 0; }
...
lval eval_if(lval *f, lval ex) { return evca(f, evca(f,ex)?cdr(ex):cddr(ex)); }
...
lval eval_unwind_protect(lval *f, lval ex) { NF(1) T=0;
T=ma(g,2,52,E,cdr(ex)); dyns = cons(g, T, dyns); T = evca(g, ex);
T = rvalues(g, T); unwind(g, cdr(dyns)); return mvalues(T); }
lval eval_if(lval *f, lval ex) {
return evca(f, evca(f,ex)?cdr(ex):cddr(ex)); }
lval eval_multiple_value_call(lval *f, lval ex) { lval *g=f+3; lval l;
f[1]=evca(f, ex); for (ex=cdr(ex); ex; ex=cdr(ex)) { *g=*f;
g[-1]=((g-f-3)<<5)|16; for (l = rvalues(g, evca(g, ex)); l; l = cdr(l)) {
g[-1] = car(l); g++; }} xvalues = 8; return call(f, f[1], g-f-3); }
lval eval_multiple_value_prog1(lval *f, lval ex) { NF(1) T=0;
T = evca(g, ex); T = rvalues(g, T); eval_body(g, cdr(ex));
return mvalues(T); }
...
+---------------
| I think it would be more useful to have a small, but readable
| implementation, than having a very small but difficult to read
| implementation.
+---------------
I agree. Which is why even though my QDL is (currently) *much* less
featureful than Lisp500, there might be some point in making it available,
since IMHO it's much more readable. E.g., compare the above "one-liner"
"eval_if()" with the version in QDL-0.4:
lispobj
eval_if(lispobj rest, lispobj env)
{
lispobj bool;
GC_PROTECT_BUF(2);
GC_PROTECT_2(rest, env);
bool = eval(car(rest), env);
GC_UNPROTECT;
if (bool != NIL)
return eval(cadr(rest), env);
else
return eval(caddr(rest), env);
}
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607