@@ -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) {
523527lisp 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+
647675lisp 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() {
10591098void 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