Skip to content

Commit 8970673

Browse files
committed
varius bugfix and setq and new macros
- setq, and fix bug in primeval...
1 parent 5c5bbf3 commit 8970673

File tree

1 file changed

+96
-11
lines changed

1 file changed

+96
-11
lines changed

lisp.c

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ lisp primapply(lisp ff, lisp args, lisp env, lisp all) {
441441
int n = ATTR(prim, ff, n);
442442
int an = abs(n);
443443

444+
// these special cases are redundant, can be done at general solution
444445
if (n == 2) { // eq/plus etc
445446
lisp (*fp)(lisp,lisp) = ATTR(prim, ff, f);
446447
return (*fp)(eval(car(args), env), eval(car(cdr(args)), env));
@@ -462,11 +463,11 @@ lisp primapply(lisp ff, lisp args, lisp env, lisp all) {
462463
return (*fp)(env, args, all);
463464
}
464465
// don't do evalist, but allocate array, better for GC
465-
if (an > 0 && an <= 4) {
466+
if (1 && an > 0 && an <= 4) {
466467
if (n < 0) an++; // add one for neval and initial env
467468
lisp argv[an];
468469
int i;
469-
for(i = 0; i < n; i++) {
470+
for(i = 0; i < an; i++) {
470471
// if noeval, put env first
471472
if (i == 0 && n < 0) {
472473
argv[0] = env;
@@ -483,10 +484,13 @@ lisp primapply(lisp ff, lisp args, lisp env, lisp all) {
483484
case 2: return fp(argv[0], argv[1]);
484485
case 3: return fp(argv[0], argv[1], argv[2]);
485486
case 4: return fp(argv[0], argv[1], argv[2], argv[3]);
487+
case 5: return fp(argv[0], argv[1], argv[2], argv[3], argv[4]);
488+
case 6: return fp(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
486489
}
487490
}
488491
// above is all optimiziations
489492

493+
// this is the old fallback solution, simple and works but expensive
490494
// prepare arguments
491495
if (n >= 0) {
492496
args = evallist(args, env);
@@ -523,7 +527,8 @@ lisp secretMkAtom(char* s) {
523527
lisp find_symbol(char *s, int len) {
524528
atom* cur = (atom*)symbol_list;
525529
while (cur) {
526-
if (strncmp(s, cur->name, len) == 0) return (lisp)cur;
530+
//if (strncmp(s, cur->name, len+1) == 0) return (lisp)cur;
531+
if (strncmp(s, cur->name, len) == 0 && strlen(cur->name) == len) return (lisp)cur;
527532
cur = cur->next;
528533
}
529534
return NULL;
@@ -644,14 +649,37 @@ lisp equal(lisp a, lisp b) { return eq(a, b) ? t : symbol("*EQUAL-NOT-DEFINED*")
644649
// setcdr(nenv, FAC); // create circular dependency on it's own defininition symbol by redefining
645650
// return nenv;
646651
//}
652+
653+
lisp _setqq(lisp env, lisp name, lisp v) {
654+
printf("[_setqq = "); princ(name); printf(" := "); princ(v); printf(" ]\n");
655+
lisp bind = assoc(name, env);
656+
if (!bind) return;
657+
setcdr(bind, v);
658+
return v;
659+
}
660+
lisp _setq(lisp env, lisp name, lisp v) {
661+
return _setqq(env, name, eval(v, env));
662+
}
663+
lisp _set(lisp env, lisp name, lisp v) {
664+
return _setqq(env, eval(name, env), eval(v, env));
665+
}
666+
667+
lisp _quote(lisp env, lisp x) {
668+
return x;
669+
}
670+
671+
lisp quote(lisp x) {
672+
return list(symbol("quote"), x, END);
673+
}
674+
647675
lisp setq(lisp name, lisp v, lisp env) {
648676
lisp bind = assoc(name, env);
649677
if (!bind) {
650678
bind = cons(name, nil);
651679
env = cons(bind, env);
652680
}
653-
v = eval(v, env); // evaluate using new env containing right env with binding to self
654-
setcdr(bind, v); // create circular dependency on it's own defininition symbol by redefining
681+
v = eval(v, env);
682+
setcdr(bind, v);
655683
return env;
656684
}
657685

@@ -832,7 +860,8 @@ static lisp eval_hlp(lisp e, lisp env) {
832860
if (tag == atom_TAG) {
833861
lisp v = assoc(e, env); // look up variable
834862
if (v) return cdr(v);
835-
printf("Undefined symbol: "); princ(e); terpri();
863+
printf("--Undefined symbol: "); princ(e); terpri();
864+
printf(" ENV= "); princ(env); terpri();
836865
return nil;
837866
}
838867
if (tag != conss_TAG) return e;
@@ -894,7 +923,8 @@ lisp evalGC(lisp e, lisp env) {
894923
if (tag == atom_TAG) {
895924
lisp v = assoc(e, env);
896925
if (v) return cdr(v);
897-
printf("Undefined symbol: "); princ(e); terpri();
926+
printf("--Undefined symbol: "); princ(e); terpri();
927+
printf(" ENV= "); princ(env); terpri();
898928
return nil;
899929
}
900930
if (tag != atom_TAG && tag != conss_TAG && tag != thunk_TAG) return e;
@@ -988,9 +1018,14 @@ lisp funcapply(lisp f, lisp args, lisp env) {
9881018
}
9891019

9901020
// User, macros, assume a "globaL" env variable implicitly, and updates it
991-
#define SETQ(sname, val) env = setq(symbol(#sname), val, env)
1021+
#define SET(sname, val) env = setq(symbol(#sname), val, env)
1022+
#define SETQc(sname, val) env = setq(symbol(#sname), val, env)
1023+
#define SETQ(sname, val) env = setq(symbol(#sname), read(#val), env)
1024+
#define SETQQ(sname, val) env = setq(symbol(#sname), quote(read(#val)), env)
9921025
#define DEF(fname, sbody) env = setq(symbol(#fname), read(#sbody), env)
993-
//#define EVAL(what) ({ eval(read(#what), env); terpri(); }) // TODO: no good!
1026+
#define EVAL(what) eval(read(#what), env)
1027+
#define PRINT(what) ({ princ(EVAL(what)); terpri(); })
1028+
#define SHOW(what) ({ printf(#what " => "); princ(EVAL(what)); terpri(); })
9941029
#define PRIM(fname, argn, fun) env = setq(symbol(#fname), mkprim(#fname, argn, fun), env)
9951030

9961031
// returns an env with functions
@@ -1011,7 +1046,7 @@ lisp lispinit() {
10111046
// nil = symbol("nil"); // LOL? TODO:? that wouldn't make sense? then it would be taken as true!
10121047
LAMBDA = mkprim("lambda", -16, lambda);
10131048

1014-
SETQ(lambda, LAMBDA);
1049+
SETQc(lambda, LAMBDA);
10151050
PRIM(+, 2, plus);
10161051
PRIM(-, 2, minus);
10171052
PRIM(*, 2, times);
@@ -1037,7 +1072,11 @@ lisp lispinit() {
10371072

10381073
PRIM(read, 1, read);
10391074

1040-
// setq
1075+
PRIM(set, -2, _set);
1076+
PRIM(setq, -2, _setq);
1077+
PRIM(setqq, -2, _setqq);
1078+
PRIM(quote, -1, _quote);
1079+
10411080
// define
10421081
// defun
10431082
// defmacro
@@ -1059,6 +1098,51 @@ lisp lispinit() {
10591098
void newLispTest(lisp env) {
10601099
dogc = 1;
10611100

1101+
printf("\n\n----------------------CLOSURE GENERATOR\n");
1102+
SETQc(a, mkint(35));
1103+
SHOW(a);
1104+
SETQc(a, mkint(99));
1105+
SHOW(a);
1106+
//princ(eval(read("(setq a 11111)"), env));
1107+
1108+
terpri();
1109+
PRINT(set);
1110+
_setq(env, symbol("a"), read("(+ 3 5)"));
1111+
SHOW(a);
1112+
1113+
terpri();
1114+
PRINT(setq);
1115+
_setq(env, symbol("a"), read("(+ 3 5)"));
1116+
SHOW(a);
1117+
1118+
// TODO: setqq doesn't do the job...
1119+
terpri();
1120+
printf("-setq x a---\n");
1121+
SETQQ(x, a);
1122+
SHOW(x);
1123+
1124+
terpri();
1125+
PRINT(setqq);
1126+
_setqq(env, symbol("x"), read("(+ 3 5)"));
1127+
SHOW(a);
1128+
1129+
//return;
1130+
1131+
SETQc(b, mkint(777));
1132+
SHOW(b);
1133+
SETQ(b, 999);
1134+
SHOW(b);
1135+
SETQ(b, (+ 3 4));
1136+
SHOW(b);
1137+
printf("----change from lisp!\n");
1138+
SETQ(c, 11111);
1139+
SHOW(c);
1140+
SHOW(c);
1141+
EVAL((setq c 12345));
1142+
princ(env); terpri();
1143+
SHOW(c);
1144+
1145+
printf("\n\n----------------------misc\n");
10621146
printf("ENV= "); princ(env); terpri();
10631147
princ(read("(foo bar 42)")); terpri();
10641148
princ(mkint(3)); terpri();
@@ -1088,6 +1172,7 @@ void newLispTest(lisp env) {
10881172
printf("2====\n");
10891173
printf("\nTEST %d=", LOOP); princ(evalGC(read(LOOPTAIL), env)); terpri();
10901174

1175+
printf("\n\n---cleanup\n");
10911176
mark(env); // TODO: move into GC()
10921177
gc();
10931178
}

0 commit comments

Comments
 (0)