Takehisa Oneta
/
malisp
Lisp Interpreter for mbed LPC1768
Embed:
(wiki syntax)
Show/hide line numbers
malisp.cpp
00001 #include "mbed.h" 00002 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 #include <ctype.h> 00006 #include <string.h> 00007 #include "malisp.h" 00008 #include "mbed_functions.h" 00009 00010 extern Serial pc; 00011 extern DigitalOut led1; 00012 extern DigitalOut led2; 00013 extern DigitalOut led3; 00014 extern DigitalOut led4; 00015 extern char *lisplib; 00016 00017 int _stack = 5000; 00018 00019 LIST *TRU; 00020 LIST *g_alist; // 連想リスト 00021 LIST *g_oblist; // list of Lisp Functions 00022 00023 char progon; 00024 00025 //FILE *fd; // input file descriptor 00026 FILE_MINE fd; 00027 00028 int32_t getc_mine_buffer_pt = 0; 00029 int getc_mine_buffer[8]; 00030 uint32_t lisplib_counter = 0; 00031 00032 //---------------------------------------------------------------- 00033 //int getc_mine(FILE *fd) 00034 int getc_mine(FILE_MINE fd) 00035 { 00036 if (getc_mine_buffer_pt > 0) { 00037 int c = getc_mine_buffer[getc_mine_buffer_pt]; 00038 getc_mine_buffer_pt--; 00039 if (getc_mine_buffer_pt < 0) { 00040 getc_mine_buffer_pt = 0; 00041 } 00042 return c; 00043 } 00044 00045 //return getc(fd); 00046 00047 int c = 0; 00048 if (fd == FILE_SERIAL) { 00049 c = pc.getc(); 00050 //pc.putc(c); 00051 00052 } else if (fd == FILE_STRING) { 00053 00054 if (lisplib_counter > strlen(lisplib)) { 00055 c = EOF; // EOF 00056 } else { 00057 c = *(lisplib + lisplib_counter); 00058 lisplib_counter++; 00059 } 00060 } 00061 00062 return c; 00063 } 00064 00065 //void ungetc_mine(int c, FILE *fd) 00066 void ungetc_mine(int c, FILE_MINE fd) 00067 { 00068 getc_mine_buffer_pt++; 00069 getc_mine_buffer[getc_mine_buffer_pt] = c; 00070 } 00071 00072 //---------------------------------------------------------------- 00073 // main program 00074 //---------------------------------------------------------------- 00075 00076 void malisp_main() 00077 { 00078 initialize(); 00079 pc.printf("\nMarc Adler's LISP Interpreter. (mbed port and expansion by ohneta)\n"); 00080 load_library(); 00081 00082 pc.printf("[FREE-MEM: %d bytes]\n", _getFreeMemorySize()); 00083 00084 { 00085 fd = FILE_SERIAL; 00086 getc_mine_buffer_pt = 0; 00087 interpret_malisp(); 00088 } 00089 } 00090 00091 void interpret_malisp() 00092 { 00093 LIST *p = NULL; 00094 LIST *q = NULL; 00095 int c; 00096 00097 while (EOF != (c = gettok())) { 00098 if (c == ERR) { 00099 continue; 00100 } 00101 00102 switch (c) { 00103 case LPAREN: 00104 getc_mine(fd); // span the paren 00105 q = makelist(); 00106 p = eval(q, g_alist); 00107 break; 00108 00109 case LETTER: 00110 p = cdr(car(getid())); 00111 break; 00112 } 00113 00114 if (fd == FILE_SERIAL) { 00115 pc.printf("\n"); 00116 pc.printf("value => "); 00117 if (p == NULL) { 00118 pc.printf("nil"); 00119 } else { 00120 lisp_print(cons(p, NULL)); 00121 //lisp_print(p); 00122 } 00123 pc.printf("\n"); 00124 } 00125 } 00126 } 00127 00128 //---------------------------------------------------------------- 00129 // initialization procedures 00130 //---------------------------------------------------------------- 00131 00132 void initialize() 00133 { 00134 init("'", QUOTE); 00135 init("car", FCAR); 00136 init("cond", COND); 00137 init("cdr", FCDR); 00138 init("defun", DEFUN); 00139 init("cons",FCONS); 00140 init("nil", NILL); 00141 init("atom",FATOM); 00142 init("prog",PROG); 00143 init("eq", FEQ); 00144 init("go", GO); 00145 init("setq",FSETQ); 00146 init("return",RETRN); 00147 init("print",PRINT); 00148 init("read", FREAD); 00149 init("rplaca",FREPLACA); 00150 init("rplacd",FREPLACD); 00151 init("apply", FAPPLY); 00152 init("eval", FEVAL); 00153 init("and", FAND); 00154 init("or", FOR); 00155 init("not", FNOT); 00156 init("plus", PLUS); 00157 init("zerop", ZEROP); 00158 init("diff", DIFF); 00159 init("greaterp", GREATERP); 00160 init("times", TIMES); 00161 init("lessp", LESSP); 00162 init("add1", ADD1); 00163 init("sub1", SUB1); 00164 init("quot", QUOTIENT); 00165 TRU = cons(init("t", T), NULL); 00166 init("numberp", NUMBERP); 00167 rplact(TRU, SATOM); 00168 init("null", NUL); 00169 init("funcall",FUNCALL); 00170 00171 // for mbed functions 00172 init("info", FINFO); 00173 init("freemem", FFREEMEM); 00174 00175 init("wait", FWAIT); 00176 init("dout", FDOUT); 00177 init("din", FDIN); 00178 init("aout", FAOUT); 00179 init("ain", FAIN); 00180 init("pwmout", PWMOUT); 00181 00182 g_oblist = g_alist; 00183 } 00184 00185 LIST *init(char *name, int t) 00186 { 00187 LIST *p = install(name, false); 00188 rplact(p, t); 00189 00190 return p; 00191 } 00192 00193 //---------------------------------------------------------------- 00194 // create the executable list form of a LISP program 00195 //---------------------------------------------------------------- 00196 00197 LIST *makelist() 00198 { 00199 LIST *p; 00200 00201 switch (gettok()) { 00202 case LPAREN: 00203 getc_mine(fd); // span the paren ????? 00204 p = makelist(); 00205 p = cons(p, makelist()); 00206 rplact(p, LST); 00207 return p; 00208 00209 case LETTER: 00210 p = getid(); 00211 return cons(p, makelist()); 00212 00213 case INQUOTE: 00214 p = getid(); 00215 p = cons(p, makelist()); 00216 rplaca(p, cons(car(p), cons(car(cdr(p)), NULL))); 00217 rplacd(p, cdr(cdr(p))); 00218 return p; 00219 00220 case DIGIT: 00221 p = getnum(); 00222 return cons(p, makelist()); 00223 00224 case RPAREN: 00225 getc_mine(fd); // span rparen ?????? 00226 return NULL; 00227 } 00228 00229 return NULL; 00230 } 00231 00232 00233 // isp_print - walks along the list structure printing atoms 00234 void lisp_print(LIST *p) 00235 { 00236 if (p == NULL) { 00237 return; 00238 } 00239 00240 if (type(p) == RATOM) { 00241 pc.printf("%f ", p->u.num); 00242 } else if (type(p) == IATOM) { 00243 pc.printf("%d ", (int) p->u.num); 00244 } else if (type(p) == SATOM) { 00245 pc.printf("%s ", getname(car(p))); 00246 } else if (type(car(p)) == LST) { 00247 pc.printf("%c", '('); 00248 lisp_print(car(p)); 00249 pc.printf("%c", ')'); 00250 lisp_print(cdr(p)); 00251 } else if (type(p) == LST) { 00252 lisp_print(car(p)); 00253 lisp_print(cdr(p)); 00254 } else { 00255 pc.printf("******** can't print it out *******\n"); 00256 } 00257 } 00258 00259 //---------------------------------------------------------------- 00260 // evaluate a LISP function 00261 //---------------------------------------------------------------- 00262 00263 LIST *eval(LIST *x, LIST *alist) 00264 { 00265 LIST *p, *q; 00266 int savt, t; 00267 00268 if (x == NULL) { 00269 return NULL; 00270 } 00271 t = type(x); 00272 if (t == VARI) { 00273 return assoc(alist, getname(car(x))); 00274 } 00275 if (t == IATOM || t == RATOM) { 00276 return x; 00277 } 00278 if (t == LABL) { 00279 return NULL; 00280 } 00281 00282 switch (type(car(x))) { 00283 case T: 00284 return TRU; 00285 00286 case NILL: 00287 return NULL; 00288 00289 case QUOTE: 00290 var_to_atom(car(cdr(x))); 00291 return car(cdr(x)); 00292 00293 case FCAR: 00294 return car(eval(cdr(x), alist)); 00295 00296 case FCDR: 00297 return cdr(eval(cdr(x), alist)); 00298 00299 case FATOM: 00300 return atom(eval(cdr(x), alist)); 00301 00302 case FEQ: 00303 return eq(eval(car(cdr(x)),alist), eval(cdr(cdr(x)),alist)); 00304 00305 case NUL: 00306 return eq(eval(car(cdr(x)), alist), NULL); 00307 00308 case FCONS: 00309 return cons(eval(car(cdr(x)),alist), eval(cdr(cdr(x)), alist)); 00310 00311 case FLIST: 00312 return _list(x); 00313 00314 case COND: 00315 return evalcond(cdr(x), alist); 00316 00317 case FSETQ: 00318 p = eval(cdr(cdr(x)), alist); 00319 rplacd(getvar(alist, getname(car(car(cdr(x))))), p); 00320 return p; 00321 00322 case DEFUN: 00323 rplact(car(car(cdr(x))), FUSER); 00324 rplacd(car(car(cdr(x))), cdr(cdr(x))); 00325 var_to_user(cdr(cdr(cdr(x)))); 00326 if (fd == FILE_SERIAL) { 00327 pc.printf("%s\n", getname(car(car(cdr(x))))); 00328 } 00329 return NULL; 00330 00331 case FUSER: 00332 p = cdr(car(car(x))); // p is statement list 00333 return eval(car(cdr(p)), pairargs(car(p), evalargs(cdr(x),alist), alist, FALSE)); 00334 00335 case FAPPLY: 00336 case FUNCALL: 00337 p = eval(car(cdr(x)), alist); // func name 00338 if (isfunc(savt = type(car(p)))) { 00339 p = cons(p, cdr(cdr(x))); 00340 if (savt == FUSER) { 00341 rplact(car(p), FUSER); 00342 } 00343 q = eval(p, alist); 00344 rplact(car(p), savt); 00345 return q; 00346 } else 00347 return NULL; 00348 00349 case FEVAL: 00350 p = eval(cdr(x), alist); 00351 if (type(p) == SATOM) { 00352 return assoc(alist, getname(car(p))); 00353 } 00354 return eval(p, alist); 00355 00356 case PRINT: 00357 lisp_print(eval(car(cdr(x)), alist)); 00358 pc.printf("\n"); 00359 return NULL; 00360 00361 case FREAD: 00362 return makelist(); 00363 00364 case FAND: 00365 return _and(x); 00366 case FOR: 00367 return _or(x); 00368 case FNOT: 00369 return _not(x); 00370 00371 case PLUS: 00372 case DIFF: 00373 case TIMES: 00374 case QUOTIENT: 00375 case GREATERP: 00376 case LESSP: 00377 return arith(car(x), eval(car(cdr(x)), alist), eval(cdr(cdr(x)), alist)); 00378 00379 case ADD1: 00380 case SUB1: 00381 return arith(car(x), eval(car(cdr(x)), alist), NULL); 00382 00383 case ZEROP: 00384 p = eval(car(cdr(x)), alist); 00385 return (p->u.num == 0) ? TRU : NULL; 00386 00387 case NUMBERP: 00388 savt = type(eval(car(cdr(x)), alist)); 00389 return (savt==IATOM || savt==RATOM) ? TRU : NULL; 00390 00391 case PROG: 00392 return evalprog(x, alist); 00393 00394 case GO: 00395 return cdr(car(car(cdr(x)))); 00396 00397 case RETRN: 00398 progon = FALSE; 00399 return eval(cdr(x), alist); 00400 00401 case LST: 00402 if (cdr(x) == NULL) { 00403 return eval(car(x), alist); 00404 } 00405 return cons(eval(car(x),alist),eval(cdr(x),alist)); 00406 00407 case VARI: 00408 return assoc(alist, getname(car(car(x)))); 00409 00410 case IATOM: 00411 case RATOM: 00412 return car(x); 00413 00414 00415 00416 // mbed expand 00417 case FINFO: 00418 { 00419 pc.printf("\noblist --\n"); 00420 debug(g_oblist); 00421 00422 return NULL; 00423 } 00424 case FFREEMEM: 00425 { 00426 LIST * p = memfreesize(); 00427 if (p != NULL) { 00428 p->gcbit = GARBAGE; 00429 } 00430 return p; 00431 } 00432 case FWAIT: 00433 { 00434 LIST * p = mbed_wait(eval(car(cdr(x)), alist)); 00435 /* 00436 if (p != NULL) { 00437 p->gcbit = GARBAGE; 00438 } 00439 */ 00440 return p; 00441 } 00442 case FDOUT: 00443 return mbed_digitalout(eval(car(cdr(x)), alist), eval(cdr(cdr(x)), alist)); 00444 case FDIN: 00445 return mbed_digitalin(eval(car(cdr(x)), alist), eval(cdr(cdr(x)), alist)); 00446 case FAOUT: 00447 return mbed_analogout(eval(car(cdr(x)), alist), eval(cdr(cdr(x)), alist)); 00448 case FAIN: 00449 return mbed_analogin(eval(car(cdr(x)), alist)); 00450 case PWMOUT: 00451 return mbed_pwmout(eval(car(cdr(x)), alist), eval(car(cdr(cdr(x))), alist), eval(cdr(cdr(cdr(x))), alist)); 00452 } 00453 00454 return NULL; 00455 } 00456 00457 00458 LIST *evalcond(LIST *expr, LIST *alist) 00459 { 00460 if (expr == NULL) { 00461 return NULL; 00462 } 00463 00464 if (eval(car(car(expr)), alist) != NULL) { // expr was true 00465 return eval(car(cdr(car(expr))), alist); // return result 00466 } 00467 00468 return evalcond(cdr(expr), alist); // eval rest of args 00469 } 00470 00471 00472 LIST *evalprog(LIST *p, LIST *alist) 00473 { 00474 LIST *x = NULL; 00475 00476 // set up parameters as locals 00477 alist = pairargs(car(cdr(p)), cons(NULL, NULL), alist, TRUE); 00478 progon = TRUE; 00479 p = cdr(cdr(p)); /* p now points to the statement list */ 00480 find_labels(p); /* set up all labels in the prog */ 00481 00482 while (p != NULL && progon) { 00483 x = eval(car(p), alist); 00484 if (type(car(car(p))) == GO) { 00485 p = x; /* GO returned the next statement to go to */ 00486 } else { 00487 p = cdr(p); /* just follow regular chain of statements */ 00488 00489 } 00490 } 00491 00492 progon = TRUE; /* in case of nested progs */ 00493 return x; 00494 } 00495 00496 // pairargs - installs parameters in the alist, and sets the value to be the value of the corresponding argument. 00497 LIST *pairargs(LIST *params, LIST *args, LIST *alist, int prog) 00498 { 00499 if (params == NULL) { // no more args to be evaluated 00500 return alist; 00501 } 00502 00503 LIST *p = cons(NULL, car(args)); // value of param is corresponding arg 00504 p->u.pname = getname(car(car(params))); 00505 rplact(p, VARI); 00506 if (prog) { 00507 return cons(p, pairargs(cdr(params), cons(NULL,NULL), alist, prog)); 00508 } 00509 00510 return cons(p, pairargs(cdr(params), cdr(args), alist, prog)); 00511 } 00512 00513 LIST *evalargs(LIST *arglist, LIST *alist) 00514 { 00515 if (arglist == NULL) { 00516 return NULL; 00517 } 00518 00519 return cons(eval(car(arglist),alist), evalargs(cdr(arglist), alist)); 00520 } 00521 00522 LIST *assoc( LIST *alist, char *name) 00523 { 00524 return cdr(getvar(alist, name)); 00525 } 00526 00527 LIST *getvar(LIST *alist, char *name) 00528 { 00529 return lookup(alist, name); 00530 } 00531 00532 // arith - performs arithmetic on numeric items 00533 LIST *arith(LIST *op, LIST *x, LIST *y) 00534 { 00535 LIST *p; 00536 float res = 0; 00537 int t = type(op); 00538 00539 if (t == LESSP) { 00540 return (x->u.num < y->u.num) ? TRU : NULL; 00541 } 00542 if (t == GREATERP) { 00543 return (x->u.num > y->u.num) ? TRU : NULL; 00544 } 00545 00546 switch (t) { 00547 case PLUS: 00548 res = x->u.num + y->u.num; 00549 break; 00550 case DIFF: 00551 res = x->u.num - y->u.num; 00552 break; 00553 case TIMES: 00554 res = x->u.num * y->u.num; 00555 break; 00556 case QUOTIENT: 00557 res = x->u.num / y->u.num; 00558 break; 00559 case ADD1: 00560 res = x->u.num + 1; 00561 break; 00562 case SUB1: 00563 res = x->u.num - 1; 00564 break; 00565 } 00566 00567 p = cons(NULL, NULL); 00568 00569 // @TODO: tがADD1かSUB1の場合、yは必ずNULLなので、 type(y)を実行するとエラーだと思うんだが... 00570 /* 00571 if ( (type(x) == IATOM) && 00572 (type(y) == IATOM) || 00573 (t == ADD1) || (t == SUB1) ) 00574 ) { 00575 */ 00576 if ((type(x) == IATOM) && ((t == ADD1) || (t == SUB1))) { 00577 p->u.num = (int)res; 00578 rplact(p, IATOM); 00579 } else { 00580 p->u.num = res; 00581 rplact(p, RATOM); 00582 } 00583 00584 return p; 00585 } 00586 00587 //---------------------------------------------------------------- 00588 // input functions 00589 //---------------------------------------------------------------- 00590 00591 // advance - skips white space in input file 00592 int advance() 00593 { 00594 int c; 00595 #if 0 00596 while (((c = getc_mine(fd)) != EOF) && (strchr(" \t\n", c) != NULL)); 00597 #else 00598 while (1) { 00599 c = getc_mine(fd); 00600 if (c == EOF) { 00601 break; 00602 } 00603 if (strchr(" \t\n\r", c) == NULL) { 00604 break; 00605 } 00606 } 00607 #endif 00608 ungetc_mine(c, fd); 00609 //pc.printf("%c", c); 00610 00611 return c; 00612 } 00613 00614 LIST *lookup(LIST *head, char *name) 00615 { 00616 LIST *p; 00617 00618 #if 0 00619 for (p = head; p != NULL && strcmp(name, getname(car(p))); p = cdr(p)) { 00620 ; 00621 } 00622 #else 00623 p = head; 00624 while (p != NULL) { 00625 if (strcmp(name, getname(car(p))) == 0) { 00626 break; 00627 } 00628 p = cdr(p); 00629 } 00630 #endif 00631 00632 return ((p == NULL) ? NULL : car(p)); 00633 } 00634 00635 /** 00636 * nameをalistに加える 00637 * 00638 * @param char *name alistに加える名前 00639 * @param bool nameCopyFlag nameをコピーするか否か。 true=コピーする、1=コピーしない(nameがconstな文字列) 00640 */ 00641 LIST *install(char *name, bool nameCopyFlag = true) 00642 { 00643 LIST *p = cons(NULL, NULL); 00644 00645 if (nameCopyFlag) { 00646 p->u.pname = (char *)emalloc(strlen(name) + 1); 00647 strcpy(p->u.pname, name); 00648 } else { 00649 p->u.pname = name; 00650 } 00651 00652 rplact(p, VARI); 00653 g_alist = cons(p, g_alist); 00654 00655 return p; 00656 } 00657 00658 LIST *getnum() 00659 { 00660 LIST *p; 00661 float sum, n; 00662 int c; 00663 00664 sum = 0.0; 00665 p = cons(NULL, NULL); 00666 rplact(p, IATOM); 00667 00668 while (isdigit(c = getc_mine(fd))) { 00669 sum = sum * 10 + c - '0'; 00670 } 00671 00672 if (c == '.') { /* the number is real */ 00673 n = 10; 00674 rplact(p, RATOM); 00675 //while (isdigit(c = getc(fd))) { 00676 while (isdigit(c = getc_mine(fd))) { 00677 sum += (c - '0')/n; 00678 n *= 10; 00679 } 00680 } 00681 00682 ungetc_mine(c, fd); 00683 p->u.num = sum; 00684 00685 return p; 00686 } 00687 00688 LIST *getid() 00689 { 00690 LIST *p; 00691 00692 char inbuf[120]; // トークン 1つ分のバッファ 00693 char *s = inbuf; 00694 LIST *idptr; 00695 00696 // トークンを取得する 00697 { 00698 int c = getc_mine(fd); 00699 *s = c; 00700 s++; 00701 if (c != '\'') { 00702 while(1) { 00703 c = getc_mine(fd); 00704 if (!isalnum(c)) { 00705 ungetc_mine(c, fd); 00706 break; 00707 } 00708 *s = c; 00709 s++; 00710 } 00711 } 00712 *s = '\0'; 00713 } 00714 00715 if ((idptr = lookup(g_oblist, inbuf)) == NULL) { // not a LISP function 00716 if ((idptr = lookup(g_alist, inbuf)) == NULL) { // id not declared yet 00717 idptr = install(inbuf, true); // install it in g_alist (alist) 00718 } 00719 } 00720 p = cons(idptr, NULL); 00721 rplact(p, type(idptr)); 00722 00723 return p; 00724 } 00725 00726 int gettok() 00727 { 00728 int c; 00729 00730 while ((c = advance()) == ';') { // saw a comment 00731 while (1) { 00732 c = getc_mine(fd); 00733 if ((c == EOF) || (c == '\n')) { // EOF or CR 00734 break; 00735 } 00736 } 00737 } 00738 00739 if (isalpha(c)) { 00740 return LETTER; 00741 } 00742 if (isdigit(c)) { 00743 return DIGIT; 00744 } 00745 switch (c) { 00746 case '(': 00747 return LPAREN; 00748 case ')': 00749 return RPAREN; 00750 case '\'': 00751 return INQUOTE; 00752 case EOF: 00753 return EOF; 00754 } 00755 00756 return ERR; 00757 } 00758 00759 //---------------------------------------------------------------- 00760 // LISP primitive functions 00761 //---------------------------------------------------------------- 00762 00763 // new - gets a new node from the free storage 00764 LIST *new_malisp() 00765 { 00766 LIST *p = (struct LIST *)emalloc(sizeof(LIST)); 00767 p->gcbit = RUNNING; 00768 00769 return p; 00770 } 00771 00772 int type(LIST *p) 00773 { 00774 return p->htype; 00775 } 00776 00777 char* getname(LIST *p) 00778 { 00779 return (p == NULL) ? NULL : p->u.pname; 00780 } 00781 00782 // pのcar部をqに置き換える 00783 void rplaca(LIST *p, LIST *q) 00784 { 00785 p->left = q; 00786 } 00787 00788 // pのcdr部をqに置き換える 00789 void rplacd(LIST *p, LIST *q) 00790 { 00791 p->right = q; 00792 } 00793 00794 // pのタイプ(htype)をtに置き換える 00795 void rplact(LIST *p, int t) 00796 { 00797 p->htype = t; 00798 } 00799 00800 LIST *car(LIST *p) 00801 { 00802 return (p == NULL) ? NULL : p->left; 00803 } 00804 00805 LIST *cdr(LIST *p) 00806 { 00807 return (p == NULL) ? NULL : p->right; 00808 } 00809 00810 LIST *cons(LIST *p, LIST *q) 00811 { 00812 LIST *x = new_malisp(); 00813 00814 rplaca(x, p); 00815 rplacd(x, q); 00816 rplact(x, LST); 00817 00818 return x; 00819 } 00820 00821 LIST *eq(LIST *x, LIST *y) 00822 { 00823 if (x == NULL || y == NULL) { 00824 if (x == y) { 00825 return TRU; 00826 } 00827 } else if ( (type(x) == SATOM) && 00828 (type(y) == SATOM) && 00829 (car(x) == car(y)) ) { 00830 return TRU; 00831 } 00832 00833 return NULL; 00834 } 00835 00836 LIST *atom(LIST *x) 00837 { 00838 #if 0 00839 int typ; 00840 00841 if (x == NULL || (typ = type(x)) == IATOM || typ == RATOM || typ == SATOM) { 00842 return TRU; 00843 } 00844 #else 00845 if (x == NULL) { 00846 return TRU; 00847 } 00848 00849 int typ = type(x); 00850 if (typ == IATOM) { 00851 return TRU; 00852 } 00853 if (typ == RATOM) { 00854 return TRU; 00855 } 00856 if (typ == SATOM) { 00857 return TRU; 00858 } 00859 #endif 00860 return NULL; 00861 } 00862 00863 //---------------------------------------------------------------- 00864 // logical connectives - and, or, not 00865 00866 LIST *_and(LIST *x) 00867 { 00868 LIST *p; 00869 for (p = cdr(x); p != NULL; p = cdr(p)) { 00870 if (eval(car(p), NULL) == NULL) { 00871 return NULL; 00872 } 00873 } 00874 00875 return TRU; 00876 } 00877 00878 LIST *_or(LIST *x) 00879 { 00880 LIST *p; 00881 for (p = cdr(x); p != NULL; p = cdr(p)) { 00882 if (eval(car(p), NULL) != NULL) { 00883 return TRU; 00884 } 00885 } 00886 00887 return NULL; 00888 } 00889 00890 LIST *_not(LIST *x) 00891 { 00892 return (eval(cdr(x), NULL) == NULL) ? TRU : NULL; 00893 } 00894 00895 // other primitives 00896 00897 LIST *_list(LIST *x) 00898 { 00899 LIST *res, *p; 00900 00901 for (res = NULL, p = cdr(x); p != NULL; p = cdr(p)) { 00902 res = cons(res, car(p)); 00903 } 00904 00905 return res; 00906 } 00907 00908 00909 void var_to_user(LIST *p) 00910 { 00911 if (p == NULL) { 00912 return; 00913 } 00914 00915 if (type(p) == VARI) { 00916 if (type(car(p)) == FUSER) { 00917 rplact(p, FUSER); 00918 } 00919 } else if (type(p) == LST) { 00920 var_to_user(car(p)); 00921 var_to_user(cdr(p)); 00922 } 00923 } 00924 00925 void var_to_atom(LIST *p) 00926 { 00927 int t; 00928 00929 if (p != NULL) { 00930 if (((t = type(p)) != LST && !isfunc(t)) || t == FUSER) { 00931 rplact(p, SATOM); 00932 } else { 00933 var_to_atom(car(p)); var_to_atom(cdr(p)); 00934 } 00935 } 00936 } 00937 00938 // find_labels - change the type of all labels in a PROG to LABL 00939 void find_labels(LIST *p) 00940 { 00941 for ( ; p != NULL; p = cdr(p)) { 00942 if (type(car(p)) == VARI) { 00943 rplact(car(p), LABL); // change the type to LABL 00944 rplacd(car(car(p)), cdr(p)); // label points to next statement 00945 } 00946 } 00947 } 00948 00949 //---------------------------------------------------------------- 00950 // garbage collection 00951 //---------------------------------------------------------------- 00952 00953 void work_garbageCollect(LIST *p) 00954 { 00955 int cnt = 0; 00956 while (p != NULL) { 00957 00958 int t = type(p); 00959 00960 pc.printf("[%d] ", cnt); 00961 pc.printf("(%d) ", t); 00962 if ((t == IATOM) || (t == RATOM)) { 00963 pc.printf("[%f ] : ", p->u.num); 00964 } else if (t == SATOM) { 00965 pc.printf("[%s ] : ", p->u.pname); 00966 } else { 00967 pc.printf(" : "); 00968 } 00969 00970 //pc.printf("%d : ", (p->gcbit >> 16) & 0xff); // num 00971 //pc.printf("%d \n", (p->gcbit & 0xff)); // bit (USED/RUNNING) 00972 00973 p = cdr(p); 00974 cnt++; 00975 } 00976 } 00977 00978 // marktree - recursively marks all used items in a list 00979 void marktree(LIST *p) 00980 { 00981 if (p != NULL) { 00982 if (type(p) == LST) { 00983 marktree(car(p)); 00984 marktree(cdr(p)); 00985 } 00986 p->gcbit = USED; 00987 } 00988 } 00989 00990 /*********************** storage allocator *****************/ 00991 00992 void *emalloc(size_t size) 00993 { 00994 void *s; 00995 00996 if ((s = malloc(size)) == NULL) { 00997 pc.printf("OUT OF MEMORY !! : crashed !! \n"); 00998 exit(0); 00999 } 01000 01001 return s; 01002 } 01003 01004 // routine to load the library of lisp functions in 01005 void load_library(void) 01006 { 01007 #if 0 01008 char libpath[1024]; 01009 strcpy(libpath, getenv("HOME")); 01010 strcat(libpath, "/lisplib"); 01011 01012 if ((fd = fopen(libpath, "r")) != NULL) { 01013 interpret_malisp(); 01014 fclose(fd); 01015 01016 pc.printf("loaded lisplib from %s\n", libpath); 01017 } 01018 interpret_malisp(); 01019 01020 fd = stdin; 01021 #else 01022 01023 fd = FILE_STRING; 01024 interpret_malisp(); 01025 pc.printf("loaded lisplib from flash\n"); 01026 01027 fd = FILE_SERIAL; 01028 01029 #endif 01030 } 01031 01032 // isfunc - returns YES if type t is a user-function or a lisp primitive 01033 int isfunc(int t) 01034 { 01035 return 01036 ( t==FUSER || t==ADD1 || t==SUB1 || t==PLUS || t==DIFF || t==TIMES || 01037 t==QUOTIENT || t==LESSP || t==GREATERP || t==ZEROP || t==NUMBERP || 01038 t==FCAR || t==FCDR || t==FCONS || t==FREAD || t==PRINT || t==FNOT|| 01039 t==FAND || t==FOR || t==FEVAL || t==FEQ || t==FATOM || 01040 01041 // mbed extends 01042 t == FFREEMEM || t == FWAIT || t == FDOUT || t == FDIN || 01043 t == FAOUT || t == FAIN || t == PWMOUT 01044 ); 01045 } 01046 01047 void debug(LIST *p) 01048 { 01049 pc.printf("DEBUG ---\n"); 01050 debug2(p); 01051 pc.printf("\n"); 01052 } 01053 01054 void debug2(LIST *p) 01055 { 01056 int t; 01057 01058 if (p != NULL) { 01059 if ((t = type(p)) == LST) { 01060 pc.printf("("); 01061 debug2(car(p)); 01062 debug2(cdr(p)); 01063 pc.printf(")"); 01064 } else if (t == RATOM) { 01065 pc.printf("RATOM %f ", p->u.num); 01066 } else if (t == IATOM) { 01067 pc.printf("IATOM %d ", (int) p->u.num); 01068 } else if (t == SATOM) { 01069 pc.printf("SATOM %s ", getname(car(p))); 01070 } else { 01071 pc.printf("FUNC %d ", type(p)); 01072 } 01073 } 01074 }
Generated on Wed Jul 13 2022 19:47:42 by 1.7.2