Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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