You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4410 lines
126 KiB

3 years ago
  1. /* uLisp AVR Version 3.4 - www.ulisp.com
  2. David Johnson-Davies - www.technoblogy.com - 5th December 2020
  3. Licensed under the MIT license: https://opensource.org/licenses/MIT
  4. */
  5. // Lisp Library
  6. const char LispLibrary[] PROGMEM = "";
  7. // Compile options
  8. #define checkoverflow
  9. // #define resetautorun
  10. #define printfreespace
  11. // #define printgcs
  12. // #define sdcardsupport
  13. // #define lisplibrary
  14. // #define lineeditor
  15. // #define vt100
  16. // Includes
  17. // #include "LispLibrary.h"
  18. #include <avr/sleep.h>
  19. #include <setjmp.h>
  20. #include <SPI.h>
  21. #include <limits.h>
  22. #include <EEPROM.h>
  23. #if defined(sdcardsupport)
  24. #include <SD.h>
  25. #define SDSIZE 172
  26. #else
  27. #define SDSIZE 0
  28. #endif
  29. // Platform specific settings
  30. #define WORDALIGNED __attribute__((aligned (2)))
  31. #define BUFFERSIZE 21 /* longest builtin name + 1 */
  32. #if defined(__AVR_ATmega328P__)
  33. #define WORKSPACESIZE (314-SDSIZE) /* Objects (4*bytes) */
  34. #define EEPROMSIZE 1024 /* Bytes */
  35. #define SYMBOLTABLESIZE BUFFERSIZE /* Bytes - no long symbols */
  36. #define STACKDIFF 0
  37. #define CPU_ATmega328P
  38. #elif defined(__AVR_ATmega2560__)
  39. #define WORKSPACESIZE (1214-SDSIZE) /* Objects (4*bytes) */
  40. #define EEPROMSIZE 4096 /* Bytes */
  41. #define SYMBOLTABLESIZE 512 /* Bytes */
  42. #define STACKDIFF 320
  43. #define CPU_ATmega2560
  44. #elif defined(__AVR_ATmega1284P__)
  45. #define WORKSPACESIZE (2816-SDSIZE) /* Objects (4*bytes) */
  46. #define EEPROMSIZE 4096 /* Bytes */
  47. #define SYMBOLTABLESIZE 512 /* Bytes */
  48. #define STACKDIFF 320
  49. #define CPU_ATmega1284P
  50. #elif defined(ARDUINO_AVR_NANO_EVERY)
  51. #define WORKSPACESIZE (1065-SDSIZE) /* Objects (4*bytes) */
  52. #define EEPROMSIZE 256 /* Bytes */
  53. #define SYMBOLTABLESIZE BUFFERSIZE /* Bytes - no long symbols */
  54. #define STACKDIFF 320
  55. #define CPU_ATmega4809
  56. #elif defined(ARDUINO_AVR_ATmega4809) /* Curiosity Nano using MegaCoreX */
  57. #define Serial Serial3
  58. #define WORKSPACESIZE (1065-SDSIZE) /* Objects (4*bytes) */
  59. #define EEPROMSIZE 256 /* Bytes */
  60. #define SYMBOLTABLESIZE BUFFERSIZE /* Bytes - no long symbols */
  61. #define STACKDIFF 320
  62. #define CPU_ATmega4809
  63. #elif defined(__AVR_ATmega4809__)
  64. #define WORKSPACESIZE (1065-SDSIZE) /* Objects (4*bytes) */
  65. #define EEPROMSIZE 256 /* Bytes */
  66. #define SYMBOLTABLESIZE BUFFERSIZE /* Bytes - no long symbols */
  67. #define STACKDIFF 320
  68. #define CPU_ATmega4809
  69. #elif defined(__AVR_AVR128DA48__)
  70. #define Serial Serial1
  71. #define WORKSPACESIZE 2800-SDSIZE /* Objects (4*bytes) */
  72. #define EEPROMSIZE 256 /* Bytes */
  73. #define SYMBOLTABLESIZE 256 /* Bytes */
  74. #define STACKDIFF 320
  75. #define CPU_AVR128DA48
  76. #elif defined(__AVR_AVR128DB48__)
  77. #define Serial Serial1
  78. #define WORKSPACESIZE 2800-SDSIZE /* Objects (4*bytes) */
  79. #define EEPROMSIZE 256 /* Bytes */
  80. #define SYMBOLTABLESIZE 256 /* Bytes */
  81. #define STACKDIFF 320
  82. #define CPU_AVR128DA48
  83. #else
  84. #error "Board not supported!"
  85. #endif
  86. // C Macros
  87. #define nil NULL
  88. #define car(x) (((object *) (x))->car)
  89. #define cdr(x) (((object *) (x))->cdr)
  90. #define first(x) (((object *) (x))->car)
  91. #define second(x) (car(cdr(x)))
  92. #define cddr(x) (cdr(cdr(x)))
  93. #define third(x) (car(cdr(cdr(x))))
  94. #define push(x, y) ((y) = cons((x),(y)))
  95. #define pop(y) ((y) = cdr(y))
  96. #define integerp(x) ((x) != NULL && (x)->type == NUMBER)
  97. #define floatp(x) ((x) != NULL && (x)->type == FLOAT)
  98. #define symbolp(x) ((x) != NULL && (x)->type == SYMBOL)
  99. #define stringp(x) ((x) != NULL && (x)->type == STRING)
  100. #define characterp(x) ((x) != NULL && (x)->type == CHARACTER)
  101. #define streamp(x) ((x) != NULL && (x)->type == STREAM)
  102. #define mark(x) (car(x) = (object *)(((uintptr_t)(car(x))) | MARKBIT))
  103. #define unmark(x) (car(x) = (object *)(((uintptr_t)(car(x))) & ~MARKBIT))
  104. #define marked(x) ((((uintptr_t)(car(x))) & MARKBIT) != 0)
  105. #define MARKBIT 1
  106. #define setflag(x) (Flags = Flags | 1<<(x))
  107. #define clrflag(x) (Flags = Flags & ~(1<<(x)))
  108. #define tstflag(x) (Flags & 1<<(x))
  109. #define issp(x) (x == ' ' || x == '\n' || x == '\r' || x == '\t')
  110. #define SDCARD_SS_PIN 10
  111. #if defined(CPU_ATmega4809)
  112. #define PROGMEM
  113. #define PSTR(s) (s)
  114. #endif
  115. // Constants
  116. const int TRACEMAX = 3; // Number of traced functions
  117. enum type { ZZERO=0, SYMBOL=2, NUMBER=4, STREAM=6, CHARACTER=8, FLOAT=10, STRING=12, PAIR=14 }; // STRING and PAIR must be last
  118. enum token { UNUSED, BRA, KET, QUO, DOT };
  119. enum stream { SERIALSTREAM, I2CSTREAM, SPISTREAM, SDSTREAM, STRINGSTREAM };
  120. // Stream names used by printobject
  121. const char serialstream[] PROGMEM = "serial";
  122. const char i2cstream[] PROGMEM = "i2c";
  123. const char spistream[] PROGMEM = "spi";
  124. const char sdstream[] PROGMEM = "sd";
  125. PGM_P const streamname[] PROGMEM = {serialstream, i2cstream, spistream, sdstream};
  126. // Typedefs
  127. typedef unsigned int symbol_t;
  128. typedef struct sobject {
  129. union {
  130. struct {
  131. sobject *car;
  132. sobject *cdr;
  133. };
  134. struct {
  135. unsigned int type;
  136. union {
  137. symbol_t name;
  138. int integer;
  139. int chars; // For strings
  140. };
  141. };
  142. };
  143. } object;
  144. typedef object *(*fn_ptr_type)(object *, object *);
  145. typedef void (*mapfun_t)(object *, object **);
  146. typedef struct {
  147. PGM_P string;
  148. fn_ptr_type fptr;
  149. uint8_t minmax;
  150. } tbl_entry_t;
  151. typedef int (*gfun_t)();
  152. typedef void (*pfun_t)(char);
  153. #if defined(CPU_ATmega328P) || defined(CPU_ATmega2560) || defined(CPU_ATmega1284P) || defined(CPU_AVR128DA48)
  154. typedef int BitOrder;
  155. typedef int PinMode;
  156. #endif
  157. enum function { NIL, TEE, NOTHING, OPTIONAL, AMPREST, LAMBDA, LET, LETSTAR, CLOSURE, SPECIAL_FORMS, QUOTE,
  158. DEFUN, DEFVAR, SETQ, LOOP, RETURN, PUSH, POP, INCF, DECF, SETF, DOLIST, DOTIMES, TRACE, UNTRACE,
  159. FORMILLIS, WITHSERIAL, WITHI2C, WITHSPI, WITHSDCARD, TAIL_FORMS, PROGN, IF, COND, WHEN, UNLESS, CASE, AND,
  160. OR, FUNCTIONS, NOT, NULLFN, CONS, ATOM, LISTP, CONSP, SYMBOLP, BOUNDP, SETFN, STREAMP, EQ, CAR, FIRST,
  161. CDR, REST, CAAR, CADR, SECOND, CDAR, CDDR, CAAAR, CAADR, CADAR, CADDR, THIRD, CDAAR, CDADR, CDDAR, CDDDR,
  162. LENGTH, LIST, REVERSE, NTH, ASSOC, MEMBER, APPLY, FUNCALL, APPEND, MAPC, MAPCAR, MAPCAN, ADD, SUBTRACT,
  163. MULTIPLY, DIVIDE, TRUNCATE, MOD, ONEPLUS, ONEMINUS, ABS, RANDOM, MAXFN, MINFN, NOTEQ, NUMEQ, LESS, LESSEQ,
  164. GREATER, GREATEREQ, PLUSP, MINUSP, ZEROP, ODDP, EVENP, INTEGERP, NUMBERP, CHAR, CHARCODE, CODECHAR,
  165. CHARACTERP, STRINGP, STRINGEQ, STRINGLESS, STRINGGREATER, SORT, STRINGFN, CONCATENATE, SUBSEQ,
  166. READFROMSTRING, PRINCTOSTRING, PRIN1TOSTRING, LOGAND, LOGIOR, LOGXOR, LOGNOT, ASH, LOGBITP, EVAL, GLOBALS,
  167. LOCALS, MAKUNBOUND, BREAK, READ, PRIN1, PRINT, PRINC, TERPRI, READBYTE, READLINE, WRITEBYTE, WRITESTRING,
  168. WRITELINE, RESTARTI2C, GC, ROOM, SAVEIMAGE, LOADIMAGE, CLS, PINMODE, DIGITALREAD, DIGITALWRITE,
  169. ANALOGREAD, ANALOGREFERENCE, ANALOGREADRESOLUTION, ANALOGWRITE, DACREFERENCE, DELAY, MILLIS, SLEEP, NOTE,
  170. EDIT, PPRINT, PPRINTALL, FORMAT, REQUIRE, LISTLIBRARY, KEYWORDS,
  171. #if defined(CPU_ATmega328P)
  172. K_HIGH, K_LOW, K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL, K_EXTERNAL,
  173. #elif defined(CPU_ATmega2560)
  174. K_HIGH, K_LOW, K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL1V1, K_INTERNAL2V56, K_EXTERNAL,
  175. #elif defined(CPU_ATmega4809)
  176. K_HIGH, K_LOW, K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL, K_VDD, K_INTERNAL0V55,
  177. K_INTERNAL1V1, K_INTERNAL1V5, K_INTERNAL2V5, K_INTERNAL4V3, K_EXTERNAL,
  178. #elif defined(CPU_AVR128DA48)
  179. K_HIGH, K_LOW, K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_VDD, K_INTERNAL1V024, K_INTERNAL2V048,
  180. K_INTERNAL4V096, K_INTERNAL2V5, K_EXTERNAL, K_ADC_DAC0, K_ADC_TEMPERATURE,
  181. #endif
  182. USERFUNCTIONS, ENDFUNCTIONS };
  183. // Global variables
  184. object Workspace[WORKSPACESIZE] WORDALIGNED;
  185. char SymbolTable[SYMBOLTABLESIZE];
  186. jmp_buf exception;
  187. unsigned int Freespace = 0;
  188. object *Freelist;
  189. char *SymbolTop = SymbolTable;
  190. unsigned int I2CCount;
  191. unsigned int TraceFn[TRACEMAX];
  192. unsigned int TraceDepth[TRACEMAX];
  193. object *GlobalEnv;
  194. object *GCStack = NULL;
  195. object *GlobalString;
  196. int GlobalStringIndex = 0;
  197. uint8_t PrintCount = 0;
  198. uint8_t BreakLevel = 0;
  199. char LastChar = 0;
  200. char LastPrint = 0;
  201. // Flags
  202. enum flag { PRINTREADABLY, RETURNFLAG, ESCAPE, EXITEDITOR, LIBRARYLOADED, NOESC };
  203. volatile char Flags = 0b00001; // PRINTREADABLY set by default
  204. // Forward references
  205. object *tee;
  206. object *tf_progn (object *form, object *env);
  207. object *eval (object *form, object *env);
  208. object *read (gfun_t gfun);
  209. void repl (object *env);
  210. void printobject (object *form, pfun_t pfun);
  211. char *lookupbuiltin (symbol_t name);
  212. intptr_t lookupfn (symbol_t name);
  213. int builtin (char* n);
  214. void pfstring (PGM_P s, pfun_t pfun);
  215. // Error handling
  216. void errorsub (symbol_t fname, PGM_P string) {
  217. pfl(pserial); pfstring(PSTR("Error: "), pserial);
  218. if (fname) {
  219. pserial('\'');
  220. pstring(symbolname(fname), pserial);
  221. pserial('\''); pserial(' ');
  222. }
  223. pfstring(string, pserial);
  224. }
  225. void error (symbol_t fname, PGM_P string, object *symbol) {
  226. errorsub(fname, string);
  227. pserial(':'); pserial(' ');
  228. printobject(symbol, pserial);
  229. pln(pserial);
  230. GCStack = NULL;
  231. longjmp(exception, 1);
  232. }
  233. void error2 (symbol_t fname, PGM_P string) {
  234. errorsub(fname, string);
  235. pln(pserial);
  236. GCStack = NULL;
  237. longjmp(exception, 1);
  238. }
  239. // Save space as these are used multiple times
  240. const char notanumber[] PROGMEM = "argument is not a number";
  241. const char notaninteger[] PROGMEM = "argument is not an integer";
  242. const char notastring[] PROGMEM = "argument is not a string";
  243. const char notalist[] PROGMEM = "argument is not a list";
  244. const char notasymbol[] PROGMEM = "argument is not a symbol";
  245. const char notproper[] PROGMEM = "argument is not a proper list";
  246. const char toomanyargs[] PROGMEM = "too many arguments";
  247. const char toofewargs[] PROGMEM = "too few arguments";
  248. const char noargument[] PROGMEM = "missing argument";
  249. const char nostream[] PROGMEM = "missing stream argument";
  250. const char overflow[] PROGMEM = "arithmetic overflow";
  251. const char indexnegative[] PROGMEM = "index can't be negative";
  252. const char invalidarg[] PROGMEM = "invalid argument";
  253. const char invalidkey[] PROGMEM = "invalid keyword";
  254. const char invalidpin[] PROGMEM = "invalid pin";
  255. const char resultproper[] PROGMEM = "result is not a proper list";
  256. const char oddargs[] PROGMEM = "odd number of arguments";
  257. // Set up workspace
  258. void initworkspace () {
  259. Freelist = NULL;
  260. for (int i=WORKSPACESIZE-1; i>=0; i--) {
  261. object *obj = &Workspace[i];
  262. car(obj) = NULL;
  263. cdr(obj) = Freelist;
  264. Freelist = obj;
  265. Freespace++;
  266. }
  267. }
  268. object *myalloc () {
  269. if (Freespace == 0) error2(0, PSTR("no room"));
  270. object *temp = Freelist;
  271. Freelist = cdr(Freelist);
  272. Freespace--;
  273. return temp;
  274. }
  275. void myfree (object *obj) {
  276. car(obj) = NULL;
  277. cdr(obj) = Freelist;
  278. Freelist = obj;
  279. Freespace++;
  280. }
  281. // Make each type of object
  282. object *number (int n) {
  283. object *ptr = myalloc();
  284. ptr->type = NUMBER;
  285. ptr->integer = n;
  286. return ptr;
  287. }
  288. object *character (char c) {
  289. object *ptr = myalloc();
  290. ptr->type = CHARACTER;
  291. ptr->chars = c;
  292. return ptr;
  293. }
  294. object *cons (object *arg1, object *arg2) {
  295. object *ptr = myalloc();
  296. ptr->car = arg1;
  297. ptr->cdr = arg2;
  298. return ptr;
  299. }
  300. object *symbol (symbol_t name) {
  301. object *ptr = myalloc();
  302. ptr->type = SYMBOL;
  303. ptr->name = name;
  304. return ptr;
  305. }
  306. object *newsymbol (symbol_t name) {
  307. for (int i=WORKSPACESIZE-1; i>=0; i--) {
  308. object *obj = &Workspace[i];
  309. if (symbolp(obj) && obj->name == name) return obj;
  310. }
  311. return symbol(name);
  312. }
  313. object *stream (unsigned char streamtype, unsigned char address) {
  314. object *ptr = myalloc();
  315. ptr->type = STREAM;
  316. ptr->integer = streamtype<<8 | address;
  317. return ptr;
  318. }
  319. // Garbage collection
  320. void markobject (object *obj) {
  321. MARK:
  322. if (obj == NULL) return;
  323. if (marked(obj)) return;
  324. object* arg = car(obj);
  325. unsigned int type = obj->type;
  326. mark(obj);
  327. if (type >= PAIR || type == ZZERO) { // cons
  328. markobject(arg);
  329. obj = cdr(obj);
  330. goto MARK;
  331. }
  332. if (type == STRING) {
  333. obj = cdr(obj);
  334. while (obj != NULL) {
  335. arg = car(obj);
  336. mark(obj);
  337. obj = arg;
  338. }
  339. }
  340. }
  341. void sweep () {
  342. Freelist = NULL;
  343. Freespace = 0;
  344. for (int i=WORKSPACESIZE-1; i>=0; i--) {
  345. object *obj = &Workspace[i];
  346. if (!marked(obj)) myfree(obj); else unmark(obj);
  347. }
  348. }
  349. void gc (object *form, object *env) {
  350. #if defined(printgcs)
  351. int start = Freespace;
  352. #endif
  353. markobject(tee);
  354. markobject(GlobalEnv);
  355. markobject(GCStack);
  356. markobject(form);
  357. markobject(env);
  358. sweep();
  359. #if defined(printgcs)
  360. pfl(pserial); pserial('{'); pint(Freespace - start, pserial); pserial('}');
  361. #endif
  362. }
  363. // Compact image
  364. void movepointer (object *from, object *to) {
  365. for (int i=0; i<WORKSPACESIZE; i++) {
  366. object *obj = &Workspace[i];
  367. unsigned int type = (obj->type) & ~MARKBIT;
  368. if (marked(obj) && (type >= STRING || type==ZZERO)) {
  369. if (car(obj) == (object *)((uintptr_t)from | MARKBIT))
  370. car(obj) = (object *)((uintptr_t)to | MARKBIT);
  371. if (cdr(obj) == from) cdr(obj) = to;
  372. }
  373. }
  374. // Fix strings
  375. for (int i=0; i<WORKSPACESIZE; i++) {
  376. object *obj = &Workspace[i];
  377. if (marked(obj) && ((obj->type) & ~MARKBIT) == STRING) {
  378. obj = cdr(obj);
  379. while (obj != NULL) {
  380. if (cdr(obj) == to) cdr(obj) = from;
  381. obj = (object *)((uintptr_t)(car(obj)) & ~MARKBIT);
  382. }
  383. }
  384. }
  385. }
  386. uintptr_t compactimage (object **arg) {
  387. markobject(tee);
  388. markobject(GlobalEnv);
  389. markobject(GCStack);
  390. object *firstfree = Workspace;
  391. while (marked(firstfree)) firstfree++;
  392. object *obj = &Workspace[WORKSPACESIZE-1];
  393. while (firstfree < obj) {
  394. if (marked(obj)) {
  395. car(firstfree) = car(obj);
  396. cdr(firstfree) = cdr(obj);
  397. unmark(obj);
  398. movepointer(obj, firstfree);
  399. if (GlobalEnv == obj) GlobalEnv = firstfree;
  400. if (GCStack == obj) GCStack = firstfree;
  401. if (*arg == obj) *arg = firstfree;
  402. while (marked(firstfree)) firstfree++;
  403. }
  404. obj--;
  405. }
  406. sweep();
  407. return firstfree - Workspace;
  408. }
  409. // Make SD card filename
  410. char *MakeFilename (object *arg) {
  411. char *buffer = SymbolTop;
  412. int max = maxbuffer(buffer);
  413. int i = 0;
  414. do {
  415. char c = nthchar(arg, i);
  416. if (c == '\0') break;
  417. buffer[i++] = c;
  418. } while (i<max);
  419. buffer[i] = '\0';
  420. return buffer;
  421. }
  422. // Save-image and load-image
  423. #if defined(sdcardsupport)
  424. void SDWriteInt (File file, int data) {
  425. file.write(data & 0xFF); file.write(data>>8 & 0xFF);
  426. }
  427. #else
  428. void EEPROMWriteInt (unsigned int *addr, int data) {
  429. EEPROM.write((*addr)++, data & 0xFF); EEPROM.write((*addr)++, data>>8 & 0xFF);
  430. }
  431. #endif
  432. unsigned int saveimage (object *arg) {
  433. unsigned int imagesize = compactimage(&arg);
  434. #if defined(sdcardsupport)
  435. SD.begin(SDCARD_SS_PIN);
  436. File file;
  437. if (stringp(arg)) {
  438. file = SD.open(MakeFilename(arg), O_RDWR | O_CREAT | O_TRUNC);
  439. arg = NULL;
  440. } else if (arg == NULL || listp(arg)) file = SD.open("/ULISP.IMG", O_RDWR | O_CREAT | O_TRUNC);
  441. else error(SAVEIMAGE, invalidarg, arg);
  442. if (!file) error2(SAVEIMAGE, PSTR("problem saving to SD card"));
  443. SDWriteInt(file, (uintptr_t)arg);
  444. SDWriteInt(file, imagesize);
  445. SDWriteInt(file, (uintptr_t)GlobalEnv);
  446. SDWriteInt(file, (uintptr_t)GCStack);
  447. #if SYMBOLTABLESIZE > BUFFERSIZE
  448. SDWriteInt(file, (uintptr_t)SymbolTop);
  449. int SymbolUsed = SymbolTop - SymbolTable;
  450. for (int i=0; i<SymbolUsed; i++) file.write(SymbolTable[i]);
  451. #endif
  452. for (unsigned int i=0; i<imagesize; i++) {
  453. object *obj = &Workspace[i];
  454. SDWriteInt(file, (uintptr_t)car(obj));
  455. SDWriteInt(file, (uintptr_t)cdr(obj));
  456. }
  457. file.close();
  458. return imagesize;
  459. #else
  460. if (!(arg == NULL || listp(arg))) error(SAVEIMAGE, invalidarg, arg);
  461. int SymbolUsed = SymbolTop - SymbolTable;
  462. int bytesneeded = imagesize*4 + SymbolUsed + 10;
  463. if (bytesneeded > EEPROMSIZE) error(SAVEIMAGE, PSTR("image size too large"), number(imagesize));
  464. unsigned int addr = 0;
  465. EEPROMWriteInt(&addr, (unsigned int)arg);
  466. EEPROMWriteInt(&addr, imagesize);
  467. EEPROMWriteInt(&addr, (unsigned int)GlobalEnv);
  468. EEPROMWriteInt(&addr, (unsigned int)GCStack);
  469. #if SYMBOLTABLESIZE > BUFFERSIZE
  470. EEPROMWriteInt(&addr, (unsigned int)SymbolTop);
  471. for (int i=0; i<SymbolUsed; i++) EEPROM.write(addr++, SymbolTable[i]);
  472. #endif
  473. for (unsigned int i=0; i<imagesize; i++) {
  474. object *obj = &Workspace[i];
  475. EEPROMWriteInt(&addr, (uintptr_t)car(obj));
  476. EEPROMWriteInt(&addr, (uintptr_t)cdr(obj));
  477. }
  478. return imagesize;
  479. #endif
  480. }
  481. #if defined(sdcardsupport)
  482. int SDReadInt (File file) {
  483. uint8_t b0 = file.read(); uint8_t b1 = file.read();
  484. return b0 | b1<<8;
  485. }
  486. #else
  487. int EEPROMReadInt (unsigned int *addr) {
  488. uint8_t b0 = EEPROM.read((*addr)++); uint8_t b1 = EEPROM.read((*addr)++);
  489. return b0 | b1<<8;
  490. }
  491. #endif
  492. unsigned int loadimage (object *arg) {
  493. #if defined(sdcardsupport)
  494. SD.begin(SDCARD_SS_PIN);
  495. File file;
  496. if (stringp(arg)) file = SD.open(MakeFilename(arg));
  497. else if (arg == NULL) file = SD.open("/ULISP.IMG");
  498. else error(LOADIMAGE, invalidarg, arg);
  499. if (!file) error2(LOADIMAGE, PSTR("problem loading from SD card"));
  500. SDReadInt(file);
  501. int imagesize = SDReadInt(file);
  502. GlobalEnv = (object *)SDReadInt(file);
  503. GCStack = (object *)SDReadInt(file);
  504. #if SYMBOLTABLESIZE > BUFFERSIZE
  505. SymbolTop = (char *)SDReadInt(file);
  506. int SymbolUsed = SymbolTop - SymbolTable;
  507. for (int i=0; i<SymbolUsed; i++) SymbolTable[i] = file.read();
  508. #endif
  509. for (int i=0; i<imagesize; i++) {
  510. object *obj = &Workspace[i];
  511. car(obj) = (object *)SDReadInt(file);
  512. cdr(obj) = (object *)SDReadInt(file);
  513. }
  514. file.close();
  515. gc(NULL, NULL);
  516. return imagesize;
  517. #else
  518. unsigned int addr = 0;
  519. EEPROMReadInt(&addr); // Skip eval address
  520. unsigned int imagesize = EEPROMReadInt(&addr);
  521. if (imagesize == 0 || imagesize == 0xFFFF) error2(LOADIMAGE, PSTR("no saved image"));
  522. GlobalEnv = (object *)EEPROMReadInt(&addr);
  523. GCStack = (object *)EEPROMReadInt(&addr);
  524. #if SYMBOLTABLESIZE > BUFFERSIZE
  525. SymbolTop = (char *)EEPROMReadInt(&addr);
  526. int SymbolUsed = SymbolTop - SymbolTable;
  527. for (int i=0; i<SymbolUsed; i++) SymbolTable[i] = EEPROM.read(addr++);
  528. #endif
  529. for (int i=0; i<imagesize; i++) {
  530. object *obj = &Workspace[i];
  531. car(obj) = (object *)EEPROMReadInt(&addr);
  532. cdr(obj) = (object *)EEPROMReadInt(&addr);
  533. }
  534. gc(NULL, NULL);
  535. return imagesize;
  536. #endif
  537. }
  538. void autorunimage () {
  539. #if defined(sdcardsupport)
  540. SD.begin(SDCARD_SS_PIN);
  541. File file = SD.open("ULISP.IMG");
  542. if (!file) error2(0, PSTR("problem autorunning from SD card"));
  543. object *autorun = (object *)SDReadInt(file);
  544. file.close();
  545. if (autorun != NULL) {
  546. loadimage(NULL);
  547. apply(0, autorun, NULL, NULL);
  548. }
  549. #else
  550. unsigned int addr = 0;
  551. object *autorun = (object *)EEPROMReadInt(&addr);
  552. if (autorun != NULL && (unsigned int)autorun != 0xFFFF) {
  553. loadimage(nil);
  554. apply(0, autorun, NULL, NULL);
  555. }
  556. #endif
  557. }
  558. // Tracing
  559. bool tracing (symbol_t name) {
  560. int i = 0;
  561. while (i < TRACEMAX) {
  562. if (TraceFn[i] == name) return i+1;
  563. i++;
  564. }
  565. return 0;
  566. }
  567. void trace (symbol_t name) {
  568. if (tracing(name)) error(TRACE, PSTR("already being traced"), symbol(name));
  569. int i = 0;
  570. while (i < TRACEMAX) {
  571. if (TraceFn[i] == 0) { TraceFn[i] = name; TraceDepth[i] = 0; return; }
  572. i++;
  573. }
  574. error2(TRACE, PSTR("already tracing 3 functions"));
  575. }
  576. void untrace (symbol_t name) {
  577. int i = 0;
  578. while (i < TRACEMAX) {
  579. if (TraceFn[i] == name) { TraceFn[i] = 0; return; }
  580. i++;
  581. }
  582. error(UNTRACE, PSTR("not tracing"), symbol(name));
  583. }
  584. // Helper functions
  585. bool consp (object *x) {
  586. if (x == NULL) return false;
  587. unsigned int type = x->type;
  588. return type >= PAIR || type == ZZERO;
  589. }
  590. bool atom (object *x) {
  591. if (x == NULL) return true;
  592. unsigned int type = x->type;
  593. return type < PAIR && type != ZZERO;
  594. }
  595. bool listp (object *x) {
  596. if (x == NULL) return true;
  597. unsigned int type = x->type;
  598. return type >= PAIR || type == ZZERO;
  599. }
  600. bool improperp (object *x) {
  601. if (x == NULL) return false;
  602. unsigned int type = x->type;
  603. return type < PAIR && type != ZZERO;
  604. }
  605. object *quote (object *arg) {
  606. return cons(symbol(QUOTE), cons(arg,NULL));
  607. }
  608. // Radix 40 encoding
  609. #define MAXSYMBOL 64000
  610. int toradix40 (char ch) {
  611. if (ch == 0) return 0;
  612. if (ch >= '0' && ch <= '9') return ch-'0'+30;
  613. if (ch == '$') return 27; if (ch == '*') return 28; if (ch == '-') return 29;
  614. ch = ch | 0x20;
  615. if (ch >= 'a' && ch <= 'z') return ch-'a'+1;
  616. return -1; // Invalid
  617. }
  618. int fromradix40 (int n) {
  619. if (n >= 1 && n <= 26) return 'a'+n-1;
  620. if (n == 27) return '$'; if (n == 28) return '*'; if (n == 29) return '-';
  621. if (n >= 30 && n <= 39) return '0'+n-30;
  622. return 0;
  623. }
  624. int pack40 (char *buffer) {
  625. return (((toradix40(buffer[0]) * 40) + toradix40(buffer[1])) * 40 + toradix40(buffer[2]));
  626. }
  627. bool valid40 (char *buffer) {
  628. return (toradix40(buffer[0]) >= 0 && toradix40(buffer[1]) >= 0 && toradix40(buffer[2]) >= 0);
  629. }
  630. char *symbolname (symbol_t x) {
  631. if (x < ENDFUNCTIONS) return lookupbuiltin(x);
  632. else if (x >= MAXSYMBOL) return lookupsymbol(x);
  633. char *buffer = SymbolTop;
  634. buffer[3] = '\0';
  635. for (int n=2; n>=0; n--) {
  636. buffer[n] = fromradix40(x % 40);
  637. x = x / 40;
  638. }
  639. return buffer;
  640. }
  641. int digitvalue (char d) {
  642. if (d>='0' && d<='9') return d-'0';
  643. d = d | 0x20;
  644. if (d>='a' && d<='f') return d-'a'+10;
  645. return 16;
  646. }
  647. int checkinteger (symbol_t name, object *obj) {
  648. if (!integerp(obj)) error(name, notaninteger, obj);
  649. return obj->integer;
  650. }
  651. int checkchar (symbol_t name, object *obj) {
  652. if (!characterp(obj)) error(name, PSTR("argument is not a character"), obj);
  653. return obj->chars;
  654. }
  655. int isstream (object *obj){
  656. if (!streamp(obj)) error(0, PSTR("not a stream"), obj);
  657. return obj->integer;
  658. }
  659. int issymbol (object *obj, symbol_t n) {
  660. return symbolp(obj) && obj->name == n;
  661. }
  662. int keywordp (object *obj) {
  663. if (!symbolp(obj)) return false;
  664. symbol_t name = obj->name;
  665. return ((name > KEYWORDS) && (name < USERFUNCTIONS));
  666. }
  667. int checkkeyword (symbol_t name, object *obj) {
  668. if (!keywordp(obj)) error(name, PSTR("argument is not a keyword"), obj);
  669. symbol_t kname = obj->name;
  670. uint8_t context = getminmax(kname);
  671. if (context != 0 && context != name) error(name, invalidkey, obj);
  672. return ((int)lookupfn(kname));
  673. }
  674. void checkargs (symbol_t name, object *args) {
  675. int nargs = listlength(name, args);
  676. if (name >= ENDFUNCTIONS) error(0, PSTR("not valid here"), symbol(name));
  677. checkminmax(name, nargs);
  678. }
  679. int eq (object *arg1, object *arg2) {
  680. if (arg1 == arg2) return true; // Same object
  681. if ((arg1 == nil) || (arg2 == nil)) return false; // Not both values
  682. if (arg1->cdr != arg2->cdr) return false; // Different values
  683. if (symbolp(arg1) && symbolp(arg2)) return true; // Same symbol
  684. if (integerp(arg1) && integerp(arg2)) return true; // Same integer
  685. if (characterp(arg1) && characterp(arg2)) return true; // Same character
  686. return false;
  687. }
  688. int listlength (symbol_t name, object *list) {
  689. int length = 0;
  690. while (list != NULL) {
  691. if (improperp(list)) error2(name, notproper);
  692. list = cdr(list);
  693. length++;
  694. }
  695. return length;
  696. }
  697. // Association lists
  698. object *assoc (object *key, object *list) {
  699. while (list != NULL) {
  700. if (improperp(list)) error(ASSOC, notproper, list);
  701. object *pair = first(list);
  702. if (!listp(pair)) error(ASSOC, PSTR("element is not a list"), pair);
  703. if (pair != NULL && eq(key,car(pair))) return pair;
  704. list = cdr(list);
  705. }
  706. return nil;
  707. }
  708. object *delassoc (object *key, object **alist) {
  709. object *list = *alist;
  710. object *prev = NULL;
  711. while (list != NULL) {
  712. object *pair = first(list);
  713. if (eq(key,car(pair))) {
  714. if (prev == NULL) *alist = cdr(list);
  715. else cdr(prev) = cdr(list);
  716. return key;
  717. }
  718. prev = list;
  719. list = cdr(list);
  720. }
  721. return nil;
  722. }
  723. // String utilities
  724. void indent (uint8_t spaces, char ch, pfun_t pfun) {
  725. for (uint8_t i=0; i<spaces; i++) pfun(ch);
  726. }
  727. object *startstring (symbol_t name) {
  728. object *string = myalloc();
  729. string->type = STRING;
  730. GlobalString = NULL;
  731. GlobalStringIndex = 0;
  732. return string;
  733. }
  734. void buildstring (char ch, int *chars, object **head) {
  735. static object* tail;
  736. static uint8_t shift;
  737. if (*chars == 0) {
  738. shift = (sizeof(int)-1)*8;
  739. *chars = ch<<shift;
  740. object *cell = myalloc();
  741. if (*head == NULL) *head = cell; else tail->car = cell;
  742. cell->car = NULL;
  743. cell->chars = *chars;
  744. tail = cell;
  745. } else {
  746. shift = shift - 8;
  747. *chars = *chars | ch<<shift;
  748. tail->chars = *chars;
  749. if (shift == 0) *chars = 0;
  750. }
  751. }
  752. object *readstring (char delim, gfun_t gfun) {
  753. object *obj = myalloc();
  754. obj->type = STRING;
  755. int ch = gfun();
  756. if (ch == -1) return nil;
  757. object *head = NULL;
  758. int chars = 0;
  759. while ((ch != delim) && (ch != -1)) {
  760. if (ch == '\\') ch = gfun();
  761. buildstring(ch, &chars, &head);
  762. ch = gfun();
  763. }
  764. obj->cdr = head;
  765. return obj;
  766. }
  767. int stringlength (object *form) {
  768. int length = 0;
  769. form = cdr(form);
  770. while (form != NULL) {
  771. int chars = form->chars;
  772. for (int i=(sizeof(int)-1)*8; i>=0; i=i-8) {
  773. if (chars>>i & 0xFF) length++;
  774. }
  775. form = car(form);
  776. }
  777. return length;
  778. }
  779. char nthchar (object *string, int n) {
  780. object *arg = cdr(string);
  781. int top;
  782. if (sizeof(int) == 4) { top = n>>2; n = 3 - (n&3); }
  783. else { top = n>>1; n = 1 - (n&1); }
  784. for (int i=0; i<top; i++) {
  785. if (arg == NULL) return 0;
  786. arg = car(arg);
  787. }
  788. if (arg == NULL) return 0;
  789. return (arg->chars)>>(n*8) & 0xFF;
  790. }
  791. int gstr () {
  792. if (LastChar) {
  793. char temp = LastChar;
  794. LastChar = 0;
  795. return temp;
  796. }
  797. char c = nthchar(GlobalString, GlobalStringIndex++);
  798. if (c != 0) return c;
  799. return '\n'; // -1?
  800. }
  801. void pstr (char c) {
  802. buildstring(c, &GlobalStringIndex, &GlobalString);
  803. }
  804. // Lookup variable in environment
  805. object *value (symbol_t n, object *env) {
  806. while (env != NULL) {
  807. object *pair = car(env);
  808. if (pair != NULL && car(pair)->name == n) return pair;
  809. env = cdr(env);
  810. }
  811. return nil;
  812. }
  813. bool boundp (object *var, object *env) {
  814. symbol_t varname = var->name;
  815. if (value(varname, env) != NULL) return true;
  816. if (value(varname, GlobalEnv) != NULL) return true;
  817. return false;
  818. }
  819. object *findvalue (object *var, object *env) {
  820. symbol_t varname = var->name;
  821. object *pair = value(varname, env);
  822. if (pair == NULL) pair = value(varname, GlobalEnv);
  823. if (pair == NULL) error(0, PSTR("unknown variable"), var);
  824. return pair;
  825. }
  826. // Handling closures
  827. object *closure (int tc, symbol_t name, object *state, object *function, object *args, object **env) {
  828. int trace = 0;
  829. if (name) trace = tracing(name);
  830. if (trace) {
  831. indent(TraceDepth[trace-1]<<1, ' ', pserial);
  832. pint(TraceDepth[trace-1]++, pserial);
  833. pserial(':'); pserial(' '); pserial('('); pstring(symbolname(name), pserial);
  834. }
  835. object *params = first(function);
  836. if (!listp(params)) error(name, notalist, params);
  837. function = cdr(function);
  838. // Dropframe
  839. if (tc) {
  840. if (*env != NULL && car(*env) == NULL) {
  841. pop(*env);
  842. while (*env != NULL && car(*env) != NULL) pop(*env);
  843. } else push(nil, *env);
  844. }
  845. // Push state
  846. while (state != NULL) {
  847. object *pair = first(state);
  848. push(pair, *env);
  849. state = cdr(state);
  850. }
  851. // Add arguments to environment
  852. bool optional = false;
  853. while (params != NULL) {
  854. object *value;
  855. object *var = first(params);
  856. if (symbolp(var) && var->name == OPTIONAL) optional = true;
  857. else {
  858. if (consp(var)) {
  859. if (!optional) error(name, PSTR("invalid default value"), var);
  860. if (args == NULL) value = eval(second(var), *env);
  861. else { value = first(args); args = cdr(args); }
  862. var = first(var);
  863. if (!symbolp(var)) error(name, PSTR("illegal optional parameter"), var);
  864. } else if (!symbolp(var)) {
  865. error2(name, PSTR("illegal function parameter"));
  866. } else if (var->name == AMPREST) {
  867. params = cdr(params);
  868. var = first(params);
  869. value = args;
  870. args = NULL;
  871. } else {
  872. if (args == NULL) {
  873. if (optional) value = nil;
  874. else error2(name, toofewargs);
  875. } else { value = first(args); args = cdr(args); }
  876. }
  877. push(cons(var,value), *env);
  878. if (trace) { pserial(' '); printobject(value, pserial); }
  879. }
  880. params = cdr(params);
  881. }
  882. if (args != NULL) error2(name, toomanyargs);
  883. if (trace) { pserial(')'); pln(pserial); }
  884. // Do an implicit progn
  885. if (tc) push(nil, *env);
  886. return tf_progn(function, *env);
  887. }
  888. object *apply (symbol_t name, object *function, object *args, object *env) {
  889. if (symbolp(function)) {
  890. symbol_t fname = function->name;
  891. if ((fname > FUNCTIONS) && (fname < KEYWORDS)) {
  892. checkargs(fname, args);
  893. return ((fn_ptr_type)lookupfn(fname))(args, env);
  894. } else function = eval(function, env);
  895. }
  896. if (consp(function) && issymbol(car(function), LAMBDA)) {
  897. function = cdr(function);
  898. object *result = closure(0, name, NULL, function, args, &env);
  899. return eval(result, env);
  900. }
  901. if (consp(function) && issymbol(car(function), CLOSURE)) {
  902. function = cdr(function);
  903. object *result = closure(0, name, car(function), cdr(function), args, &env);
  904. return eval(result, env);
  905. }
  906. error(name, PSTR("illegal function"), function);
  907. return NULL;
  908. }
  909. // In-place operations
  910. object **place (symbol_t name, object *args, object *env) {
  911. if (atom(args)) return &cdr(findvalue(args, env));
  912. object* function = first(args);
  913. if (symbolp(function)) {
  914. symbol_t fname = function->name;
  915. if (fname == CAR || fname == FIRST) {
  916. object *value = eval(second(args), env);
  917. if (!listp(value)) error(name, PSTR("can't take car"), value);
  918. return &car(value);
  919. }
  920. if (fname == CDR || fname == REST) {
  921. object *value = eval(second(args), env);
  922. if (!listp(value)) error(name, PSTR("can't take cdr"), value);
  923. return &cdr(value);
  924. }
  925. if (fname == NTH) {
  926. int index = checkinteger(NTH, eval(second(args), env));
  927. object *list = eval(third(args), env);
  928. if (atom(list)) error(name, PSTR("second argument to nth is not a list"), list);
  929. while (index > 0) {
  930. list = cdr(list);
  931. if (list == NULL) error2(name, PSTR("index to nth is out of range"));
  932. index--;
  933. }
  934. return &car(list);
  935. }
  936. }
  937. error2(name, PSTR("illegal place"));
  938. return nil;
  939. }
  940. // Checked car and cdr
  941. object *carx (object *arg) {
  942. if (!listp(arg)) error(0, PSTR("can't take car"), arg);
  943. if (arg == nil) return nil;
  944. return car(arg);
  945. }
  946. object *cdrx (object *arg) {
  947. if (!listp(arg)) error(0, PSTR("can't take cdr"), arg);
  948. if (arg == nil) return nil;
  949. return cdr(arg);
  950. }
  951. // I2C interface
  952. #if defined(CPU_ATmega328P)
  953. uint8_t const TWI_SDA_PIN = 18;
  954. uint8_t const TWI_SCL_PIN = 19;
  955. #elif defined(CPU_ATmega1280) || defined(CPU_ATmega2560)
  956. uint8_t const TWI_SDA_PIN = 20;
  957. uint8_t const TWI_SCL_PIN = 21;
  958. #elif defined(CPU_ATmega644P) || defined(CPU_ATmega1284P)
  959. uint8_t const TWI_SDA_PIN = 17;
  960. uint8_t const TWI_SCL_PIN = 16;
  961. #elif defined(CPU_ATmega32U4)
  962. uint8_t const TWI_SDA_PIN = 6;
  963. uint8_t const TWI_SCL_PIN = 5;
  964. #endif
  965. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  966. uint32_t const FREQUENCY = 400000L; // Hardware I2C clock in Hz
  967. uint32_t const T_RISE = 300L; // Rise time
  968. #else
  969. uint32_t const F_TWI = 400000L; // Hardware I2C clock in Hz
  970. uint8_t const TWSR_MTX_DATA_ACK = 0x28;
  971. uint8_t const TWSR_MTX_ADR_ACK = 0x18;
  972. uint8_t const TWSR_MRX_ADR_ACK = 0x40;
  973. uint8_t const TWSR_START = 0x08;
  974. uint8_t const TWSR_REP_START = 0x10;
  975. uint8_t const I2C_READ = 1;
  976. uint8_t const I2C_WRITE = 0;
  977. #endif
  978. void I2Cinit (bool enablePullup) {
  979. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  980. if (enablePullup) {
  981. pinMode(PIN_WIRE_SDA, INPUT_PULLUP);
  982. pinMode(PIN_WIRE_SCL, INPUT_PULLUP);
  983. }
  984. uint32_t baud = ((F_CPU/FREQUENCY) - (((F_CPU*T_RISE)/1000)/1000)/1000 - 10)/2;
  985. TWI0.MBAUD = (uint8_t)baud;
  986. TWI0.MCTRLA = TWI_ENABLE_bm; // Enable as master, no interrupts
  987. TWI0.MSTATUS = TWI_BUSSTATE_IDLE_gc;
  988. #else
  989. TWSR = 0; // no prescaler
  990. TWBR = (F_CPU/F_TWI - 16)/2; // set bit rate factor
  991. if (enablePullup) {
  992. digitalWrite(TWI_SDA_PIN, HIGH);
  993. digitalWrite(TWI_SCL_PIN, HIGH);
  994. }
  995. #endif
  996. }
  997. int I2Cread () {
  998. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  999. if (I2CCount != 0) I2CCount--;
  1000. while (!(TWI0.MSTATUS & TWI_RIF_bm)); // Wait for read interrupt flag
  1001. uint8_t data = TWI0.MDATA;
  1002. // Check slave sent ACK?
  1003. if (I2CCount != 0) TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // ACK = more bytes to read
  1004. else TWI0.MCTRLB = TWI_ACKACT_bm | TWI_MCMD_RECVTRANS_gc; // Send NAK
  1005. return data;
  1006. #else
  1007. if (I2CCount != 0) I2CCount--;
  1008. TWCR = 1<<TWINT | 1<<TWEN | ((I2CCount == 0) ? 0 : (1<<TWEA));
  1009. while (!(TWCR & 1<<TWINT));
  1010. return TWDR;
  1011. #endif
  1012. }
  1013. bool I2Cwrite (uint8_t data) {
  1014. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  1015. while (!(TWI0.MSTATUS & TWI_WIF_bm)); // Wait for write interrupt flag
  1016. TWI0.MDATA = data;
  1017. TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // Do nothing
  1018. return !(TWI0.MSTATUS & TWI_RXACK_bm); // Returns true if slave gave an ACK
  1019. #else
  1020. TWDR = data;
  1021. TWCR = 1<<TWINT | 1 << TWEN;
  1022. while (!(TWCR & 1<<TWINT));
  1023. return (TWSR & 0xF8) == TWSR_MTX_DATA_ACK;
  1024. #endif
  1025. }
  1026. bool I2Cstart (uint8_t address, uint8_t read) {
  1027. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  1028. TWI0.MADDR = address<<1 | read; // Send START condition
  1029. while (!(TWI0.MSTATUS & (TWI_WIF_bm | TWI_RIF_bm))); // Wait for write or read interrupt flag
  1030. if ((TWI0.MSTATUS & TWI_ARBLOST_bm)) return false; // Return false if arbitration lost or bus error
  1031. return !(TWI0.MSTATUS & TWI_RXACK_bm); // Return true if slave gave an ACK
  1032. #else
  1033. uint8_t addressRW = address<<1 | read;
  1034. TWCR = 1<<TWINT | 1<<TWSTA | 1<<TWEN; // Send START condition
  1035. while (!(TWCR & 1<<TWINT));
  1036. if ((TWSR & 0xF8) != TWSR_START && (TWSR & 0xF8) != TWSR_REP_START) return false;
  1037. TWDR = addressRW; // send device address and direction
  1038. TWCR = 1<<TWINT | 1<<TWEN;
  1039. while (!(TWCR & 1<<TWINT));
  1040. if (addressRW & I2C_READ) return (TWSR & 0xF8) == TWSR_MRX_ADR_ACK;
  1041. else return (TWSR & 0xF8) == TWSR_MTX_ADR_ACK;
  1042. #endif
  1043. }
  1044. bool I2Crestart (uint8_t address, uint8_t read) {
  1045. return I2Cstart(address, read);
  1046. }
  1047. void I2Cstop (uint8_t read) {
  1048. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  1049. (void) read;
  1050. TWI0.MCTRLB = TWI_ACKACT_bm | TWI_MCMD_STOP_gc; // Send STOP
  1051. #else
  1052. (void) read;
  1053. TWCR = 1<<TWINT | 1<<TWEN | 1<<TWSTO;
  1054. while (TWCR & 1<<TWSTO); // wait until stop and bus released
  1055. #endif
  1056. }
  1057. // Streams
  1058. inline int spiread () { return SPI.transfer(0); }
  1059. #if defined(CPU_ATmega1284P)
  1060. inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
  1061. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1062. inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
  1063. inline int serial2read () { while (!Serial2.available()) testescape(); return Serial2.read(); }
  1064. inline int serial3read () { while (!Serial3.available()) testescape(); return Serial3.read(); }
  1065. #endif
  1066. #if defined(sdcardsupport)
  1067. File SDpfile, SDgfile;
  1068. inline int SDread () {
  1069. if (LastChar) {
  1070. char temp = LastChar;
  1071. LastChar = 0;
  1072. return temp;
  1073. }
  1074. return SDgfile.read();
  1075. }
  1076. #endif
  1077. void serialbegin (int address, int baud) {
  1078. #if defined(CPU_ATmega328P)
  1079. (void) address; (void) baud;
  1080. #elif defined(CPU_ATmega1284P)
  1081. if (address == 1) Serial1.begin((long)baud*100);
  1082. else error(WITHSERIAL, PSTR("port not supported"), number(address));
  1083. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1084. if (address == 1) Serial1.begin((long)baud*100);
  1085. else if (address == 2) Serial2.begin((long)baud*100);
  1086. else if (address == 3) Serial3.begin((long)baud*100);
  1087. else error(WITHSERIAL, PSTR("port not supported"), number(address));
  1088. #endif
  1089. }
  1090. void serialend (int address) {
  1091. #if defined(CPU_ATmega328P)
  1092. (void) address;
  1093. #elif defined(CPU_ATmega1284P)
  1094. if (address == 1) {Serial1.flush(); Serial1.end(); }
  1095. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1096. if (address == 1) {Serial1.flush(); Serial1.end(); }
  1097. else if (address == 2) {Serial2.flush(); Serial2.end(); }
  1098. else if (address == 3) {Serial3.flush(); Serial3.end(); }
  1099. #endif
  1100. }
  1101. gfun_t gstreamfun (object *args) {
  1102. int streamtype = SERIALSTREAM;
  1103. int address = 0;
  1104. gfun_t gfun = gserial;
  1105. if (args != NULL) {
  1106. int stream = isstream(first(args));
  1107. streamtype = stream>>8; address = stream & 0xFF;
  1108. }
  1109. if (streamtype == I2CSTREAM) gfun = (gfun_t)I2Cread;
  1110. else if (streamtype == SPISTREAM) gfun = spiread;
  1111. else if (streamtype == SERIALSTREAM) {
  1112. if (address == 0) gfun = gserial;
  1113. #if defined(CPU_ATmega1284P)
  1114. else if (address == 1) gfun = serial1read;
  1115. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1116. else if (address == 1) gfun = serial1read;
  1117. else if (address == 2) gfun = serial2read;
  1118. else if (address == 3) gfun = serial3read;
  1119. #endif
  1120. }
  1121. #if defined(sdcardsupport)
  1122. else if (streamtype == SDSTREAM) gfun = (gfun_t)SDread;
  1123. #endif
  1124. else error2(0, PSTR("Unknown stream type"));
  1125. return gfun;
  1126. }
  1127. inline void spiwrite (char c) { SPI.transfer(c); }
  1128. #if defined(CPU_ATmega1284P)
  1129. inline void serial1write (char c) { Serial1.write(c); }
  1130. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1131. inline void serial1write (char c) { Serial1.write(c); }
  1132. inline void serial2write (char c) { Serial2.write(c); }
  1133. inline void serial3write (char c) { Serial3.write(c); }
  1134. #endif
  1135. #if defined(sdcardsupport)
  1136. inline void SDwrite (char c) { SDpfile.write(c); }
  1137. #endif
  1138. pfun_t pstreamfun (object *args) {
  1139. int streamtype = SERIALSTREAM;
  1140. int address = 0;
  1141. pfun_t pfun = pserial;
  1142. if (args != NULL && first(args) != NULL) {
  1143. int stream = isstream(first(args));
  1144. streamtype = stream>>8; address = stream & 0xFF;
  1145. }
  1146. if (streamtype == I2CSTREAM) pfun = (pfun_t)I2Cwrite;
  1147. else if (streamtype == SPISTREAM) pfun = spiwrite;
  1148. else if (streamtype == SERIALSTREAM) {
  1149. if (address == 0) pfun = pserial;
  1150. #if defined(CPU_ATmega1284P)
  1151. else if (address == 1) pfun = serial1write;
  1152. #elif defined(CPU_ATmega2560) || defined(CPU_AVR128DA48)
  1153. else if (address == 1) pfun = serial1write;
  1154. else if (address == 2) pfun = serial2write;
  1155. else if (address == 3) pfun = serial3write;
  1156. #endif
  1157. }
  1158. else if (streamtype == STRINGSTREAM) {
  1159. pfun = pstr;
  1160. }
  1161. #if defined(sdcardsupport)
  1162. else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite;
  1163. #endif
  1164. else error2(0, PSTR("unknown stream type"));
  1165. return pfun;
  1166. }
  1167. // Check pins - these are board-specific not processor-specific
  1168. void checkanalogread (int pin) {
  1169. #if defined(__AVR_ATmega328P__)
  1170. if (!(pin>=0 && pin<=5)) error(ANALOGREAD, invalidpin, number(pin));
  1171. #elif defined(__AVR_ATmega2560__)
  1172. if (!(pin>=0 && pin<=15)) error(ANALOGREAD, invalidpin, number(pin));
  1173. #elif defined(__AVR_ATmega1284P__)
  1174. if (!(pin>=0 && pin<=7)) error(ANALOGREAD, invalidpin, number(pin));
  1175. #elif defined(ARDUINO_AVR_NANO_EVERY)
  1176. if (!((pin>=14 && pin<=21))) error(ANALOGREAD, invalidpin, number(pin));
  1177. #elif defined(ARDUINO_AVR_ATmega4809) /* MegaCoreX core */
  1178. if (!((pin>=22 && pin<=33) || (pin>=36 && pin<=39))) error(ANALOGREAD, invalidpin, number(pin));
  1179. #elif defined(__AVR_ATmega4809__)
  1180. if (!(pin>=14 && pin<=21)) error(ANALOGREAD, invalidpin, number(pin));
  1181. #elif defined(__AVR_AVR128DA48__)
  1182. if (!(pin>=22 && pin<=39)) error(ANALOGREAD, invalidpin, number(pin));
  1183. #endif
  1184. }
  1185. void checkanalogwrite (int pin) {
  1186. #if defined(__AVR_ATmega328P__)
  1187. if (!((pin>=2 && pin<=13) || pin==4 || pin==7 || pin==8)) error(ANALOGWRITE, invalidpin, number(pin));
  1188. #elif defined(__AVR_ATmega2560__)
  1189. if (!((pin>=2 && pin<=13) || (pin>=44 && pin<=46))) error(ANALOGWRITE, invalidpin, number(pin));
  1190. #elif defined(__AVR_ATmega1284P__)
  1191. if (!(pin==3 || pin==4 || pin==6 || pin==7 || (pin>=12 && pin<=15))) error(ANALOGWRITE, invalidpin, number(pin));
  1192. #elif defined(ARDUINO_AVR_NANO_EVERY)
  1193. if (!(pin==3 || (pin>=5 && pin<=6) || (pin>=9 && pin<=11))) error(ANALOGWRITE, invalidpin, number(pin));
  1194. #elif defined(ARDUINO_AVR_ATmega4809) /* MegaCoreX core */
  1195. if (!((pin>=16 && pin<=19) || (pin>=38 && pin<=39))) error(ANALOGWRITE, invalidpin, number(pin));
  1196. #elif defined(__AVR_ATmega4809__)
  1197. if (!(pin==3 || pin==5 || pin==6 || pin==9 || pin==10)) error(ANALOGWRITE, invalidpin, number(pin));
  1198. #elif defined(__AVR_AVR128DA48__)
  1199. if (!((pin>=4 && pin<=5) || (pin>=8 && pin<=19) || (pin>=38 && pin<=39))) error(ANALOGREAD, invalidpin, number(pin));
  1200. #endif
  1201. }
  1202. // Note
  1203. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  1204. const int scale[] PROGMEM = {4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902};
  1205. #else
  1206. const uint8_t scale[] PROGMEM = {239,226,213,201,190,179,169,160,151,142,134,127};
  1207. #endif
  1208. void playnote (int pin, int note, int octave) {
  1209. #if defined(CPU_ATmega328P)
  1210. if (pin == 3) {
  1211. DDRD = DDRD | 1<<DDD3; // PD3 (Arduino D3) as output
  1212. TCCR2A = 0<<COM2A0 | 1<<COM2B0 | 2<<WGM20; // Toggle OC2B on match
  1213. } else if (pin == 11) {
  1214. DDRB = DDRB | 1<<DDB3; // PB3 (Arduino D11) as output
  1215. TCCR2A = 1<<COM2A0 | 0<<COM2B0 | 2<<WGM20; // Toggle OC2A on match
  1216. } else error(NOTE, invalidpin, number(pin));
  1217. int prescaler = 9 - octave - note/12;
  1218. if (prescaler<3 || prescaler>6) error(NOTE, PSTR("octave out of range"), number(prescaler));
  1219. OCR2A = pgm_read_byte(&scale[note%12]) - 1;
  1220. TCCR2B = 0<<WGM22 | prescaler<<CS20;
  1221. #elif defined(CPU_ATmega2560)
  1222. if (pin == 9) {
  1223. DDRH = DDRH | 1<<DDH6; // PH6 (Arduino D9) as output
  1224. TCCR2A = 0<<COM2A0 | 1<<COM2B0 | 2<<WGM20; // Toggle OC2B on match
  1225. } else if (pin == 10) {
  1226. DDRB = DDRB | 1<<DDB4; // PB4 (Arduino D10) as output
  1227. TCCR2A = 1<<COM2A0 | 0<<COM2B0 | 2<<WGM20; // Toggle OC2A on match
  1228. } else error(NOTE, invalidpin, number(pin));
  1229. int prescaler = 9 - octave - note/12;
  1230. if (prescaler<3 || prescaler>6) error(NOTE, PSTR("octave out of range"), number(prescaler));
  1231. OCR2A = pgm_read_byte(&scale[note%12]) - 1;
  1232. TCCR2B = 0<<WGM22 | prescaler<<CS20;
  1233. #elif defined(CPU_ATmega1284P)
  1234. if (pin == 14) {
  1235. DDRD = DDRD | 1<<DDD6; // PD6 (Arduino D14) as output
  1236. TCCR2A = 0<<COM2A0 | 1<<COM2B0 | 2<<WGM20; // Toggle OC2B on match
  1237. } else if (pin == 15) {
  1238. DDRD = DDRD | 1<<DDD7; // PD7 (Arduino D15) as output
  1239. TCCR2A = 1<<COM2A0 | 0<<COM2B0 | 2<<WGM20; // Toggle OC2A on match
  1240. } else error(NOTE, invalidpin, number(pin));
  1241. int prescaler = 9 - octave - note/12;
  1242. if (prescaler<3 || prescaler>6) error(NOTE, PSTR("octave out of range"), number(prescaler));
  1243. OCR2A = pgm_read_byte(&scale[note%12]) - 1;
  1244. TCCR2B = 0<<WGM22 | prescaler<<CS20;
  1245. #elif defined(CPU_ATmega4809)
  1246. int prescaler = 8 - octave - note/12;
  1247. if (prescaler<0 || prescaler>8) error(NOTE, PSTR("octave out of range"), number(prescaler));
  1248. tone(pin, scale[note%12]>>prescaler);
  1249. #elif defined(CPU_AVR128DA48)
  1250. int prescaler = 8 - octave - note/12;
  1251. if (prescaler<0 || prescaler>8) error(NOTE, PSTR("octave out of range"), number(prescaler));
  1252. tone(pin, pgm_read_word(&scale[note%12])>>prescaler);
  1253. #endif
  1254. }
  1255. void nonote (int pin) {
  1256. #if defined(CPU_ATmega4809) || defined(CPU_AVR128DA48)
  1257. noTone(pin);
  1258. #else
  1259. (void) pin;
  1260. TCCR2B = 0<<WGM22 | 0<<CS20;
  1261. #endif
  1262. }
  1263. // Sleep
  1264. #if !defined(CPU_ATmega4809) && !defined(CPU_AVR128DA48)
  1265. // Interrupt vector for sleep watchdog
  1266. ISR(WDT_vect) {
  1267. WDTCSR |= 1<<WDIE;
  1268. }
  1269. #endif
  1270. void initsleep () {
  1271. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  1272. }
  1273. void sleep (int secs) {
  1274. #if !defined(CPU_ATmega4809) && !defined(CPU_AVR128DA48)
  1275. // Set up Watchdog timer for 1 Hz interrupt
  1276. WDTCSR = 1<<WDCE | 1<<WDE;
  1277. WDTCSR = 1<<WDIE | 6<<WDP0; // 1 sec interrupt
  1278. delay(100); // Give serial time to settle
  1279. // Disable ADC and timer 0
  1280. ADCSRA = ADCSRA & ~(1<<ADEN);
  1281. #if defined(CPU_ATmega328P)
  1282. PRR = PRR | 1<<PRTIM0;
  1283. #elif defined(CPU_ATmega2560) || defined(CPU_ATmega1284P)
  1284. PRR0 = PRR0 | 1<<PRTIM0;
  1285. #endif
  1286. while (secs > 0) {
  1287. sleep_enable();
  1288. sleep_cpu();
  1289. secs--;
  1290. }
  1291. WDTCSR = 1<<WDCE | 1<<WDE; // Disable watchdog
  1292. WDTCSR = 0;
  1293. // Enable ADC and timer 0
  1294. ADCSRA = ADCSRA | 1<<ADEN;
  1295. #if defined(CPU_ATmega328P)
  1296. PRR = PRR & ~(1<<PRTIM0);
  1297. #elif defined(CPU_ATmega2560) || defined(CPU_ATmega1284P)
  1298. PRR0 = PRR0 & ~(1<<PRTIM0);
  1299. #endif
  1300. #else
  1301. delay(1000*secs);
  1302. #endif
  1303. }
  1304. // Prettyprint
  1305. const int PPINDENT = 2;
  1306. const int PPWIDTH = 80;
  1307. void pcount (char c) {
  1308. if (c == '\n') PrintCount++;
  1309. PrintCount++;
  1310. }
  1311. uint8_t atomwidth (object *obj) {
  1312. PrintCount = 0;
  1313. printobject(obj, pcount);
  1314. return PrintCount;
  1315. }
  1316. uint8_t hexwidth (object *obj) {
  1317. PrintCount = 0;
  1318. pinthex(obj->integer, pcount);
  1319. return PrintCount;
  1320. }
  1321. boolean quoted (object *obj) {
  1322. return (consp(obj) && car(obj) != NULL && car(obj)->name == QUOTE && consp(cdr(obj)) && cddr(obj) == NULL);
  1323. }
  1324. int subwidth (object *obj, int w) {
  1325. if (atom(obj)) return w - atomwidth(obj);
  1326. if (quoted(obj)) return subwidthlist(car(cdr(obj)), w - 1);
  1327. return subwidthlist(obj, w - 1);
  1328. }
  1329. int subwidthlist (object *form, int w) {
  1330. while (form != NULL && w >= 0) {
  1331. if (atom(form)) return w - (2 + atomwidth(form));
  1332. w = subwidth(car(form), w - 1);
  1333. form = cdr(form);
  1334. }
  1335. return w;
  1336. }
  1337. void superprint (object *form, int lm, pfun_t pfun) {
  1338. if (atom(form)) {
  1339. if (symbolp(form) && form->name == NOTHING) pstring(symbolname(form->name), pfun);
  1340. else printobject(form, pfun);
  1341. }
  1342. else if (quoted(form)) { pfun('\''); superprint(car(cdr(form)), lm + 1, pfun); }
  1343. else if (subwidth(form, PPWIDTH - lm) >= 0) supersub(form, lm + PPINDENT, 0, pfun);
  1344. else supersub(form, lm + PPINDENT, 1, pfun);
  1345. }
  1346. const int ppspecials = 15;
  1347. const uint8_t ppspecial[ppspecials] PROGMEM =
  1348. { DOTIMES, DOLIST, IF, SETQ, TEE, LET, LETSTAR, LAMBDA, WHEN, UNLESS, WITHI2C, WITHSERIAL, WITHSPI, WITHSDCARD, FORMILLIS };
  1349. void supersub (object *form, int lm, int super, pfun_t pfun) {
  1350. int special = 0, separate = 1;
  1351. object *arg = car(form);
  1352. if (symbolp(arg)) {
  1353. int name = arg->name;
  1354. if (name == DEFUN) special = 2;
  1355. else for (int i=0; i<ppspecials; i++) {
  1356. #if defined(CPU_ATmega4809)
  1357. if (name == ppspecial[i]) { special = 1; break; }
  1358. #else
  1359. if (name == pgm_read_byte(&ppspecial[i])) { special = 1; break; }
  1360. #endif
  1361. }
  1362. }
  1363. while (form != NULL) {
  1364. if (atom(form)) { pfstring(PSTR(" . "), pfun); printobject(form, pfun); pfun(')'); return; }
  1365. else if (separate) { pfun('('); separate = 0; }
  1366. else if (special) { pfun(' '); special--; }
  1367. else if (!super) pfun(' ');
  1368. else { pln(pfun); indent(lm, ' ', pfun); }
  1369. superprint(car(form), lm, pfun);
  1370. form = cdr(form);
  1371. }
  1372. pfun(')'); return;
  1373. }
  1374. // Special forms
  1375. object *sp_quote (object *args, object *env) {
  1376. (void) env;
  1377. checkargs(QUOTE, args);
  1378. return first(args);
  1379. }
  1380. object *sp_defun (object *args, object *env) {
  1381. (void) env;
  1382. checkargs(DEFUN, args);
  1383. object *var = first(args);
  1384. if (!symbolp(var)) error(DEFUN, notasymbol, var);
  1385. object *val = cons(symbol(LAMBDA), cdr(args));
  1386. object *pair = value(var->name,GlobalEnv);
  1387. if (pair != NULL) cdr(pair) = val;
  1388. else push(cons(var, val), GlobalEnv);
  1389. return var;
  1390. }
  1391. object *sp_defvar (object *args, object *env) {
  1392. checkargs(DEFVAR, args);
  1393. object *var = first(args);
  1394. if (!symbolp(var)) error(DEFVAR, notasymbol, var);
  1395. object *val = NULL;
  1396. args = cdr(args);
  1397. if (args != NULL) { setflag(NOESC); val = eval(first(args), env); clrflag(NOESC); }
  1398. object *pair = value(var->name, GlobalEnv);
  1399. if (pair != NULL) cdr(pair) = val;
  1400. else push(cons(var, val), GlobalEnv);
  1401. return var;
  1402. }
  1403. object *sp_setq (object *args, object *env) {
  1404. object *arg = nil;
  1405. while (args != NULL) {
  1406. if (cdr(args) == NULL) error2(SETQ, oddargs);
  1407. object *pair = findvalue(first(args), env);
  1408. arg = eval(second(args), env);
  1409. cdr(pair) = arg;
  1410. args = cddr(args);
  1411. }
  1412. return arg;
  1413. }
  1414. object *sp_loop (object *args, object *env) {
  1415. object *start = args;
  1416. for (;;) {
  1417. args = start;
  1418. while (args != NULL) {
  1419. object *result = eval(car(args),env);
  1420. if (tstflag(RETURNFLAG)) {
  1421. clrflag(RETURNFLAG);
  1422. return result;
  1423. }
  1424. args = cdr(args);
  1425. }
  1426. }
  1427. }
  1428. object *sp_return (object *args, object *env) {
  1429. object *result = eval(tf_progn(args,env), env);
  1430. setflag(RETURNFLAG);
  1431. return result;
  1432. }
  1433. object *sp_push (object *args, object *env) {
  1434. checkargs(PUSH, args);
  1435. object *item = eval(first(args), env);
  1436. object **loc = place(PUSH, second(args), env);
  1437. push(item, *loc);
  1438. return *loc;
  1439. }
  1440. object *sp_pop (object *args, object *env) {
  1441. checkargs(POP, args);
  1442. object **loc = place(POP, first(args), env);
  1443. object *result = car(*loc);
  1444. pop(*loc);
  1445. return result;
  1446. }
  1447. // Accessors
  1448. object *incfdecf (symbol_t name, object *args, int increment, object *env) {
  1449. checkargs(name, args);
  1450. object **loc = place(name, first(args), env);
  1451. int result = checkinteger(name, *loc);
  1452. args = cdr(args);
  1453. if (args != NULL) increment = checkinteger(name, eval(first(args), env)) * increment;
  1454. #if defined(checkoverflow)
  1455. if (increment < 1) { if (INT_MIN - increment > result) error2(name, overflow); }
  1456. else { if (INT_MAX - increment < result) error2(name, overflow); }
  1457. #endif
  1458. result = result + increment;
  1459. *loc = number(result);
  1460. return *loc;
  1461. }
  1462. object *sp_incf (object *args, object *env) {
  1463. incfdecf(INCF, args, 1, env);
  1464. }
  1465. object *sp_decf (object *args, object *env) {
  1466. incfdecf(DECF, args, -1, env);
  1467. }
  1468. object *sp_setf (object *args, object *env) {
  1469. object *arg = nil;
  1470. while (args != NULL) {
  1471. if (cdr(args) == NULL) error2(SETF, oddargs);
  1472. object **loc = place(SETF, first(args), env);
  1473. arg = eval(second(args), env);
  1474. *loc = arg;
  1475. args = cddr(args);
  1476. }
  1477. return arg;
  1478. }
  1479. // Other special forms
  1480. object *sp_dolist (object *args, object *env) {
  1481. if (args == NULL || listlength(DOLIST, first(args)) < 2) error2(DOLIST, noargument);
  1482. object *params = first(args);
  1483. object *var = first(params);
  1484. object *list = eval(second(params), env);
  1485. push(list, GCStack); // Don't GC the list
  1486. object *pair = cons(var,nil);
  1487. push(pair,env);
  1488. params = cdr(cdr(params));
  1489. args = cdr(args);
  1490. while (list != NULL) {
  1491. if (improperp(list)) error(DOLIST, notproper, list);
  1492. cdr(pair) = first(list);
  1493. object *forms = args;
  1494. while (forms != NULL) {
  1495. object *result = eval(car(forms), env);
  1496. if (tstflag(RETURNFLAG)) {
  1497. clrflag(RETURNFLAG);
  1498. pop(GCStack);
  1499. return result;
  1500. }
  1501. forms = cdr(forms);
  1502. }
  1503. list = cdr(list);
  1504. }
  1505. cdr(pair) = nil;
  1506. pop(GCStack);
  1507. if (params == NULL) return nil;
  1508. return eval(car(params), env);
  1509. }
  1510. object *sp_dotimes (object *args, object *env) {
  1511. if (args == NULL || listlength(DOTIMES, first(args)) < 2) error2(DOTIMES, noargument);
  1512. object *params = first(args);
  1513. object *var = first(params);
  1514. int count = checkinteger(DOTIMES, eval(second(params), env));
  1515. int index = 0;
  1516. params = cdr(cdr(params));
  1517. object *pair = cons(var,number(0));
  1518. push(pair,env);
  1519. args = cdr(args);
  1520. while (index < count) {
  1521. cdr(pair) = number(index);
  1522. object *forms = args;
  1523. while (forms != NULL) {
  1524. object *result = eval(car(forms), env);
  1525. if (tstflag(RETURNFLAG)) {
  1526. clrflag(RETURNFLAG);
  1527. return result;
  1528. }
  1529. forms = cdr(forms);
  1530. }
  1531. index++;
  1532. }
  1533. cdr(pair) = number(index);
  1534. if (params == NULL) return nil;
  1535. return eval(car(params), env);
  1536. }
  1537. object *sp_trace (object *args, object *env) {
  1538. (void) env;
  1539. while (args != NULL) {
  1540. object *var = first(args);
  1541. if (!symbolp(var)) error(TRACE, notasymbol, var);
  1542. trace(var->name);
  1543. args = cdr(args);
  1544. }
  1545. int i = 0;
  1546. while (i < TRACEMAX) {
  1547. if (TraceFn[i] != 0) args = cons(symbol(TraceFn[i]), args);
  1548. i++;
  1549. }
  1550. return args;
  1551. }
  1552. object *sp_untrace (object *args, object *env) {
  1553. (void) env;
  1554. if (args == NULL) {
  1555. int i = 0;
  1556. while (i < TRACEMAX) {
  1557. if (TraceFn[i] != 0) args = cons(symbol(TraceFn[i]), args);
  1558. TraceFn[i] = 0;
  1559. i++;
  1560. }
  1561. } else {
  1562. while (args != NULL) {
  1563. object *var = first(args);
  1564. if (!symbolp(var)) error(UNTRACE, notasymbol, var);
  1565. untrace(var->name);
  1566. args = cdr(args);
  1567. }
  1568. }
  1569. return args;
  1570. }
  1571. object *sp_formillis (object *args, object *env) {
  1572. object *param = first(args);
  1573. unsigned long start = millis();
  1574. unsigned long now, total = 0;
  1575. if (param != NULL) total = checkinteger(FORMILLIS, eval(first(param), env));
  1576. eval(tf_progn(cdr(args),env), env);
  1577. do {
  1578. now = millis() - start;
  1579. testescape();
  1580. } while (now < total);
  1581. if (now <= INT_MAX) return number(now);
  1582. return nil;
  1583. }
  1584. object *sp_withserial (object *args, object *env) {
  1585. object *params = first(args);
  1586. if (params == NULL) error2(WITHSERIAL, nostream);
  1587. object *var = first(params);
  1588. int address = checkinteger(WITHSERIAL, eval(second(params), env));
  1589. params = cddr(params);
  1590. int baud = 96;
  1591. if (params != NULL) baud = checkinteger(WITHSERIAL, eval(first(params), env));
  1592. object *pair = cons(var, stream(SERIALSTREAM, address));
  1593. push(pair,env);
  1594. serialbegin(address, baud);
  1595. object *forms = cdr(args);
  1596. object *result = eval(tf_progn(forms,env), env);
  1597. serialend(address);
  1598. return result;
  1599. }
  1600. object *sp_withi2c (object *args, object *env) {
  1601. object *params = first(args);
  1602. if (params == NULL) error2(WITHI2C, nostream);
  1603. object *var = first(params);
  1604. int address = checkinteger(WITHI2C, eval(second(params), env));
  1605. params = cddr(params);
  1606. int read = 0; // Write
  1607. I2CCount = 0;
  1608. if (params != NULL) {
  1609. object *rw = eval(first(params), env);
  1610. if (integerp(rw)) I2CCount = rw->integer;
  1611. read = (rw != NULL);
  1612. }
  1613. I2Cinit(1); // Pullups
  1614. object *pair = cons(var, (I2Cstart(address, read)) ? stream(I2CSTREAM, address) : nil);
  1615. push(pair,env);
  1616. object *forms = cdr(args);
  1617. object *result = eval(tf_progn(forms,env), env);
  1618. I2Cstop(read);
  1619. return result;
  1620. }
  1621. object *sp_withspi (object *args, object *env) {
  1622. object *params = first(args);
  1623. if (params == NULL) error2(WITHSPI, nostream);
  1624. object *var = first(params);
  1625. params = cdr(params);
  1626. if (params == NULL) error2(WITHSPI, nostream);
  1627. int pin = checkinteger(WITHSPI, eval(car(params), env));
  1628. pinMode(pin, OUTPUT);
  1629. digitalWrite(pin, HIGH);
  1630. params = cdr(params);
  1631. int clock = 4000, mode = SPI_MODE0; // Defaults
  1632. BitOrder bitorder = MSBFIRST;
  1633. if (params != NULL) {
  1634. clock = checkinteger(WITHSPI, eval(car(params), env));
  1635. params = cdr(params);
  1636. if (params != NULL) {
  1637. bitorder = (checkinteger(WITHSPI, eval(car(params), env)) == 0) ? LSBFIRST : MSBFIRST;
  1638. params = cdr(params);
  1639. if (params != NULL) {
  1640. int modeval = checkinteger(WITHSPI, eval(car(params), env));
  1641. mode = (modeval == 3) ? SPI_MODE3 : (modeval == 2) ? SPI_MODE2 : (modeval == 1) ? SPI_MODE1 : SPI_MODE0;
  1642. }
  1643. }
  1644. }
  1645. object *pair = cons(var, stream(SPISTREAM, pin));
  1646. push(pair,env);
  1647. SPI.begin();
  1648. SPI.beginTransaction(SPISettings(((unsigned long)clock * 1000), bitorder, mode));
  1649. digitalWrite(pin, LOW);
  1650. object *forms = cdr(args);
  1651. object *result = eval(tf_progn(forms,env), env);
  1652. digitalWrite(pin, HIGH);
  1653. SPI.endTransaction();
  1654. return result;
  1655. }
  1656. object *sp_withsdcard (object *args, object *env) {
  1657. #if defined(sdcardsupport)
  1658. object *params = first(args);
  1659. if (params == NULL) error2(WITHSDCARD, nostream);
  1660. object *var = first(params);
  1661. object *filename = eval(second(params), env);
  1662. params = cddr(params);
  1663. SD.begin(SDCARD_SS_PIN);
  1664. int mode = 0;
  1665. if (params != NULL && first(params) != NULL) mode = checkinteger(WITHSDCARD, first(params));
  1666. int oflag = O_READ;
  1667. if (mode == 1) oflag = O_RDWR | O_CREAT | O_APPEND; else if (mode == 2) oflag = O_RDWR | O_CREAT | O_TRUNC;
  1668. if (mode >= 1) {
  1669. SDpfile = SD.open(MakeFilename(filename), oflag);
  1670. if (!SDpfile) error2(WITHSDCARD, PSTR("problem writing to SD card"));
  1671. } else {
  1672. SDgfile = SD.open(MakeFilename(filename), oflag);
  1673. if (!SDgfile) error2(WITHSDCARD, PSTR("problem reading from SD card"));
  1674. }
  1675. object *pair = cons(var, stream(SDSTREAM, 1));
  1676. push(pair,env);
  1677. object *forms = cdr(args);
  1678. object *result = eval(tf_progn(forms,env), env);
  1679. if (mode >= 1) SDpfile.close(); else SDgfile.close();
  1680. return result;
  1681. #else
  1682. (void) args, (void) env;
  1683. error2(WITHSDCARD, PSTR("not supported"));
  1684. return nil;
  1685. #endif
  1686. }
  1687. // Tail-recursive forms
  1688. object *tf_progn (object *args, object *env) {
  1689. if (args == NULL) return nil;
  1690. object *more = cdr(args);
  1691. while (more != NULL) {
  1692. object *result = eval(car(args),env);
  1693. if (tstflag(RETURNFLAG)) return result;
  1694. args = more;
  1695. more = cdr(args);
  1696. }
  1697. return car(args);
  1698. }
  1699. object *tf_if (object *args, object *env) {
  1700. if (args == NULL || cdr(args) == NULL) error2(IF, PSTR("missing argument(s)"));
  1701. if (eval(first(args), env) != nil) return second(args);
  1702. args = cddr(args);
  1703. return (args != NULL) ? first(args) : nil;
  1704. }
  1705. object *tf_cond (object *args, object *env) {
  1706. while (args != NULL) {
  1707. object *clause = first(args);
  1708. if (!consp(clause)) error(COND, PSTR("illegal clause"), clause);
  1709. object *test = eval(first(clause), env);
  1710. object *forms = cdr(clause);
  1711. if (test != nil) {
  1712. if (forms == NULL) return quote(test); else return tf_progn(forms, env);
  1713. }
  1714. args = cdr(args);
  1715. }
  1716. return nil;
  1717. }
  1718. object *tf_when (object *args, object *env) {
  1719. if (args == NULL) error2(WHEN, noargument);
  1720. if (eval(first(args), env) != nil) return tf_progn(cdr(args),env);
  1721. else return nil;
  1722. }
  1723. object *tf_unless (object *args, object *env) {
  1724. if (args == NULL) error2(UNLESS, noargument);
  1725. if (eval(first(args), env) != nil) return nil;
  1726. else return tf_progn(cdr(args),env);
  1727. }
  1728. object *tf_case (object *args, object *env) {
  1729. object *test = eval(first(args), env);
  1730. args = cdr(args);
  1731. while (args != NULL) {
  1732. object *clause = first(args);
  1733. if (!consp(clause)) error(CASE, PSTR("illegal clause"), clause);
  1734. object *key = car(clause);
  1735. object *forms = cdr(clause);
  1736. if (consp(key)) {
  1737. while (key != NULL) {
  1738. if (eq(test,car(key))) return tf_progn(forms, env);
  1739. key = cdr(key);
  1740. }
  1741. } else if (eq(test,key) || eq(key,tee)) return tf_progn(forms, env);
  1742. args = cdr(args);
  1743. }
  1744. return nil;
  1745. }
  1746. object *tf_and (object *args, object *env) {
  1747. if (args == NULL) return tee;
  1748. object *more = cdr(args);
  1749. while (more != NULL) {
  1750. if (eval(car(args), env) == NULL) return nil;
  1751. args = more;
  1752. more = cdr(args);
  1753. }
  1754. return car(args);
  1755. }
  1756. object *tf_or (object *args, object *env) {
  1757. while (args != NULL) {
  1758. if (eval(car(args), env) != NULL) return car(args);
  1759. args = cdr(args);
  1760. }
  1761. return nil;
  1762. }
  1763. // Core functions
  1764. object *fn_not (object *args, object *env) {
  1765. (void) env;
  1766. return (first(args) == nil) ? tee : nil;
  1767. }
  1768. object *fn_cons (object *args, object *env) {
  1769. (void) env;
  1770. return cons(first(args), second(args));
  1771. }
  1772. object *fn_atom (object *args, object *env) {
  1773. (void) env;
  1774. return atom(first(args)) ? tee : nil;
  1775. }
  1776. object *fn_listp (object *args, object *env) {
  1777. (void) env;
  1778. return listp(first(args)) ? tee : nil;
  1779. }
  1780. object *fn_consp (object *args, object *env) {
  1781. (void) env;
  1782. return consp(first(args)) ? tee : nil;
  1783. }
  1784. object *fn_symbolp (object *args, object *env) {
  1785. (void) env;
  1786. object *arg = first(args);
  1787. return symbolp(arg) ? tee : nil;
  1788. }
  1789. object *fn_boundp (object *args, object *env) {
  1790. (void) env;
  1791. object *var = first(args);
  1792. if (!symbolp(var)) error(BOUNDP, notasymbol, var);
  1793. return boundp(var, env) ? tee : nil;
  1794. }
  1795. object *fn_setfn (object *args, object *env) {
  1796. object *arg = nil;
  1797. while (args != NULL) {
  1798. if (cdr(args) == NULL) error2(SETFN, oddargs);
  1799. object *pair = findvalue(first(args), env);
  1800. arg = second(args);
  1801. cdr(pair) = arg;
  1802. args = cddr(args);
  1803. }
  1804. return arg;
  1805. }
  1806. object *fn_streamp (object *args, object *env) {
  1807. (void) env;
  1808. object *arg = first(args);
  1809. return streamp(arg) ? tee : nil;
  1810. }
  1811. object *fn_eq (object *args, object *env) {
  1812. (void) env;
  1813. return eq(first(args), second(args)) ? tee : nil;
  1814. }
  1815. // List functions
  1816. object *fn_car (object *args, object *env) {
  1817. (void) env;
  1818. return carx(first(args));
  1819. }
  1820. object *fn_cdr (object *args, object *env) {
  1821. (void) env;
  1822. return cdrx(first(args));
  1823. }
  1824. object *fn_caar (object *args, object *env) {
  1825. (void) env;
  1826. return carx(carx(first(args)));
  1827. }
  1828. object *fn_cadr (object *args, object *env) {
  1829. (void) env;
  1830. return carx(cdrx(first(args)));
  1831. }
  1832. object *fn_cdar (object *args, object *env) {
  1833. (void) env;
  1834. return cdrx(carx(first(args)));
  1835. }
  1836. object *fn_cddr (object *args, object *env) {
  1837. (void) env;
  1838. return cdrx(cdrx(first(args)));
  1839. }
  1840. object *fn_caaar (object *args, object *env) {
  1841. (void) env;
  1842. return carx(carx(carx(first(args))));
  1843. }
  1844. object *fn_caadr (object *args, object *env) {
  1845. (void) env;
  1846. return carx(carx(cdrx(first(args))));
  1847. }
  1848. object *fn_cadar (object *args, object *env) {
  1849. (void) env;
  1850. return carx(cdrx(carx(first(args))));
  1851. }
  1852. object *fn_caddr (object *args, object *env) {
  1853. (void) env;
  1854. return carx(cdrx(cdrx(first(args))));
  1855. }
  1856. object *fn_cdaar (object *args, object *env) {
  1857. (void) env;
  1858. return cdrx(carx(carx(first(args))));
  1859. }
  1860. object *fn_cdadr (object *args, object *env) {
  1861. (void) env;
  1862. return cdrx(carx(cdrx(first(args))));
  1863. }
  1864. object *fn_cddar (object *args, object *env) {
  1865. (void) env;
  1866. return cdrx(cdrx(carx(first(args))));
  1867. }
  1868. object *fn_cdddr (object *args, object *env) {
  1869. (void) env;
  1870. return cdrx(cdrx(cdrx(first(args))));
  1871. }
  1872. object *fn_length (object *args, object *env) {
  1873. (void) env;
  1874. object *arg = first(args);
  1875. if (listp(arg)) return number(listlength(LENGTH, arg));
  1876. if (!stringp(arg)) error(LENGTH, PSTR("argument is not a list or string"), arg);
  1877. return number(stringlength(arg));
  1878. }
  1879. object *fn_list (object *args, object *env) {
  1880. (void) env;
  1881. return args;
  1882. }
  1883. object *fn_reverse (object *args, object *env) {
  1884. (void) env;
  1885. object *list = first(args);
  1886. object *result = NULL;
  1887. while (list != NULL) {
  1888. if (improperp(list)) error(REVERSE, notproper, list);
  1889. push(first(list),result);
  1890. list = cdr(list);
  1891. }
  1892. return result;
  1893. }
  1894. object *fn_nth (object *args, object *env) {
  1895. (void) env;
  1896. int n = checkinteger(NTH, first(args));
  1897. if (n < 0) error(NTH, indexnegative, first(args));
  1898. object *list = second(args);
  1899. while (list != NULL) {
  1900. if (improperp(list)) error(NTH, notproper, list);
  1901. if (n == 0) return car(list);
  1902. list = cdr(list);
  1903. n--;
  1904. }
  1905. return nil;
  1906. }
  1907. object *fn_assoc (object *args, object *env) {
  1908. (void) env;
  1909. object *key = first(args);
  1910. object *list = second(args);
  1911. return assoc(key,list);
  1912. }
  1913. object *fn_member (object *args, object *env) {
  1914. (void) env;
  1915. object *item = first(args);
  1916. object *list = second(args);
  1917. while (list != NULL) {
  1918. if (improperp(list)) error(MEMBER, notproper, list);
  1919. if (eq(item,car(list))) return list;
  1920. list = cdr(list);
  1921. }
  1922. return nil;
  1923. }
  1924. object *fn_apply (object *args, object *env) {
  1925. object *previous = NULL;
  1926. object *last = args;
  1927. while (cdr(last) != NULL) {
  1928. previous = last;
  1929. last = cdr(last);
  1930. }
  1931. object *arg = car(last);
  1932. if (!listp(arg)) error(APPLY, notalist, arg);
  1933. cdr(previous) = arg;
  1934. return apply(APPLY, first(args), cdr(args), env);
  1935. }
  1936. object *fn_funcall (object *args, object *env) {
  1937. return apply(FUNCALL, first(args), cdr(args), env);
  1938. }
  1939. object *fn_append (object *args, object *env) {
  1940. (void) env;
  1941. object *head = NULL;
  1942. object *tail;
  1943. while (args != NULL) {
  1944. object *list = first(args);
  1945. if (!listp(list)) error(APPEND, notalist, list);
  1946. while (consp(list)) {
  1947. object *obj = cons(car(list), cdr(list));
  1948. if (head == NULL) head = obj;
  1949. else cdr(tail) = obj;
  1950. tail = obj;
  1951. list = cdr(list);
  1952. if (cdr(args) != NULL && improperp(list)) error(APPEND, notproper, first(args));
  1953. }
  1954. args = cdr(args);
  1955. }
  1956. return head;
  1957. }
  1958. object *fn_mapc (object *args, object *env) {
  1959. object *function = first(args);
  1960. args = cdr(args);
  1961. object *result = first(args);
  1962. object *params = cons(NULL, NULL);
  1963. push(params,GCStack);
  1964. // Make parameters
  1965. while (true) {
  1966. object *tailp = params;
  1967. object *lists = args;
  1968. while (lists != NULL) {
  1969. object *list = car(lists);
  1970. if (list == NULL) {
  1971. pop(GCStack);
  1972. return result;
  1973. }
  1974. if (improperp(list)) error(MAPC, notproper, list);
  1975. object *obj = cons(first(list),NULL);
  1976. car(lists) = cdr(list);
  1977. cdr(tailp) = obj; tailp = obj;
  1978. lists = cdr(lists);
  1979. }
  1980. apply(MAPC, function, cdr(params), env);
  1981. }
  1982. }
  1983. void mapcarfun (object *result, object **tail) {
  1984. object *obj = cons(result,NULL);
  1985. cdr(*tail) = obj; *tail = obj;
  1986. }
  1987. void mapcanfun (object *result, object **tail) {
  1988. while (consp(result)) {
  1989. cdr(*tail) = result; *tail = result;
  1990. result = cdr(result);
  1991. }
  1992. if (result != NULL) error(MAPCAN, resultproper, result);
  1993. }
  1994. object *mapcarcan (symbol_t name, object *args, object *env, mapfun_t fun) {
  1995. object *function = first(args);
  1996. args = cdr(args);
  1997. object *params = cons(NULL, NULL);
  1998. push(params,GCStack);
  1999. object *head = cons(NULL, NULL);
  2000. push(head,GCStack);
  2001. object *tail = head;
  2002. // Make parameters
  2003. while (true) {
  2004. object *tailp = params;
  2005. object *lists = args;
  2006. while (lists != NULL) {
  2007. object *list = car(lists);
  2008. if (list == NULL) {
  2009. pop(GCStack);
  2010. pop(GCStack);
  2011. return cdr(head);
  2012. }
  2013. if (improperp(list)) error(name, notproper, list);
  2014. object *obj = cons(first(list),NULL);
  2015. car(lists) = cdr(list);
  2016. cdr(tailp) = obj; tailp = obj;
  2017. lists = cdr(lists);
  2018. }
  2019. object *result = apply(name, function, cdr(params), env);
  2020. fun(result, &tail);
  2021. }
  2022. }
  2023. object *fn_mapcar (object *args, object *env) {
  2024. return mapcarcan(MAPCAR, args, env, mapcarfun);
  2025. }
  2026. object *fn_mapcan (object *args, object *env) {
  2027. return mapcarcan(MAPCAN, args, env, mapcanfun);
  2028. }
  2029. // Arithmetic functions
  2030. object *fn_add (object *args, object *env) {
  2031. (void) env;
  2032. int result = 0;
  2033. while (args != NULL) {
  2034. int temp = checkinteger(ADD, car(args));
  2035. #if defined(checkoverflow)
  2036. if (temp < 1) { if (INT_MIN - temp > result) error2(ADD, overflow); }
  2037. else { if (INT_MAX - temp < result) error2(ADD, overflow); }
  2038. #endif
  2039. result = result + temp;
  2040. args = cdr(args);
  2041. }
  2042. return number(result);
  2043. }
  2044. object *fn_subtract (object *args, object *env) {
  2045. (void) env;
  2046. int result = checkinteger(SUBTRACT, car(args));
  2047. args = cdr(args);
  2048. if (args == NULL) {
  2049. #if defined(checkoverflow)
  2050. if (result == INT_MIN) error2(SUBTRACT, overflow);
  2051. #endif
  2052. return number(-result);
  2053. }
  2054. while (args != NULL) {
  2055. int temp = checkinteger(SUBTRACT, car(args));
  2056. #if defined(checkoverflow)
  2057. if (temp < 1) { if (INT_MAX + temp < result) error2(SUBTRACT, overflow); }
  2058. else { if (INT_MIN + temp > result) error2(SUBTRACT, overflow); }
  2059. #endif
  2060. result = result - temp;
  2061. args = cdr(args);
  2062. }
  2063. return number(result);
  2064. }
  2065. object *fn_multiply (object *args, object *env) {
  2066. (void) env;
  2067. int result = 1;
  2068. while (args != NULL){
  2069. #if defined(checkoverflow)
  2070. signed long temp = (signed long) result * checkinteger(MULTIPLY, car(args));
  2071. if ((temp > INT_MAX) || (temp < INT_MIN)) error2(MULTIPLY, overflow);
  2072. result = temp;
  2073. #else
  2074. result = result * checkinteger(MULTIPLY, car(args));
  2075. #endif
  2076. args = cdr(args);
  2077. }
  2078. return number(result);
  2079. }
  2080. object *fn_divide (object *args, object *env) {
  2081. (void) env;
  2082. int result = checkinteger(DIVIDE, first(args));
  2083. args = cdr(args);
  2084. while (args != NULL) {
  2085. int arg = checkinteger(DIVIDE, car(args));
  2086. if (arg == 0) error2(DIVIDE, PSTR("division by zero"));
  2087. #if defined(checkoverflow)
  2088. if ((result == INT_MIN) && (arg == -1)) error2(DIVIDE, overflow);
  2089. #endif
  2090. result = result / arg;
  2091. args = cdr(args);
  2092. }
  2093. return number(result);
  2094. }
  2095. object *fn_mod (object *args, object *env) {
  2096. (void) env;
  2097. int arg1 = checkinteger(MOD, first(args));
  2098. int arg2 = checkinteger(MOD, second(args));
  2099. if (arg2 == 0) error2(MOD, PSTR("division by zero"));
  2100. int r = arg1 % arg2;
  2101. if ((arg1<0) != (arg2<0)) r = r + arg2;
  2102. return number(r);
  2103. }
  2104. object *fn_oneplus (object *args, object *env) {
  2105. (void) env;
  2106. int result = checkinteger(ONEPLUS, first(args));
  2107. #if defined(checkoverflow)
  2108. if (result == INT_MAX) error2(ONEPLUS, overflow);
  2109. #endif
  2110. return number(result + 1);
  2111. }
  2112. object *fn_oneminus (object *args, object *env) {
  2113. (void) env;
  2114. int result = checkinteger(ONEMINUS, first(args));
  2115. #if defined(checkoverflow)
  2116. if (result == INT_MIN) error2(ONEMINUS, overflow);
  2117. #endif
  2118. return number(result - 1);
  2119. }
  2120. object *fn_abs (object *args, object *env) {
  2121. (void) env;
  2122. int result = checkinteger(ABS, first(args));
  2123. #if defined(checkoverflow)
  2124. if (result == INT_MIN) error2(ABS, overflow);
  2125. #endif
  2126. return number(abs(result));
  2127. }
  2128. object *fn_random (object *args, object *env) {
  2129. (void) env;
  2130. int arg = checkinteger(RANDOM, first(args));
  2131. return number(random(arg));
  2132. }
  2133. object *fn_maxfn (object *args, object *env) {
  2134. (void) env;
  2135. int result = checkinteger(MAXFN, first(args));
  2136. args = cdr(args);
  2137. while (args != NULL) {
  2138. int next = checkinteger(MAXFN, car(args));
  2139. if (next > result) result = next;
  2140. args = cdr(args);
  2141. }
  2142. return number(result);
  2143. }
  2144. object *fn_minfn (object *args, object *env) {
  2145. (void) env;
  2146. int result = checkinteger(MINFN, first(args));
  2147. args = cdr(args);
  2148. while (args != NULL) {
  2149. int next = checkinteger(MINFN, car(args));
  2150. if (next < result) result = next;
  2151. args = cdr(args);
  2152. }
  2153. return number(result);
  2154. }
  2155. // Arithmetic comparisons
  2156. object *fn_noteq (object *args, object *env) {
  2157. (void) env;
  2158. while (args != NULL) {
  2159. object *nargs = args;
  2160. int arg1 = checkinteger(NOTEQ, first(nargs));
  2161. nargs = cdr(nargs);
  2162. while (nargs != NULL) {
  2163. int arg2 = checkinteger(NOTEQ, first(nargs));
  2164. if (arg1 == arg2) return nil;
  2165. nargs = cdr(nargs);
  2166. }
  2167. args = cdr(args);
  2168. }
  2169. return tee;
  2170. }
  2171. object *fn_numeq (object *args, object *env) {
  2172. (void) env;
  2173. int arg1 = checkinteger(NUMEQ, first(args));
  2174. args = cdr(args);
  2175. while (args != NULL) {
  2176. int arg2 = checkinteger(NUMEQ, first(args));
  2177. if (!(arg1 == arg2)) return nil;
  2178. arg1 = arg2;
  2179. args = cdr(args);
  2180. }
  2181. return tee;
  2182. }
  2183. object *fn_less (object *args, object *env) {
  2184. (void) env;
  2185. int arg1 = checkinteger(LESS, first(args));
  2186. args = cdr(args);
  2187. while (args != NULL) {
  2188. int arg2 = checkinteger(LESS, first(args));
  2189. if (!(arg1 < arg2)) return nil;
  2190. arg1 = arg2;
  2191. args = cdr(args);
  2192. }
  2193. return tee;
  2194. }
  2195. object *fn_lesseq (object *args, object *env) {
  2196. (void) env;
  2197. int arg1 = checkinteger(LESSEQ, first(args));
  2198. args = cdr(args);
  2199. while (args != NULL) {
  2200. int arg2 = checkinteger(LESSEQ, first(args));
  2201. if (!(arg1 <= arg2)) return nil;
  2202. arg1 = arg2;
  2203. args = cdr(args);
  2204. }
  2205. return tee;
  2206. }
  2207. object *fn_greater (object *args, object *env) {
  2208. (void) env;
  2209. int arg1 = checkinteger(GREATER, first(args));
  2210. args = cdr(args);
  2211. while (args != NULL) {
  2212. int arg2 = checkinteger(GREATER, first(args));
  2213. if (!(arg1 > arg2)) return nil;
  2214. arg1 = arg2;
  2215. args = cdr(args);
  2216. }
  2217. return tee;
  2218. }
  2219. object *fn_greatereq (object *args, object *env) {
  2220. (void) env;
  2221. int arg1 = checkinteger(GREATEREQ, first(args));
  2222. args = cdr(args);
  2223. while (args != NULL) {
  2224. int arg2 = checkinteger(GREATEREQ, first(args));
  2225. if (!(arg1 >= arg2)) return nil;
  2226. arg1 = arg2;
  2227. args = cdr(args);
  2228. }
  2229. return tee;
  2230. }
  2231. object *fn_plusp (object *args, object *env) {
  2232. (void) env;
  2233. int arg = checkinteger(PLUSP, first(args));
  2234. if (arg > 0) return tee;
  2235. else return nil;
  2236. }
  2237. object *fn_minusp (object *args, object *env) {
  2238. (void) env;
  2239. int arg = checkinteger(MINUSP, first(args));
  2240. if (arg < 0) return tee;
  2241. else return nil;
  2242. }
  2243. object *fn_zerop (object *args, object *env) {
  2244. (void) env;
  2245. int arg = checkinteger(ZEROP, first(args));
  2246. return (arg == 0) ? tee : nil;
  2247. }
  2248. object *fn_oddp (object *args, object *env) {
  2249. (void) env;
  2250. int arg = checkinteger(ODDP, first(args));
  2251. return ((arg & 1) == 1) ? tee : nil;
  2252. }
  2253. object *fn_evenp (object *args, object *env) {
  2254. (void) env;
  2255. int arg = checkinteger(EVENP, first(args));
  2256. return ((arg & 1) == 0) ? tee : nil;
  2257. }
  2258. // Number functions
  2259. object *fn_integerp (object *args, object *env) {
  2260. (void) env;
  2261. return integerp(first(args)) ? tee : nil;
  2262. }
  2263. // Characters
  2264. object *fn_char (object *args, object *env) {
  2265. (void) env;
  2266. object *arg = first(args);
  2267. if (!stringp(arg)) error(CHAR, notastring, arg);
  2268. char c = nthchar(arg, checkinteger(CHAR, second(args)));
  2269. if (c == 0) error2(CHAR, PSTR("index out of range"));
  2270. return character(c);
  2271. }
  2272. object *fn_charcode (object *args, object *env) {
  2273. (void) env;
  2274. return number(checkchar(CHARCODE, first(args)));
  2275. }
  2276. object *fn_codechar (object *args, object *env) {
  2277. (void) env;
  2278. return character(checkinteger(CODECHAR, first(args)));
  2279. }
  2280. object *fn_characterp (object *args, object *env) {
  2281. (void) env;
  2282. return characterp(first(args)) ? tee : nil;
  2283. }
  2284. // Strings
  2285. object *fn_stringp (object *args, object *env) {
  2286. (void) env;
  2287. return stringp(first(args)) ? tee : nil;
  2288. }
  2289. bool stringcompare (symbol_t name, object *args, bool lt, bool gt, bool eq) {
  2290. object *arg1 = first(args); if (!stringp(arg1)) error(name, notastring, arg1);
  2291. object *arg2 = second(args); if (!stringp(arg2)) error(name, notastring, arg2);
  2292. arg1 = cdr(arg1);
  2293. arg2 = cdr(arg2);
  2294. while ((arg1 != NULL) || (arg2 != NULL)) {
  2295. if (arg1 == NULL) return lt;
  2296. if (arg2 == NULL) return gt;
  2297. if (arg1->chars < arg2->chars) return lt;
  2298. if (arg1->chars > arg2->chars) return gt;
  2299. arg1 = car(arg1);
  2300. arg2 = car(arg2);
  2301. }
  2302. return eq;
  2303. }
  2304. object *fn_stringeq (object *args, object *env) {
  2305. (void) env;
  2306. return stringcompare(STRINGEQ, args, false, false, true) ? tee : nil;
  2307. }
  2308. object *fn_stringless (object *args, object *env) {
  2309. (void) env;
  2310. return stringcompare(STRINGLESS, args, true, false, false) ? tee : nil;
  2311. }
  2312. object *fn_stringgreater (object *args, object *env) {
  2313. (void) env;
  2314. return stringcompare(STRINGGREATER, args, false, true, false) ? tee : nil;
  2315. }
  2316. object *fn_sort (object *args, object *env) {
  2317. if (first(args) == NULL) return nil;
  2318. object *list = cons(nil,first(args));
  2319. push(list,GCStack);
  2320. object *predicate = second(args);
  2321. object *compare = cons(NULL, cons(NULL, NULL));
  2322. push(compare,GCStack);
  2323. object *ptr = cdr(list);
  2324. while (cdr(ptr) != NULL) {
  2325. object *go = list;
  2326. while (go != ptr) {
  2327. car(compare) = car(cdr(ptr));
  2328. car(cdr(compare)) = car(cdr(go));
  2329. if (apply(SORT, predicate, compare, env)) break;
  2330. go = cdr(go);
  2331. }
  2332. if (go != ptr) {
  2333. object *obj = cdr(ptr);
  2334. cdr(ptr) = cdr(obj);
  2335. cdr(obj) = cdr(go);
  2336. cdr(go) = obj;
  2337. } else ptr = cdr(ptr);
  2338. }
  2339. pop(GCStack); pop(GCStack);
  2340. return cdr(list);
  2341. }
  2342. object *fn_stringfn (object *args, object *env) {
  2343. (void) env;
  2344. object *arg = first(args);
  2345. int type = arg->type;
  2346. if (type == STRING) return arg;
  2347. object *obj = myalloc();
  2348. obj->type = STRING;
  2349. if (type == CHARACTER) {
  2350. object *cell = myalloc();
  2351. cell->car = NULL;
  2352. uint8_t shift = (sizeof(int)-1)*8;
  2353. cell->chars = (arg->chars)<<shift;
  2354. obj->cdr = cell;
  2355. } else if (type == SYMBOL) {
  2356. char *s = symbolname(arg->name);
  2357. char ch = *s++;
  2358. object *head = NULL;
  2359. int chars = 0;
  2360. while (ch) {
  2361. if (ch == '\\') ch = *s++;
  2362. buildstring(ch, &chars, &head);
  2363. ch = *s++;
  2364. }
  2365. obj->cdr = head;
  2366. } else error(STRINGFN, PSTR("can't convert to string"), arg);
  2367. return obj;
  2368. }
  2369. object *fn_concatenate (object *args, object *env) {
  2370. (void) env;
  2371. object *arg = first(args);
  2372. if (arg->name != STRINGFN) error2(CONCATENATE, PSTR("only supports strings"));
  2373. args = cdr(args);
  2374. object *result = myalloc();
  2375. result->type = STRING;
  2376. object *head = NULL;
  2377. int chars = 0;
  2378. while (args != NULL) {
  2379. object *obj = first(args);
  2380. if (!stringp(obj)) error(CONCATENATE, notastring, obj);
  2381. obj = cdr(obj);
  2382. while (obj != NULL) {
  2383. int quad = obj->chars;
  2384. while (quad != 0) {
  2385. char ch = quad>>((sizeof(int)-1)*8) & 0xFF;
  2386. buildstring(ch, &chars, &head);
  2387. quad = quad<<8;
  2388. }
  2389. obj = car(obj);
  2390. }
  2391. args = cdr(args);
  2392. }
  2393. result->cdr = head;
  2394. return result;
  2395. }
  2396. object *fn_subseq (object *args, object *env) {
  2397. (void) env;
  2398. object *arg = first(args);
  2399. if (!stringp(arg)) error(SUBSEQ, notastring, arg);
  2400. int start = checkinteger(SUBSEQ, second(args));
  2401. if (start < 0) error(SUBSEQ, indexnegative, second(args));
  2402. int end;
  2403. args = cddr(args);
  2404. if (args != NULL) end = checkinteger(SUBSEQ, car(args)); else end = stringlength(arg);
  2405. object *result = myalloc();
  2406. result->type = STRING;
  2407. object *head = NULL;
  2408. int chars = 0;
  2409. for (int i=start; i<end; i++) {
  2410. char ch = nthchar(arg, i);
  2411. if (ch == 0) error2(SUBSEQ, PSTR("index out of range"));
  2412. buildstring(ch, &chars, &head);
  2413. }
  2414. result->cdr = head;
  2415. return result;
  2416. }
  2417. object *fn_readfromstring (object *args, object *env) {
  2418. (void) env;
  2419. object *arg = first(args);
  2420. if (!stringp(arg)) error(READFROMSTRING, notastring, arg);
  2421. GlobalString = arg;
  2422. GlobalStringIndex = 0;
  2423. return read(gstr);
  2424. }
  2425. object *fn_princtostring (object *args, object *env) {
  2426. (void) env;
  2427. object *arg = first(args);
  2428. object *obj = startstring(PRINCTOSTRING);
  2429. prin1object(arg, pstr);
  2430. obj->cdr = GlobalString;
  2431. return obj;
  2432. }
  2433. object *fn_prin1tostring (object *args, object *env) {
  2434. (void) env;
  2435. object *arg = first(args);
  2436. object *obj = startstring(PRIN1TOSTRING);
  2437. printobject(arg, pstr);
  2438. obj->cdr = GlobalString;
  2439. return obj;
  2440. }
  2441. // Bitwise operators
  2442. object *fn_logand (object *args, object *env) {
  2443. (void) env;
  2444. int result = -1;
  2445. while (args != NULL) {
  2446. result = result & checkinteger(LOGAND, first(args));
  2447. args = cdr(args);
  2448. }
  2449. return number(result);
  2450. }
  2451. object *fn_logior (object *args, object *env) {
  2452. (void) env;
  2453. int result = 0;
  2454. while (args != NULL) {
  2455. result = result | checkinteger(LOGIOR, first(args));
  2456. args = cdr(args);
  2457. }
  2458. return number(result);
  2459. }
  2460. object *fn_logxor (object *args, object *env) {
  2461. (void) env;
  2462. int result = 0;
  2463. while (args != NULL) {
  2464. result = result ^ checkinteger(LOGXOR, first(args));
  2465. args = cdr(args);
  2466. }
  2467. return number(result);
  2468. }
  2469. object *fn_lognot (object *args, object *env) {
  2470. (void) env;
  2471. int result = checkinteger(LOGNOT, car(args));
  2472. return number(~result);
  2473. }
  2474. object *fn_ash (object *args, object *env) {
  2475. (void) env;
  2476. int value = checkinteger(ASH, first(args));
  2477. int count = checkinteger(ASH, second(args));
  2478. if (count >= 0) return number(value << count);
  2479. else return number(value >> abs(count));
  2480. }
  2481. object *fn_logbitp (object *args, object *env) {
  2482. (void) env;
  2483. int index = checkinteger(LOGBITP, first(args));
  2484. int value = checkinteger(LOGBITP, second(args));
  2485. return (bitRead(value, index) == 1) ? tee : nil;
  2486. }
  2487. // System functions
  2488. object *fn_eval (object *args, object *env) {
  2489. return eval(first(args), env);
  2490. }
  2491. object *fn_globals (object *args, object *env) {
  2492. (void) args;
  2493. if (GlobalEnv == NULL) return nil;
  2494. return fn_mapcar(cons(symbol(CAR),cons(GlobalEnv,nil)), env);
  2495. }
  2496. object *fn_locals (object *args, object *env) {
  2497. (void) args;
  2498. return env;
  2499. }
  2500. object *fn_makunbound (object *args, object *env) {
  2501. (void) env;
  2502. object *var = first(args);
  2503. if (!symbolp(var)) error(MAKUNBOUND, notasymbol, var);
  2504. delassoc(var, &GlobalEnv);
  2505. return var;
  2506. }
  2507. object *fn_break (object *args, object *env) {
  2508. (void) args;
  2509. pfstring(PSTR("\nBreak!\n"), pserial);
  2510. BreakLevel++;
  2511. repl(env);
  2512. BreakLevel--;
  2513. return nil;
  2514. }
  2515. object *fn_read (object *args, object *env) {
  2516. (void) env;
  2517. gfun_t gfun = gstreamfun(args);
  2518. return read(gfun);
  2519. }
  2520. object *fn_prin1 (object *args, object *env) {
  2521. (void) env;
  2522. object *obj = first(args);
  2523. pfun_t pfun = pstreamfun(cdr(args));
  2524. printobject(obj, pfun);
  2525. return obj;
  2526. }
  2527. object *fn_print (object *args, object *env) {
  2528. (void) env;
  2529. object *obj = first(args);
  2530. pfun_t pfun = pstreamfun(cdr(args));
  2531. pln(pfun);
  2532. printobject(obj, pfun);
  2533. pfun(' ');
  2534. return obj;
  2535. }
  2536. object *fn_princ (object *args, object *env) {
  2537. (void) env;
  2538. object *obj = first(args);
  2539. pfun_t pfun = pstreamfun(cdr(args));
  2540. prin1object(obj, pfun);
  2541. return obj;
  2542. }
  2543. object *fn_terpri (object *args, object *env) {
  2544. (void) env;
  2545. pfun_t pfun = pstreamfun(args);
  2546. pln(pfun);
  2547. return nil;
  2548. }
  2549. object *fn_readbyte (object *args, object *env) {
  2550. (void) env;
  2551. gfun_t gfun = gstreamfun(args);
  2552. int c = gfun();
  2553. return (c == -1) ? nil : number(c);
  2554. }
  2555. object *fn_readline (object *args, object *env) {
  2556. (void) env;
  2557. gfun_t gfun = gstreamfun(args);
  2558. return readstring('\n', gfun);
  2559. }
  2560. object *fn_writebyte (object *args, object *env) {
  2561. (void) env;
  2562. int value = checkinteger(WRITEBYTE, first(args));
  2563. pfun_t pfun = pstreamfun(cdr(args));
  2564. (pfun)(value);
  2565. return nil;
  2566. }
  2567. object *fn_writestring (object *args, object *env) {
  2568. (void) env;
  2569. object *obj = first(args);
  2570. pfun_t pfun = pstreamfun(cdr(args));
  2571. char temp = Flags;
  2572. clrflag(PRINTREADABLY);
  2573. printstring(obj, pfun);
  2574. Flags = temp;
  2575. return nil;
  2576. }
  2577. object *fn_writeline (object *args, object *env) {
  2578. (void) env;
  2579. object *obj = first(args);
  2580. pfun_t pfun = pstreamfun(cdr(args));
  2581. char temp = Flags;
  2582. clrflag(PRINTREADABLY);
  2583. printstring(obj, pfun);
  2584. pln(pfun);
  2585. Flags = temp;
  2586. return nil;
  2587. }
  2588. object *fn_restarti2c (object *args, object *env) {
  2589. (void) env;
  2590. int stream = first(args)->integer;
  2591. args = cdr(args);
  2592. int read = 0; // Write
  2593. I2CCount = 0;
  2594. if (args != NULL) {
  2595. object *rw = first(args);
  2596. if (integerp(rw)) I2CCount = rw->integer;
  2597. read = (rw != NULL);
  2598. }
  2599. int address = stream & 0xFF;
  2600. if (stream>>8 != I2CSTREAM) error2(RESTARTI2C, PSTR("not an i2c stream"));
  2601. return I2Crestart(address, read) ? tee : nil;
  2602. }
  2603. object *fn_gc (object *obj, object *env) {
  2604. int initial = Freespace;
  2605. unsigned long start = micros();
  2606. gc(obj, env);
  2607. unsigned long elapsed = micros() - start;
  2608. pfstring(PSTR("Space: "), pserial);
  2609. pint(Freespace - initial, pserial);
  2610. pfstring(PSTR(" bytes, Time: "), pserial);
  2611. pint(elapsed, pserial);
  2612. pfstring(PSTR(" us\n"), pserial);
  2613. return nil;
  2614. }
  2615. object *fn_room (object *args, object *env) {
  2616. (void) args, (void) env;
  2617. return number(Freespace);
  2618. }
  2619. object *fn_saveimage (object *args, object *env) {
  2620. if (args != NULL) args = eval(first(args), env);
  2621. return number(saveimage(args));
  2622. }
  2623. object *fn_loadimage (object *args, object *env) {
  2624. (void) env;
  2625. if (args != NULL) args = first(args);
  2626. return number(loadimage(args));
  2627. }
  2628. object *fn_cls (object *args, object *env) {
  2629. (void) args, (void) env;
  2630. pserial(12);
  2631. return nil;
  2632. }
  2633. // Arduino procedures
  2634. object *fn_pinmode (object *args, object *env) {
  2635. (void) env;
  2636. int pin = checkinteger(PINMODE, first(args));
  2637. PinMode pm = INPUT;
  2638. object *arg = second(args);
  2639. if (keywordp(arg)) pm = checkkeyword(PINMODE, arg);
  2640. else if (integerp(arg)) {
  2641. int mode = arg->integer;
  2642. if (mode == 1) pm = OUTPUT; else if (mode == 2) pm = INPUT_PULLUP;
  2643. #if defined(INPUT_PULLDOWN)
  2644. else if (mode == 4) pm = INPUT_PULLDOWN;
  2645. #endif
  2646. } else if (arg != nil) pm = OUTPUT;
  2647. pinMode(pin, pm);
  2648. return nil;
  2649. }
  2650. object *fn_digitalread (object *args, object *env) {
  2651. (void) env;
  2652. int pin = checkinteger(DIGITALREAD, first(args));
  2653. if (digitalRead(pin) != 0) return tee; else return nil;
  2654. }
  2655. object *fn_digitalwrite (object *args, object *env) {
  2656. (void) env;
  2657. int pin = checkinteger(DIGITALWRITE, first(args));
  2658. object *arg = second(args);
  2659. int mode;
  2660. if (keywordp(arg)) mode = checkkeyword(DIGITALWRITE, arg);
  2661. else if (integerp(arg)) mode = arg->integer ? HIGH : LOW;
  2662. else mode = (arg != nil) ? HIGH : LOW;
  2663. digitalWrite(pin, mode);
  2664. return arg;
  2665. }
  2666. object *fn_analogread (object *args, object *env) {
  2667. (void) env;
  2668. int pin;
  2669. object *arg = first(args);
  2670. if (keywordp(arg)) pin = checkkeyword(ANALOGREAD, arg);
  2671. else {
  2672. pin = checkinteger(ANALOGREAD, arg);
  2673. checkanalogread(pin);
  2674. }
  2675. return number(analogRead(pin));
  2676. }
  2677. object *fn_analogreference (object *args, object *env) {
  2678. (void) env;
  2679. object *arg = first(args);
  2680. analogReference(checkkeyword(ANALOGREFERENCE, arg));
  2681. return arg;
  2682. }
  2683. object *fn_analogreadresolution (object *args, object *env) {
  2684. (void) env;
  2685. object *arg = first(args);
  2686. #if defined(CPU_AVR128DA48)
  2687. analogReadResolution(checkinteger(ANALOGREADRESOLUTION, arg));
  2688. #else
  2689. error2(ANALOGREADRESOLUTION, PSTR("not supported"));
  2690. #endif
  2691. return arg;
  2692. }
  2693. object *fn_analogwrite (object *args, object *env) {
  2694. (void) env;
  2695. int pin = checkinteger(ANALOGWRITE, first(args));
  2696. checkanalogwrite(pin);
  2697. object *value = second(args);
  2698. analogWrite(pin, checkinteger(ANALOGWRITE, value));
  2699. return value;
  2700. }
  2701. object *fn_dacreference (object *args, object *env) {
  2702. (void) env;
  2703. object *arg = first(args);
  2704. #if defined(CPU_AVR128DA48)
  2705. int ref = checkinteger(DACREFERENCE, arg);
  2706. DACReference(ref);
  2707. #endif
  2708. return arg;
  2709. }
  2710. object *fn_delay (object *args, object *env) {
  2711. (void) env;
  2712. object *arg1 = first(args);
  2713. delay(checkinteger(DELAY, arg1));
  2714. return arg1;
  2715. }
  2716. object *fn_millis (object *args, object *env) {
  2717. (void) args, (void) env;
  2718. return number(millis());
  2719. }
  2720. object *fn_sleep (object *args, object *env) {
  2721. (void) env;
  2722. object *arg1 = first(args);
  2723. sleep(checkinteger(SLEEP, arg1));
  2724. return arg1;
  2725. }
  2726. object *fn_note (object *args, object *env) {
  2727. (void) env;
  2728. static int pin = 255;
  2729. if (args != NULL) {
  2730. pin = checkinteger(NOTE, first(args));
  2731. int note = 0;
  2732. if (cddr(args) != NULL) note = checkinteger(NOTE, second(args));
  2733. int octave = 0;
  2734. if (cddr(args) != NULL) octave = checkinteger(NOTE, third(args));
  2735. playnote(pin, note, octave);
  2736. } else nonote(pin);
  2737. return nil;
  2738. }
  2739. // Tree Editor
  2740. object *fn_edit (object *args, object *env) {
  2741. object *fun = first(args);
  2742. object *pair = findvalue(fun, env);
  2743. clrflag(EXITEDITOR);
  2744. object *arg = edit(eval(fun, env));
  2745. cdr(pair) = arg;
  2746. return arg;
  2747. }
  2748. object *edit (object *fun) {
  2749. while (1) {
  2750. if (tstflag(EXITEDITOR)) return fun;
  2751. char c = gserial();
  2752. if (c == 'q') setflag(EXITEDITOR);
  2753. else if (c == 'b') return fun;
  2754. else if (c == 'r') fun = read(gserial);
  2755. else if (c == '\n') { pfl(pserial); superprint(fun, 0, pserial); pln(pserial); }
  2756. else if (c == 'c') fun = cons(read(gserial), fun);
  2757. else if (atom(fun)) pserial('!');
  2758. else if (c == 'd') fun = cons(car(fun), edit(cdr(fun)));
  2759. else if (c == 'a') fun = cons(edit(car(fun)), cdr(fun));
  2760. else if (c == 'x') fun = cdr(fun);
  2761. else pserial('?');
  2762. }
  2763. }
  2764. // Pretty printer
  2765. object *fn_pprint (object *args, object *env) {
  2766. (void) env;
  2767. object *obj = first(args);
  2768. pfun_t pfun = pstreamfun(cdr(args));
  2769. pln(pfun);
  2770. superprint(obj, 0, pfun);
  2771. return symbol(NOTHING);
  2772. }
  2773. object *fn_pprintall (object *args, object *env) {
  2774. (void) env;
  2775. pfun_t pfun = pstreamfun(args);
  2776. object *globals = GlobalEnv;
  2777. while (globals != NULL) {
  2778. object *pair = first(globals);
  2779. object *var = car(pair);
  2780. object *val = cdr(pair);
  2781. pln(pfun);
  2782. if (consp(val) && symbolp(car(val)) && car(val)->name == LAMBDA) {
  2783. superprint(cons(symbol(DEFUN), cons(var, cdr(val))), 0, pfun);
  2784. } else {
  2785. superprint(cons(symbol(DEFVAR), cons(var, cons(quote(val), NULL))), 0, pserial);
  2786. }
  2787. pln(pfun);
  2788. testescape();
  2789. globals = cdr(globals);
  2790. }
  2791. return symbol(NOTHING);
  2792. }
  2793. // Format
  2794. void formaterr (object *formatstr, PGM_P string, uint8_t p) {
  2795. pln(pserial); indent(4, ' ', pserial); printstring(formatstr, pserial); pln(pserial);
  2796. indent(p+5, ' ', pserial); pserial('^');
  2797. errorsub(FORMAT, string);
  2798. pln(pserial);
  2799. GCStack = NULL;
  2800. longjmp(exception, 1);
  2801. }
  2802. object *fn_format (object *args, object *env) {
  2803. (void) env;
  2804. pfun_t pfun = pserial;
  2805. object *output = first(args);
  2806. object *obj;
  2807. if (output == nil) { obj = startstring(FORMAT); pfun = pstr; }
  2808. else if (output != tee) pfun = pstreamfun(args);
  2809. object *formatstr = second(args);
  2810. if (!stringp(formatstr)) error(FORMAT, notastring, formatstr);
  2811. object *save = NULL;
  2812. args = cddr(args);
  2813. int len = stringlength(formatstr);
  2814. uint8_t n = 0, width = 0, w, bra = 0;
  2815. char pad = ' ';
  2816. bool tilde = false, mute = false, comma, quote;
  2817. while (n < len) {
  2818. char ch = nthchar(formatstr, n);
  2819. char ch2 = ch & ~0x20; // force to upper case
  2820. if (tilde) {
  2821. if (ch == '}') {
  2822. if (save == NULL) formaterr(formatstr, PSTR("no matching ~{"), n);
  2823. if (args == NULL) { args = cdr(save); save = NULL; } else n = bra;
  2824. mute = false; tilde = false;
  2825. }
  2826. else if (!mute) {
  2827. if (comma && quote) { pad = ch; comma = false, quote = false; }
  2828. else if (ch == '\'') {
  2829. if (comma) quote = true;
  2830. else formaterr(formatstr, PSTR("quote not valid"), n);
  2831. }
  2832. else if (ch == '~') { pfun('~'); tilde = false; }
  2833. else if (ch >= '0' && ch <= '9') width = width*10 + ch - '0';
  2834. else if (ch == ',') comma = true;
  2835. else if (ch == '%') { pln(pfun); tilde = false; }
  2836. else if (ch == '&') { pfl(pfun); tilde = false; }
  2837. else if (ch == '^') {
  2838. if (save != NULL && args == NULL) mute = true;
  2839. tilde = false;
  2840. }
  2841. else if (ch == '{') {
  2842. if (save != NULL) formaterr(formatstr, PSTR("can't nest ~{"), n);
  2843. if (args == NULL) formaterr(formatstr, noargument, n);
  2844. if (!listp(first(args))) formaterr(formatstr, notalist, n);
  2845. save = args; args = first(args); bra = n; tilde = false;
  2846. }
  2847. else if (ch2 == 'A' || ch2 == 'S' || ch2 == 'D' || ch2 == 'G' || ch2 == 'X') {
  2848. if (args == NULL) formaterr(formatstr, noargument, n);
  2849. object *arg = first(args); args = cdr(args);
  2850. uint8_t aw = atomwidth(arg);
  2851. if (width < aw) w = 0; else w = width-aw;
  2852. tilde = false;
  2853. if (ch2 == 'A') { prin1object(arg, pfun); indent(w, pad, pfun); }
  2854. else if (ch2 == 'S') { printobject(arg, pfun); indent(w, pad, pfun); }
  2855. else if (ch2 == 'D' || ch2 == 'G') { indent(w, pad, pfun); prin1object(arg, pfun); }
  2856. else if (ch2 == 'X' && integerp(arg)) {
  2857. uint8_t hw = hexwidth(arg); if (width < hw) w = 0; else w = width-hw;
  2858. indent(w, pad, pfun); pinthex(arg->integer, pfun);
  2859. } else if (ch2 == 'X') { indent(w, pad, pfun); prin1object(arg, pfun); }
  2860. tilde = false;
  2861. } else formaterr(formatstr, PSTR("invalid directive"), n);
  2862. }
  2863. } else {
  2864. if (ch == '~') { tilde = true; pad = ' '; width = 0; comma = false; quote = false; }
  2865. else if (!mute) pfun(ch);
  2866. }
  2867. n++;
  2868. }
  2869. if (output == nil) { obj->cdr = GlobalString; return obj; }
  2870. else return nil;
  2871. }
  2872. // LispLibrary
  2873. object *fn_require (object *args, object *env) {
  2874. object *arg = first(args);
  2875. object *globals = GlobalEnv;
  2876. if (!symbolp(arg)) error(REQUIRE, notasymbol, arg);
  2877. while (globals != NULL) {
  2878. object *pair = first(globals);
  2879. object *var = car(pair);
  2880. if (symbolp(var) && var == arg) return nil;
  2881. globals = cdr(globals);
  2882. }
  2883. GlobalStringIndex = 0;
  2884. object *line = read(glibrary);
  2885. while (line != NULL) {
  2886. // Is this the definition we want
  2887. int fname = first(line)->name;
  2888. if ((fname == DEFUN || fname == DEFVAR) && symbolp(second(line)) && second(line)->name == arg->name) {
  2889. eval(line, env);
  2890. return tee;
  2891. }
  2892. line = read(glibrary);
  2893. }
  2894. return nil;
  2895. }
  2896. object *fn_listlibrary (object *args, object *env) {
  2897. (void) args, (void) env;
  2898. GlobalStringIndex = 0;
  2899. object *line = read(glibrary);
  2900. while (line != NULL) {
  2901. int fname = first(line)->name;
  2902. if (fname == DEFUN || fname == DEFVAR) {
  2903. pstring(symbolname(second(line)->name), pserial); pserial(' ');
  2904. }
  2905. line = read(glibrary);
  2906. }
  2907. return symbol(NOTHING);
  2908. }
  2909. // Insert your own function definitions here
  2910. // Built-in procedure names - stored in PROGMEM
  2911. const char string0[] PROGMEM = "nil";
  2912. const char string1[] PROGMEM = "t";
  2913. const char string2[] PROGMEM = "nothing";
  2914. const char string3[] PROGMEM = "&optional";
  2915. const char string4[] PROGMEM = "&rest";
  2916. const char string5[] PROGMEM = "lambda";
  2917. const char string6[] PROGMEM = "let";
  2918. const char string7[] PROGMEM = "let*";
  2919. const char string8[] PROGMEM = "closure";
  2920. const char string9[] PROGMEM = "";
  2921. const char string10[] PROGMEM = "quote";
  2922. const char string11[] PROGMEM = "defun";
  2923. const char string12[] PROGMEM = "defvar";
  2924. const char string13[] PROGMEM = "setq";
  2925. const char string14[] PROGMEM = "loop";
  2926. const char string15[] PROGMEM = "return";
  2927. const char string16[] PROGMEM = "push";
  2928. const char string17[] PROGMEM = "pop";
  2929. const char string18[] PROGMEM = "incf";
  2930. const char string19[] PROGMEM = "decf";
  2931. const char string20[] PROGMEM = "setf";
  2932. const char string21[] PROGMEM = "dolist";
  2933. const char string22[] PROGMEM = "dotimes";
  2934. const char string23[] PROGMEM = "trace";
  2935. const char string24[] PROGMEM = "untrace";
  2936. const char string25[] PROGMEM = "for-millis";
  2937. const char string26[] PROGMEM = "with-serial";
  2938. const char string27[] PROGMEM = "with-i2c";
  2939. const char string28[] PROGMEM = "with-spi";
  2940. const char string29[] PROGMEM = "with-sd-card";
  2941. const char string30[] PROGMEM = "";
  2942. const char string31[] PROGMEM = "progn";
  2943. const char string32[] PROGMEM = "if";
  2944. const char string33[] PROGMEM = "cond";
  2945. const char string34[] PROGMEM = "when";
  2946. const char string35[] PROGMEM = "unless";
  2947. const char string36[] PROGMEM = "case";
  2948. const char string37[] PROGMEM = "and";
  2949. const char string38[] PROGMEM = "or";
  2950. const char string39[] PROGMEM = "";
  2951. const char string40[] PROGMEM = "not";
  2952. const char string41[] PROGMEM = "null";
  2953. const char string42[] PROGMEM = "cons";
  2954. const char string43[] PROGMEM = "atom";
  2955. const char string44[] PROGMEM = "listp";
  2956. const char string45[] PROGMEM = "consp";
  2957. const char string46[] PROGMEM = "symbolp";
  2958. const char string47[] PROGMEM = "boundp";
  2959. const char string48[] PROGMEM = "set";
  2960. const char string49[] PROGMEM = "streamp";
  2961. const char string50[] PROGMEM = "eq";
  2962. const char string51[] PROGMEM = "car";
  2963. const char string52[] PROGMEM = "first";
  2964. const char string53[] PROGMEM = "cdr";
  2965. const char string54[] PROGMEM = "rest";
  2966. const char string55[] PROGMEM = "caar";
  2967. const char string56[] PROGMEM = "cadr";
  2968. const char string57[] PROGMEM = "second";
  2969. const char string58[] PROGMEM = "cdar";
  2970. const char string59[] PROGMEM = "cddr";
  2971. const char string60[] PROGMEM = "caaar";
  2972. const char string61[] PROGMEM = "caadr";
  2973. const char string62[] PROGMEM = "cadar";
  2974. const char string63[] PROGMEM = "caddr";
  2975. const char string64[] PROGMEM = "third";
  2976. const char string65[] PROGMEM = "cdaar";
  2977. const char string66[] PROGMEM = "cdadr";
  2978. const char string67[] PROGMEM = "cddar";
  2979. const char string68[] PROGMEM = "cdddr";
  2980. const char string69[] PROGMEM = "length";
  2981. const char string70[] PROGMEM = "list";
  2982. const char string71[] PROGMEM = "reverse";
  2983. const char string72[] PROGMEM = "nth";
  2984. const char string73[] PROGMEM = "assoc";
  2985. const char string74[] PROGMEM = "member";
  2986. const char string75[] PROGMEM = "apply";
  2987. const char string76[] PROGMEM = "funcall";
  2988. const char string77[] PROGMEM = "append";
  2989. const char string78[] PROGMEM = "mapc";
  2990. const char string79[] PROGMEM = "mapcar";
  2991. const char string80[] PROGMEM = "mapcan";
  2992. const char string81[] PROGMEM = "+";
  2993. const char string82[] PROGMEM = "-";
  2994. const char string83[] PROGMEM = "*";
  2995. const char string84[] PROGMEM = "/";
  2996. const char string85[] PROGMEM = "truncate";
  2997. const char string86[] PROGMEM = "mod";
  2998. const char string87[] PROGMEM = "1+";
  2999. const char string88[] PROGMEM = "1-";
  3000. const char string89[] PROGMEM = "abs";
  3001. const char string90[] PROGMEM = "random";
  3002. const char string91[] PROGMEM = "max";
  3003. const char string92[] PROGMEM = "min";
  3004. const char string93[] PROGMEM = "/=";
  3005. const char string94[] PROGMEM = "=";
  3006. const char string95[] PROGMEM = "<";
  3007. const char string96[] PROGMEM = "<=";
  3008. const char string97[] PROGMEM = ">";
  3009. const char string98[] PROGMEM = ">=";
  3010. const char string99[] PROGMEM = "plusp";
  3011. const char string100[] PROGMEM = "minusp";
  3012. const char string101[] PROGMEM = "zerop";
  3013. const char string102[] PROGMEM = "oddp";
  3014. const char string103[] PROGMEM = "evenp";
  3015. const char string104[] PROGMEM = "integerp";
  3016. const char string105[] PROGMEM = "numberp";
  3017. const char string106[] PROGMEM = "char";
  3018. const char string107[] PROGMEM = "char-code";
  3019. const char string108[] PROGMEM = "code-char";
  3020. const char string109[] PROGMEM = "characterp";
  3021. const char string110[] PROGMEM = "stringp";
  3022. const char string111[] PROGMEM = "string=";
  3023. const char string112[] PROGMEM = "string<";
  3024. const char string113[] PROGMEM = "string>";
  3025. const char string114[] PROGMEM = "sort";
  3026. const char string115[] PROGMEM = "string";
  3027. const char string116[] PROGMEM = "concatenate";
  3028. const char string117[] PROGMEM = "subseq";
  3029. const char string118[] PROGMEM = "read-from-string";
  3030. const char string119[] PROGMEM = "princ-to-string";
  3031. const char string120[] PROGMEM = "prin1-to-string";
  3032. const char string121[] PROGMEM = "logand";
  3033. const char string122[] PROGMEM = "logior";
  3034. const char string123[] PROGMEM = "logxor";
  3035. const char string124[] PROGMEM = "lognot";
  3036. const char string125[] PROGMEM = "ash";
  3037. const char string126[] PROGMEM = "logbitp";
  3038. const char string127[] PROGMEM = "eval";
  3039. const char string128[] PROGMEM = "globals";
  3040. const char string129[] PROGMEM = "locals";
  3041. const char string130[] PROGMEM = "makunbound";
  3042. const char string131[] PROGMEM = "break";
  3043. const char string132[] PROGMEM = "read";
  3044. const char string133[] PROGMEM = "prin1";
  3045. const char string134[] PROGMEM = "print";
  3046. const char string135[] PROGMEM = "princ";
  3047. const char string136[] PROGMEM = "terpri";
  3048. const char string137[] PROGMEM = "read-byte";
  3049. const char string138[] PROGMEM = "read-line";
  3050. const char string139[] PROGMEM = "write-byte";
  3051. const char string140[] PROGMEM = "write-string";
  3052. const char string141[] PROGMEM = "write-line";
  3053. const char string142[] PROGMEM = "restart-i2c";
  3054. const char string143[] PROGMEM = "gc";
  3055. const char string144[] PROGMEM = "room";
  3056. const char string145[] PROGMEM = "save-image";
  3057. const char string146[] PROGMEM = "load-image";
  3058. const char string147[] PROGMEM = "cls";
  3059. const char string148[] PROGMEM = "pinmode";
  3060. const char string149[] PROGMEM = "digitalread";
  3061. const char string150[] PROGMEM = "digitalwrite";
  3062. const char string151[] PROGMEM = "analogread";
  3063. const char string152[] PROGMEM = "analogreference";
  3064. const char string153[] PROGMEM = "analogreadresolution";
  3065. const char string154[] PROGMEM = "analogwrite";
  3066. const char string155[] PROGMEM = "dacreference";
  3067. const char string156[] PROGMEM = "delay";
  3068. const char string157[] PROGMEM = "millis";
  3069. const char string158[] PROGMEM = "sleep";
  3070. const char string159[] PROGMEM = "note";
  3071. const char string160[] PROGMEM = "edit";
  3072. const char string161[] PROGMEM = "pprint";
  3073. const char string162[] PROGMEM = "pprintall";
  3074. const char string163[] PROGMEM = "format";
  3075. const char string164[] PROGMEM = "require";
  3076. const char string165[] PROGMEM = "list-library";
  3077. const char string166[] PROGMEM = "";
  3078. #if defined(CPU_ATmega328P)
  3079. const char string167[] PROGMEM = ":high";
  3080. const char string168[] PROGMEM = ":low";
  3081. const char string169[] PROGMEM = ":input";
  3082. const char string170[] PROGMEM = ":input-pullup";
  3083. const char string171[] PROGMEM = ":output";
  3084. const char string172[] PROGMEM = ":default";
  3085. const char string173[] PROGMEM = ":internal";
  3086. const char string174[] PROGMEM = ":external";
  3087. const char string175[] PROGMEM = "";
  3088. #elif defined(CPU_ATmega2560)
  3089. const char string167[] PROGMEM = ":high";
  3090. const char string168[] PROGMEM = ":low";
  3091. const char string169[] PROGMEM = ":input";
  3092. const char string170[] PROGMEM = ":input-pullup";
  3093. const char string171[] PROGMEM = ":output";
  3094. const char string172[] PROGMEM = ":default";
  3095. const char string173[] PROGMEM = ":internal1v1";
  3096. const char string174[] PROGMEM = ":internal2v56";
  3097. const char string175[] PROGMEM = ":external";
  3098. const char string176[] PROGMEM = "";
  3099. #elif defined(CPU_ATmega4809)
  3100. const char string167[] PROGMEM = ":high";
  3101. const char string168[] PROGMEM = ":low";
  3102. const char string169[] PROGMEM = ":input";
  3103. const char string170[] PROGMEM = ":input-pullup";
  3104. const char string171[] PROGMEM = ":output";
  3105. const char string172[] PROGMEM = ":default";
  3106. const char string173[] PROGMEM = ":internal";
  3107. const char string174[] PROGMEM = ":vdd";
  3108. const char string175[] PROGMEM = ":internal0v55";
  3109. const char string176[] PROGMEM = ":internal1v1";
  3110. const char string177[] PROGMEM = ":internal1v5";
  3111. const char string178[] PROGMEM = ":internal2v5";
  3112. const char string179[] PROGMEM = ":internal4v3";
  3113. const char string180[] PROGMEM = ":external";
  3114. const char string181[] PROGMEM = "";
  3115. #elif defined(CPU_AVR128DA48)
  3116. const char string167[] PROGMEM = ":high";
  3117. const char string168[] PROGMEM = ":low";
  3118. const char string169[] PROGMEM = ":input";
  3119. const char string170[] PROGMEM = ":input-pullup";
  3120. const char string171[] PROGMEM = ":output";
  3121. const char string172[] PROGMEM = ":default";
  3122. const char string173[] PROGMEM = ":vdd";
  3123. const char string174[] PROGMEM = ":internal1v024";
  3124. const char string175[] PROGMEM = ":internal2v048";
  3125. const char string176[] PROGMEM = ":internal4v096";
  3126. const char string177[] PROGMEM = ":internal2v5";
  3127. const char string178[] PROGMEM = ":external";
  3128. const char string179[] PROGMEM = ":adc-dac0";
  3129. const char string180[] PROGMEM = ":adc-temperature";
  3130. const char string181[] PROGMEM = "";
  3131. #endif
  3132. // Third parameter is no. of arguments; 1st hex digit is min, 2nd hex digit is max, 0xF is unlimited
  3133. const tbl_entry_t lookup_table[] PROGMEM = {
  3134. { string0, NULL, 0x00 },
  3135. { string1, NULL, 0x00 },
  3136. { string2, NULL, 0x00 },
  3137. { string3, NULL, 0x00 },
  3138. { string4, NULL, 0x00 },
  3139. { string5, NULL, 0x0F },
  3140. { string6, NULL, 0x0F },
  3141. { string7, NULL, 0x0F },
  3142. { string8, NULL, 0x0F },
  3143. { string9, NULL, 0x00 },
  3144. { string10, sp_quote, 0x11 },
  3145. { string11, sp_defun, 0x2F },
  3146. { string12, sp_defvar, 0x12 },
  3147. { string13, sp_setq, 0x2F },
  3148. { string14, sp_loop, 0x0F },
  3149. { string15, sp_return, 0x0F },
  3150. { string16, sp_push, 0x22 },
  3151. { string17, sp_pop, 0x11 },
  3152. { string18, sp_incf, 0x12 },
  3153. { string19, sp_decf, 0x12 },
  3154. { string20, sp_setf, 0x2F },
  3155. { string21, sp_dolist, 0x1F },
  3156. { string22, sp_dotimes, 0x1F },
  3157. { string23, sp_trace, 0x01 },
  3158. { string24, sp_untrace, 0x01 },
  3159. { string25, sp_formillis, 0x1F },
  3160. { string26, sp_withserial, 0x1F },
  3161. { string27, sp_withi2c, 0x1F },
  3162. { string28, sp_withspi, 0x1F },
  3163. { string29, sp_withsdcard, 0x2F },
  3164. { string30, NULL, 0x00 },
  3165. { string31, tf_progn, 0x0F },
  3166. { string32, tf_if, 0x23 },
  3167. { string33, tf_cond, 0x0F },
  3168. { string34, tf_when, 0x1F },
  3169. { string35, tf_unless, 0x1F },
  3170. { string36, tf_case, 0x1F },
  3171. { string37, tf_and, 0x0F },
  3172. { string38, tf_or, 0x0F },
  3173. { string39, NULL, 0x00 },
  3174. { string40, fn_not, 0x11 },
  3175. { string41, fn_not, 0x11 },
  3176. { string42, fn_cons, 0x22 },
  3177. { string43, fn_atom, 0x11 },
  3178. { string44, fn_listp, 0x11 },
  3179. { string45, fn_consp, 0x11 },
  3180. { string46, fn_symbolp, 0x11 },
  3181. { string47, fn_boundp, 0x11 },
  3182. { string48, fn_setfn, 0x2F },
  3183. { string49, fn_streamp, 0x11 },
  3184. { string50, fn_eq, 0x22 },
  3185. { string51, fn_car, 0x11 },
  3186. { string52, fn_car, 0x11 },
  3187. { string53, fn_cdr, 0x11 },
  3188. { string54, fn_cdr, 0x11 },
  3189. { string55, fn_caar, 0x11 },
  3190. { string56, fn_cadr, 0x11 },
  3191. { string57, fn_cadr, 0x11 },
  3192. { string58, fn_cdar, 0x11 },
  3193. { string59, fn_cddr, 0x11 },
  3194. { string60, fn_caaar, 0x11 },
  3195. { string61, fn_caadr, 0x11 },
  3196. { string62, fn_cadar, 0x11 },
  3197. { string63, fn_caddr, 0x11 },
  3198. { string64, fn_caddr, 0x11 },
  3199. { string65, fn_cdaar, 0x11 },
  3200. { string66, fn_cdadr, 0x11 },
  3201. { string67, fn_cddar, 0x11 },
  3202. { string68, fn_cdddr, 0x11 },
  3203. { string69, fn_length, 0x11 },
  3204. { string70, fn_list, 0x0F },
  3205. { string71, fn_reverse, 0x11 },
  3206. { string72, fn_nth, 0x22 },
  3207. { string73, fn_assoc, 0x22 },
  3208. { string74, fn_member, 0x22 },
  3209. { string75, fn_apply, 0x2F },
  3210. { string76, fn_funcall, 0x1F },
  3211. { string77, fn_append, 0x0F },
  3212. { string78, fn_mapc, 0x2F },
  3213. { string79, fn_mapcar, 0x2F },
  3214. { string80, fn_mapcan, 0x2F },
  3215. { string81, fn_add, 0x0F },
  3216. { string82, fn_subtract, 0x1F },
  3217. { string83, fn_multiply, 0x0F },
  3218. { string84, fn_divide, 0x2F },
  3219. { string85, fn_divide, 0x12 },
  3220. { string86, fn_mod, 0x22 },
  3221. { string87, fn_oneplus, 0x11 },
  3222. { string88, fn_oneminus, 0x11 },
  3223. { string89, fn_abs, 0x11 },
  3224. { string90, fn_random, 0x11 },
  3225. { string91, fn_maxfn, 0x1F },
  3226. { string92, fn_minfn, 0x1F },
  3227. { string93, fn_noteq, 0x1F },
  3228. { string94, fn_numeq, 0x1F },
  3229. { string95, fn_less, 0x1F },
  3230. { string96, fn_lesseq, 0x1F },
  3231. { string97, fn_greater, 0x1F },
  3232. { string98, fn_greatereq, 0x1F },
  3233. { string99, fn_plusp, 0x11 },
  3234. { string100, fn_minusp, 0x11 },
  3235. { string101, fn_zerop, 0x11 },
  3236. { string102, fn_oddp, 0x11 },
  3237. { string103, fn_evenp, 0x11 },
  3238. { string104, fn_integerp, 0x11 },
  3239. { string105, fn_integerp, 0x11 },
  3240. { string106, fn_char, 0x22 },
  3241. { string107, fn_charcode, 0x11 },
  3242. { string108, fn_codechar, 0x11 },
  3243. { string109, fn_characterp, 0x11 },
  3244. { string110, fn_stringp, 0x11 },
  3245. { string111, fn_stringeq, 0x22 },
  3246. { string112, fn_stringless, 0x22 },
  3247. { string113, fn_stringgreater, 0x22 },
  3248. { string114, fn_sort, 0x22 },
  3249. { string115, fn_stringfn, 0x11 },
  3250. { string116, fn_concatenate, 0x1F },
  3251. { string117, fn_subseq, 0x23 },
  3252. { string118, fn_readfromstring, 0x11 },
  3253. { string119, fn_princtostring, 0x11 },
  3254. { string120, fn_prin1tostring, 0x11 },
  3255. { string121, fn_logand, 0x0F },
  3256. { string122, fn_logior, 0x0F },
  3257. { string123, fn_logxor, 0x0F },
  3258. { string124, fn_lognot, 0x11 },
  3259. { string125, fn_ash, 0x22 },
  3260. { string126, fn_logbitp, 0x22 },
  3261. { string127, fn_eval, 0x11 },
  3262. { string128, fn_globals, 0x00 },
  3263. { string129, fn_locals, 0x00 },
  3264. { string130, fn_makunbound, 0x11 },
  3265. { string131, fn_break, 0x00 },
  3266. { string132, fn_read, 0x01 },
  3267. { string133, fn_prin1, 0x12 },
  3268. { string134, fn_print, 0x12 },
  3269. { string135, fn_princ, 0x12 },
  3270. { string136, fn_terpri, 0x01 },
  3271. { string137, fn_readbyte, 0x02 },
  3272. { string138, fn_readline, 0x01 },
  3273. { string139, fn_writebyte, 0x12 },
  3274. { string140, fn_writestring, 0x12 },
  3275. { string141, fn_writeline, 0x12 },
  3276. { string142, fn_restarti2c, 0x12 },
  3277. { string143, fn_gc, 0x00 },
  3278. { string144, fn_room, 0x00 },
  3279. { string145, fn_saveimage, 0x01 },
  3280. { string146, fn_loadimage, 0x01 },
  3281. { string147, fn_cls, 0x00 },
  3282. { string148, fn_pinmode, 0x22 },
  3283. { string149, fn_digitalread, 0x11 },
  3284. { string150, fn_digitalwrite, 0x22 },
  3285. { string151, fn_analogread, 0x11 },
  3286. { string152, fn_analogreference, 0x11 },
  3287. { string153, fn_analogreadresolution, 0x11 },
  3288. { string154, fn_analogwrite, 0x22 },
  3289. { string155, fn_dacreference, 0x11 },
  3290. { string156, fn_delay, 0x11 },
  3291. { string157, fn_millis, 0x00 },
  3292. { string158, fn_sleep, 0x11 },
  3293. { string159, fn_note, 0x03 },
  3294. { string160, fn_edit, 0x11 },
  3295. { string161, fn_pprint, 0x12 },
  3296. { string162, fn_pprintall, 0x01 },
  3297. { string163, fn_format, 0x2F },
  3298. { string164, fn_require, 0x11 },
  3299. { string165, fn_listlibrary, 0x00 },
  3300. { string166, NULL, 0x00 },
  3301. #if defined(CPU_ATmega328P)
  3302. { string167, (fn_ptr_type)HIGH, DIGITALWRITE },
  3303. { string168, (fn_ptr_type)LOW, DIGITALWRITE },
  3304. { string169, (fn_ptr_type)INPUT, PINMODE },
  3305. { string170, (fn_ptr_type)INPUT_PULLUP, PINMODE },
  3306. { string171, (fn_ptr_type)OUTPUT, PINMODE },
  3307. { string172, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
  3308. { string173, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
  3309. { string174, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
  3310. { string175, NULL, 0x00 },
  3311. #elif defined(CPU_ATmega2560)
  3312. { string167, (fn_ptr_type)HIGH, DIGITALWRITE },
  3313. { string168, (fn_ptr_type)LOW, DIGITALWRITE },
  3314. { string169, (fn_ptr_type)INPUT, PINMODE },
  3315. { string170, (fn_ptr_type)INPUT_PULLUP, PINMODE },
  3316. { string171, (fn_ptr_type)OUTPUT, PINMODE },
  3317. { string172, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
  3318. { string173, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
  3319. { string174, (fn_ptr_type)INTERNAL2V56, ANALOGREFERENCE },
  3320. { string175, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
  3321. { string176, NULL, 0x00 },
  3322. #elif defined(CPU_ATmega4809)
  3323. { string167, (fn_ptr_type)HIGH, DIGITALWRITE },
  3324. { string168, (fn_ptr_type)LOW, DIGITALWRITE },
  3325. { string169, (fn_ptr_type)INPUT, PINMODE },
  3326. { string170, (fn_ptr_type)INPUT_PULLUP, PINMODE },
  3327. { string171, (fn_ptr_type)OUTPUT, PINMODE },
  3328. { string172, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
  3329. { string173, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
  3330. { string174, (fn_ptr_type)VDD, ANALOGREFERENCE },
  3331. { string175, (fn_ptr_type)INTERNAL0V55, ANALOGREFERENCE },
  3332. { string176, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
  3333. { string177, (fn_ptr_type)INTERNAL1V5, ANALOGREFERENCE },
  3334. { string178, (fn_ptr_type)INTERNAL2V5, ANALOGREFERENCE },
  3335. { string179, (fn_ptr_type)INTERNAL4V3, ANALOGREFERENCE },
  3336. { string180, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
  3337. { string181, NULL, 0x00 },
  3338. #elif defined(CPU_AVR128DA48)
  3339. { string167, (fn_ptr_type)HIGH, DIGITALWRITE },
  3340. { string168, (fn_ptr_type)LOW, DIGITALWRITE },
  3341. { string169, (fn_ptr_type)INPUT, PINMODE },
  3342. { string170, (fn_ptr_type)INPUT_PULLUP, PINMODE },
  3343. { string171, (fn_ptr_type)OUTPUT, PINMODE },
  3344. { string172, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
  3345. { string173, (fn_ptr_type)VDD, ANALOGREFERENCE },
  3346. { string174, (fn_ptr_type)INTERNAL1V024, ANALOGREFERENCE },
  3347. { string175, (fn_ptr_type)INTERNAL2V048, ANALOGREFERENCE },
  3348. { string176, (fn_ptr_type)INTERNAL4V096, ANALOGREFERENCE },
  3349. { string177, (fn_ptr_type)INTERNAL2V5, ANALOGREFERENCE },
  3350. { string178, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
  3351. { string179, (fn_ptr_type)ADC_DAC0, ANALOGREAD },
  3352. { string180, (fn_ptr_type)ADC_TEMPERATURE, ANALOGREAD },
  3353. { string181, NULL, 0x00 },
  3354. #endif
  3355. };
  3356. // Table lookup functions
  3357. int builtin (char* n) {
  3358. int entry = 0;
  3359. while (entry < ENDFUNCTIONS) {
  3360. #if defined(CPU_ATmega4809)
  3361. if (strcasecmp(n, (char*)lookup_table[entry].string) == 0)
  3362. #else
  3363. if (strcasecmp_P(n, (char*)pgm_read_word(&lookup_table[entry].string)) == 0)
  3364. #endif
  3365. return entry;
  3366. entry++;
  3367. }
  3368. return ENDFUNCTIONS;
  3369. }
  3370. int longsymbol (char *buffer) {
  3371. char *p = SymbolTable;
  3372. int i = 0;
  3373. while (strcasecmp(p, buffer) != 0) {p = p + strlen(p) + 1; i++; }
  3374. if (p == buffer) {
  3375. // Add to symbol table?
  3376. char *newtop = SymbolTop + strlen(p) + 1;
  3377. if (SYMBOLTABLESIZE - (newtop - SymbolTable) < BUFFERSIZE) error2(0, PSTR("no room for long symbols"));
  3378. SymbolTop = newtop;
  3379. }
  3380. if (i > 1535) error2(0, PSTR("too many long symbols"));
  3381. return i + MAXSYMBOL; // First number unused by radix40
  3382. }
  3383. intptr_t lookupfn (symbol_t name) {
  3384. #if defined(CPU_ATmega4809)
  3385. return (intptr_t)lookup_table[name].fptr;
  3386. #else
  3387. return pgm_read_word(&lookup_table[name].fptr);
  3388. #endif
  3389. }
  3390. uint8_t getminmax (symbol_t name) {
  3391. #if defined(CPU_ATmega4809)
  3392. uint8_t minmax = lookup_table[name].minmax;
  3393. #else
  3394. uint8_t minmax = pgm_read_byte(&lookup_table[name].minmax);
  3395. #endif
  3396. return minmax;
  3397. }
  3398. void checkminmax (symbol_t name, int nargs) {
  3399. uint8_t minmax = getminmax(name);
  3400. if (nargs<(minmax >> 4)) error2(name, toofewargs);
  3401. if ((minmax & 0x0f) != 0x0f && nargs>(minmax & 0x0f)) error2(name, toomanyargs);
  3402. }
  3403. char *lookupbuiltin (symbol_t name) {
  3404. char *buffer = SymbolTop;
  3405. #if defined(CPU_ATmega4809)
  3406. strcpy(buffer, (char *)(lookup_table[name].string));
  3407. #else
  3408. strcpy_P(buffer, (char *)(pgm_read_word(&lookup_table[name].string)));
  3409. #endif
  3410. return buffer;
  3411. }
  3412. char *lookupsymbol (symbol_t name) {
  3413. char *p = SymbolTable;
  3414. int i = name - MAXSYMBOL;
  3415. while (i > 0 && p < SymbolTop) {p = p + strlen(p) + 1; i--; }
  3416. if (p == SymbolTop) return NULL; else return p;
  3417. }
  3418. void deletesymbol (symbol_t name) {
  3419. char *p = lookupsymbol(name);
  3420. if (p == NULL) return;
  3421. char *q = p + strlen(p) + 1;
  3422. *p = '\0'; p++;
  3423. while (q < SymbolTop) *(p++) = *(q++);
  3424. SymbolTop = p;
  3425. }
  3426. void testescape () {
  3427. if (Serial.read() == '~') error2(0, PSTR("escape!"));
  3428. }
  3429. // Main evaluator
  3430. extern char __bss_end[];
  3431. object *eval (object *form, object *env) {
  3432. uint8_t sp[0];
  3433. int TC=0;
  3434. EVAL:
  3435. // Enough space?
  3436. // Serial.println((uint16_t)sp - (uint16_t)__bss_end); // Find best STACKDIFF value
  3437. if ((uint16_t)sp - (uint16_t)__bss_end < STACKDIFF) error2(0, PSTR("stack overflow"));
  3438. if (Freespace <= WORKSPACESIZE>>4) gc(form, env); // GC when 1/16 of workspace left
  3439. // Escape
  3440. if (tstflag(ESCAPE)) { clrflag(ESCAPE); error2(0, PSTR("escape!"));}
  3441. if (!tstflag(NOESC)) testescape();
  3442. if (form == NULL) return nil;
  3443. if (form->type >= NUMBER && form->type <= STRING) return form;
  3444. if (symbolp(form)) {
  3445. symbol_t name = form->name;
  3446. object *pair = value(name, env);
  3447. if (pair != NULL) return cdr(pair);
  3448. pair = value(name, GlobalEnv);
  3449. if (pair != NULL) return cdr(pair);
  3450. else if (name < ENDFUNCTIONS) return form;
  3451. error(0, PSTR("undefined"), form);
  3452. }
  3453. // It's a list
  3454. object *function = car(form);
  3455. object *args = cdr(form);
  3456. if (function == NULL) error(0, PSTR("illegal function"), nil);
  3457. if (!listp(args)) error(0, PSTR("can't evaluate a dotted pair"), args);
  3458. // List starts with a symbol?
  3459. if (symbolp(function)) {
  3460. symbol_t name = function->name;
  3461. if ((name == LET) || (name == LETSTAR)) {
  3462. int TCstart = TC;
  3463. if (args == NULL) error2(name, noargument);
  3464. object *assigns = first(args);
  3465. if (!listp(assigns)) error(name, notalist, assigns);
  3466. object *forms = cdr(args);
  3467. object *newenv = env;
  3468. push(newenv, GCStack);
  3469. while (assigns != NULL) {
  3470. object *assign = car(assigns);
  3471. if (!consp(assign)) push(cons(assign,nil), newenv);
  3472. else if (cdr(assign) == NULL) push(cons(first(assign),nil), newenv);
  3473. else push(cons(first(assign),eval(second(assign),env)), newenv);
  3474. car(GCStack) = newenv;
  3475. if (name == LETSTAR) env = newenv;
  3476. assigns = cdr(assigns);
  3477. }
  3478. env = newenv;
  3479. pop(GCStack);
  3480. form = tf_progn(forms,env);
  3481. TC = TCstart;
  3482. goto EVAL;
  3483. }
  3484. if (name == LAMBDA) {
  3485. if (env == NULL) return form;
  3486. object *envcopy = NULL;
  3487. while (env != NULL) {
  3488. object *pair = first(env);
  3489. if (pair != NULL) push(pair, envcopy);
  3490. env = cdr(env);
  3491. }
  3492. return cons(symbol(CLOSURE), cons(envcopy,args));
  3493. }
  3494. if ((name > SPECIAL_FORMS) && (name < TAIL_FORMS)) {
  3495. return ((fn_ptr_type)lookupfn(name))(args, env);
  3496. }
  3497. if ((name > TAIL_FORMS) && (name < FUNCTIONS)) {
  3498. form = ((fn_ptr_type)lookupfn(name))(args, env);
  3499. TC = 1;
  3500. goto EVAL;
  3501. }
  3502. if ((name < SPECIAL_FORMS) || ((name > KEYWORDS) && (name < USERFUNCTIONS))) error2(name, PSTR("can't be used as a function"));
  3503. }
  3504. // Evaluate the parameters - result in head
  3505. object *fname = car(form);
  3506. int TCstart = TC;
  3507. object *head = cons(eval(fname, env), NULL);
  3508. push(head, GCStack); // Don't GC the result list
  3509. object *tail = head;
  3510. form = cdr(form);
  3511. int nargs = 0;
  3512. while (form != NULL){
  3513. object *obj = cons(eval(car(form),env),NULL);
  3514. cdr(tail) = obj;
  3515. tail = obj;
  3516. form = cdr(form);
  3517. nargs++;
  3518. }
  3519. function = car(head);
  3520. args = cdr(head);
  3521. if (symbolp(function)) {
  3522. symbol_t name = function->name;
  3523. if (name >= ENDFUNCTIONS) error(0, PSTR("not valid here"), fname);
  3524. checkminmax(name, nargs);
  3525. object *result = ((fn_ptr_type)lookupfn(name))(args, env);
  3526. pop(GCStack);
  3527. return result;
  3528. }
  3529. if (consp(function)) {
  3530. symbol_t name = 0;
  3531. if (!listp(fname)) name = fname->name;
  3532. if (issymbol(car(function), LAMBDA)) {
  3533. form = closure(TCstart, name, NULL, cdr(function), args, &env);
  3534. pop(GCStack);
  3535. int trace = tracing(fname->name);
  3536. if (trace) {
  3537. object *result = eval(form, env);
  3538. indent((--(TraceDepth[trace-1]))<<1, ' ', pserial);
  3539. pint(TraceDepth[trace-1], pserial);
  3540. pserial(':'); pserial(' ');
  3541. printobject(fname, pserial); pfstring(PSTR(" returned "), pserial);
  3542. printobject(result, pserial); pln(pserial);
  3543. return result;
  3544. } else {
  3545. TC = 1;
  3546. goto EVAL;
  3547. }
  3548. }
  3549. if (issymbol(car(function), CLOSURE)) {
  3550. function = cdr(function);
  3551. form = closure(TCstart, name, car(function), cdr(function), args, &env);
  3552. pop(GCStack);
  3553. TC = 1;
  3554. goto EVAL;
  3555. }
  3556. }
  3557. error(0, PSTR("illegal function"), fname); return nil;
  3558. }
  3559. // Print functions
  3560. inline int maxbuffer (char *buffer) {
  3561. return SYMBOLTABLESIZE-(buffer-SymbolTable)-1;
  3562. }
  3563. void pserial (char c) {
  3564. LastPrint = c;
  3565. if (c == '\n') Serial.write('\r');
  3566. Serial.write(c);
  3567. }
  3568. const char ControlCodes[] PROGMEM = "Null\0SOH\0STX\0ETX\0EOT\0ENQ\0ACK\0Bell\0Backspace\0Tab\0Newline\0VT\0"
  3569. "Page\0Return\0SO\0SI\0DLE\0DC1\0DC2\0DC3\0DC4\0NAK\0SYN\0ETB\0CAN\0EM\0SUB\0Escape\0FS\0GS\0RS\0US\0Space\0";
  3570. void pcharacter (char c, pfun_t pfun) {
  3571. if (!tstflag(PRINTREADABLY)) pfun(c);
  3572. else {
  3573. pfun('#'); pfun('\\');
  3574. if (c > 32) pfun(c);
  3575. else {
  3576. PGM_P p = ControlCodes;
  3577. #if defined(CPU_ATmega4809)
  3578. while (c > 0) {p = p + strlen(p) + 1; c--; }
  3579. #else
  3580. while (c > 0) {p = p + strlen_P(p) + 1; c--; }
  3581. #endif
  3582. pfstring(p, pfun);
  3583. }
  3584. }
  3585. }
  3586. void pstring (char *s, pfun_t pfun) {
  3587. while (*s) pfun(*s++);
  3588. }
  3589. void printstring (object *form, pfun_t pfun) {
  3590. if (tstflag(PRINTREADABLY)) pfun('"');
  3591. form = cdr(form);
  3592. while (form != NULL) {
  3593. int chars = form->chars;
  3594. for (int i=(sizeof(int)-1)*8; i>=0; i=i-8) {
  3595. char ch = chars>>i & 0xFF;
  3596. if (tstflag(PRINTREADABLY) && (ch == '"' || ch == '\\')) pfun('\\');
  3597. if (ch) pfun(ch);
  3598. }
  3599. form = car(form);
  3600. }
  3601. if (tstflag(PRINTREADABLY)) pfun('"');
  3602. }
  3603. void pfstring (PGM_P s, pfun_t pfun) {
  3604. int p = 0;
  3605. while (1) {
  3606. #if defined(CPU_ATmega4809)
  3607. char c = s[p++];
  3608. #else
  3609. char c = pgm_read_byte(&s[p++]);
  3610. #endif
  3611. if (c == 0) return;
  3612. pfun(c);
  3613. }
  3614. }
  3615. void pint (int i, pfun_t pfun) {
  3616. int lead = 0;
  3617. #if INT_MAX == 32767
  3618. int p = 10000;
  3619. #else
  3620. int p = 1000000000;
  3621. #endif
  3622. if (i<0) pfun('-');
  3623. for (int d=p; d>0; d=d/10) {
  3624. int j = i/d;
  3625. if (j!=0 || lead || d==1) { pfun(abs(j)+'0'); lead=1;}
  3626. i = i - j*d;
  3627. }
  3628. }
  3629. void pinthex (uint16_t i, pfun_t pfun) {
  3630. int lead = 0;
  3631. uint16_t p = 0x1000;
  3632. for (uint16_t d=p; d>0; d=d/16) {
  3633. uint16_t j = i/d;
  3634. if (j!=0 || lead || d==1) { pfun((j<10) ? j+'0' : j+'W'); lead=1;}
  3635. i = i - j*d;
  3636. }
  3637. }
  3638. inline void pln (pfun_t pfun) {
  3639. pfun('\n');
  3640. }
  3641. void pfl (pfun_t pfun) {
  3642. if (LastPrint != '\n') pfun('\n');
  3643. }
  3644. void plist (object *form, pfun_t pfun) {
  3645. pfun('(');
  3646. printobject(car(form), pfun);
  3647. form = cdr(form);
  3648. while (form != NULL && listp(form)) {
  3649. pfun(' ');
  3650. printobject(car(form), pfun);
  3651. form = cdr(form);
  3652. }
  3653. if (form != NULL) {
  3654. pfstring(PSTR(" . "), pfun);
  3655. printobject(form, pfun);
  3656. }
  3657. pfun(')');
  3658. }
  3659. void pstream (object *form, pfun_t pfun) {
  3660. pfun('<');
  3661. pfstring(streamname[(form->integer)>>8], pfun);
  3662. pfstring(PSTR("-stream "), pfun);
  3663. pint(form->integer & 0xFF, pfun);
  3664. pfun('>');
  3665. }
  3666. void printobject (object *form, pfun_t pfun) {
  3667. if (form == NULL) pfstring(PSTR("nil"), pfun);
  3668. else if (listp(form) && issymbol(car(form), CLOSURE)) pfstring(PSTR("<closure>"), pfun);
  3669. else if (listp(form)) plist(form, pfun);
  3670. else if (integerp(form)) pint(form->integer, pfun);
  3671. else if (symbolp(form)) { if (form->name != NOTHING) pstring(symbolname(form->name), pfun); }
  3672. else if (characterp(form)) pcharacter(form->chars, pfun);
  3673. else if (stringp(form)) printstring(form, pfun);
  3674. else if (streamp(form)) pstream(form, pfun);
  3675. else error2(0, PSTR("error in print"));
  3676. }
  3677. void prin1object (object *form, pfun_t pfun) {
  3678. char temp = Flags;
  3679. clrflag(PRINTREADABLY);
  3680. printobject(form, pfun);
  3681. Flags = temp;
  3682. }
  3683. // Read functions
  3684. int glibrary () {
  3685. if (LastChar) {
  3686. char temp = LastChar;
  3687. LastChar = 0;
  3688. return temp;
  3689. }
  3690. #if defined(CPU_ATmega4809)
  3691. char c = LispLibrary[GlobalStringIndex++];
  3692. #else
  3693. char c = pgm_read_byte(&LispLibrary[GlobalStringIndex++]);
  3694. #endif
  3695. return (c != 0) ? c : -1; // -1?
  3696. }
  3697. void loadfromlibrary (object *env) {
  3698. GlobalStringIndex = 0;
  3699. object *line = read(glibrary);
  3700. while (line != NULL) {
  3701. push(line, GCStack);
  3702. eval(line, env);
  3703. pop(GCStack);
  3704. line = read(glibrary);
  3705. }
  3706. }
  3707. // For line editor
  3708. const int TerminalWidth = 80;
  3709. volatile int WritePtr = 0, ReadPtr = 0;
  3710. const int KybdBufSize = 333; // 42*8 - 3
  3711. char KybdBuf[KybdBufSize];
  3712. volatile uint8_t KybdAvailable = 0;
  3713. // Parenthesis highlighting
  3714. void esc (int p, char c) {
  3715. Serial.write('\e'); Serial.write('[');
  3716. Serial.write((char)('0'+ p/100));
  3717. Serial.write((char)('0'+ (p/10) % 10));
  3718. Serial.write((char)('0'+ p % 10));
  3719. Serial.write(c);
  3720. }
  3721. void hilight (char c) {
  3722. Serial.write('\e'); Serial.write('['); Serial.write(c); Serial.write('m');
  3723. }
  3724. void Highlight (int p, int wp, uint8_t invert) {
  3725. wp = wp + 2; // Prompt
  3726. #if defined (printfreespace)
  3727. int f = Freespace;
  3728. while (f) { wp++; f=f/10; }
  3729. #endif
  3730. int line = wp/TerminalWidth;
  3731. int col = wp%TerminalWidth;
  3732. int targetline = (wp - p)/TerminalWidth;
  3733. int targetcol = (wp - p)%TerminalWidth;
  3734. int up = line-targetline, left = col-targetcol;
  3735. if (p) {
  3736. if (up) esc(up, 'A');
  3737. if (col > targetcol) esc(left, 'D'); else esc(-left, 'C');
  3738. if (invert) hilight('7');
  3739. Serial.write('('); Serial.write('\b');
  3740. // Go back
  3741. if (up) esc(up, 'B'); // Down
  3742. if (col > targetcol) esc(left, 'C'); else esc(-left, 'D');
  3743. Serial.write('\b'); Serial.write(')');
  3744. if (invert) hilight('0');
  3745. }
  3746. }
  3747. void processkey (char c) {
  3748. if (c == 27) { setflag(ESCAPE); return; } // Escape key
  3749. #if defined(vt100)
  3750. static int parenthesis = 0, wp = 0;
  3751. // Undo previous parenthesis highlight
  3752. Highlight(parenthesis, wp, 0);
  3753. parenthesis = 0;
  3754. #endif
  3755. // Edit buffer
  3756. if (c == '\n' || c == '\r') {
  3757. pserial('\n');
  3758. KybdAvailable = 1;
  3759. ReadPtr = 0;
  3760. return;
  3761. }
  3762. if (c == 8 || c == 0x7f) { // Backspace key
  3763. if (WritePtr > 0) {
  3764. WritePtr--;
  3765. Serial.write(8); Serial.write(' '); Serial.write(8);
  3766. if (WritePtr) c = KybdBuf[WritePtr-1];
  3767. }
  3768. } else if (WritePtr < KybdBufSize) {
  3769. KybdBuf[WritePtr++] = c;
  3770. Serial.write(c);
  3771. }
  3772. #if defined(vt100)
  3773. // Do new parenthesis highlight
  3774. if (c == ')') {
  3775. int search = WritePtr-1, level = 0;
  3776. while (search >= 0 && parenthesis == 0) {
  3777. c = KybdBuf[search--];
  3778. if (c == ')') level++;
  3779. if (c == '(') {
  3780. level--;
  3781. if (level == 0) {parenthesis = WritePtr-search-1; wp = WritePtr; }
  3782. }
  3783. }
  3784. Highlight(parenthesis, wp, 1);
  3785. }
  3786. #endif
  3787. return;
  3788. }
  3789. int gserial () {
  3790. if (LastChar) {
  3791. char temp = LastChar;
  3792. LastChar = 0;
  3793. return temp;
  3794. }
  3795. #if defined(lineeditor)
  3796. while (!KybdAvailable) {
  3797. while (!Serial.available());
  3798. char temp = Serial.read();
  3799. processkey(temp);
  3800. }
  3801. if (ReadPtr != WritePtr) return KybdBuf[ReadPtr++];
  3802. KybdAvailable = 0;
  3803. WritePtr = 0;
  3804. return '\n';
  3805. #else
  3806. while (!Serial.available());
  3807. char temp = Serial.read();
  3808. if (temp != '\n') pserial(temp);
  3809. return temp;
  3810. #endif
  3811. }
  3812. object *nextitem (gfun_t gfun) {
  3813. int ch = gfun();
  3814. while(issp(ch)) ch = gfun();
  3815. if (ch == ';') {
  3816. while(ch != '(') ch = gfun();
  3817. ch = '(';
  3818. }
  3819. if (ch == '\n') ch = gfun();
  3820. if (ch == -1) return nil;
  3821. if (ch == ')') return (object *)KET;
  3822. if (ch == '(') return (object *)BRA;
  3823. if (ch == '\'') return (object *)QUO;
  3824. if (ch == '.') return (object *)DOT;
  3825. // Parse string
  3826. if (ch == '"') return readstring('"', gfun);
  3827. // Parse symbol, character, or number
  3828. int index = 0, base = 10, sign = 1;
  3829. char *buffer = SymbolTop;
  3830. int bufmax = maxbuffer(buffer); // Max index
  3831. unsigned int result = 0;
  3832. if (ch == '+' || ch == '-') {
  3833. buffer[index++] = ch;
  3834. if (ch == '-') sign = -1;
  3835. ch = gfun();
  3836. }
  3837. // Parse reader macros
  3838. else if (ch == '#') {
  3839. ch = gfun();
  3840. char ch2 = ch & ~0x20; // force to upper case
  3841. if (ch == '\\') { // Character
  3842. base = 0; ch = gfun();
  3843. if (issp(ch) || ch == ')' || ch == '(') return character(ch);
  3844. else LastChar = ch;
  3845. } else if (ch == '|') {
  3846. do { while (gfun() != '|'); }
  3847. while (gfun() != '#');
  3848. return nextitem(gfun);
  3849. } else if (ch2 == 'B') base = 2;
  3850. else if (ch2 == 'O') base = 8;
  3851. else if (ch2 == 'X') base = 16;
  3852. else if (ch == '\'') return nextitem(gfun);
  3853. else if (ch == '.') {
  3854. setflag(NOESC);
  3855. object *result = eval(read(gfun), NULL);
  3856. clrflag(NOESC);
  3857. return result;
  3858. } else error2(0, PSTR("illegal character after #"));
  3859. ch = gfun();
  3860. }
  3861. int isnumber = (digitvalue(ch)<base);
  3862. buffer[2] = '\0'; // In case symbol is one letter
  3863. while(!issp(ch) && ch != ')' && ch != '(' && index < bufmax) {
  3864. buffer[index++] = ch;
  3865. int temp = digitvalue(ch);
  3866. result = result * base + temp;
  3867. isnumber = isnumber && (digitvalue(ch)<base);
  3868. ch = gfun();
  3869. }
  3870. buffer[index] = '\0';
  3871. if (ch == ')' || ch == '(') LastChar = ch;
  3872. if (isnumber) {
  3873. if (base == 10 && result > ((unsigned int)INT_MAX+(1-sign)/2))
  3874. error2(0, PSTR("Number out of range"));
  3875. return number(result*sign);
  3876. } else if (base == 0) {
  3877. if (index == 1) return character(buffer[0]);
  3878. PGM_P p = ControlCodes; char c = 0;
  3879. while (c < 33) {
  3880. #if defined(CPU_ATmega4809)
  3881. if (strcasecmp(buffer, p) == 0) return character(c);
  3882. p = p + strlen(p) + 1; c++;
  3883. #else
  3884. if (strcasecmp_P(buffer, p) == 0) return character(c);
  3885. p = p + strlen_P(p) + 1; c++;
  3886. #endif
  3887. }
  3888. error2(0, PSTR("unknown character"));
  3889. }
  3890. int x = builtin(buffer);
  3891. if (x == NIL) return nil;
  3892. if (x < ENDFUNCTIONS) return newsymbol(x);
  3893. else if (index < 4 && valid40(buffer)) return newsymbol(pack40(buffer));
  3894. else return newsymbol(longsymbol(buffer));
  3895. }
  3896. object *readrest (gfun_t gfun) {
  3897. object *item = nextitem(gfun);
  3898. object *head = NULL;
  3899. object *tail = NULL;
  3900. while (item != (object *)KET) {
  3901. if (item == (object *)BRA) {
  3902. item = readrest(gfun);
  3903. } else if (item == (object *)QUO) {
  3904. item = cons(symbol(QUOTE), cons(read(gfun), NULL));
  3905. } else if (item == (object *)DOT) {
  3906. tail->cdr = read(gfun);
  3907. if (readrest(gfun) != NULL) error2(0, PSTR("malformed list"));
  3908. return head;
  3909. } else {
  3910. object *cell = cons(item, NULL);
  3911. if (head == NULL) head = cell;
  3912. else tail->cdr = cell;
  3913. tail = cell;
  3914. item = nextitem(gfun);
  3915. }
  3916. }
  3917. return head;
  3918. }
  3919. object *read (gfun_t gfun) {
  3920. object *item = nextitem(gfun);
  3921. if (item == (object *)KET) error2(0, PSTR("incomplete list"));
  3922. if (item == (object *)BRA) return readrest(gfun);
  3923. if (item == (object *)DOT) return read(gfun);
  3924. if (item == (object *)QUO) return cons(symbol(QUOTE), cons(read(gfun), NULL));
  3925. return item;
  3926. }
  3927. // Setup
  3928. void initenv () {
  3929. GlobalEnv = NULL;
  3930. tee = symbol(TEE);
  3931. }
  3932. void setup () {
  3933. Serial.begin(9600);
  3934. int start = millis();
  3935. while ((millis() - start) < 5000) { if (Serial) break; }
  3936. initworkspace();
  3937. initenv();
  3938. initsleep();
  3939. pfstring(PSTR("uLisp 3.4 "), pserial); pln(pserial);
  3940. }
  3941. // Read/Evaluate/Print loop
  3942. void repl (object *env) {
  3943. for (;;) {
  3944. randomSeed(micros());
  3945. gc(NULL, env);
  3946. #if defined (printfreespace)
  3947. pint(Freespace, pserial);
  3948. #endif
  3949. if (BreakLevel) {
  3950. pfstring(PSTR(" : "), pserial);
  3951. pint(BreakLevel, pserial);
  3952. }
  3953. pserial('>'); pserial(' ');
  3954. object *line = read(gserial);
  3955. if (BreakLevel && line == nil) { pln(pserial); return; }
  3956. if (line == (object *)KET) error2(0, PSTR("unmatched right bracket"));
  3957. push(line, GCStack);
  3958. pfl(pserial);
  3959. line = eval(line, env);
  3960. pfl(pserial);
  3961. printobject(line, pserial);
  3962. pop(GCStack);
  3963. pfl(pserial);
  3964. pln(pserial);
  3965. }
  3966. }
  3967. void loop () {
  3968. if (!setjmp(exception)) {
  3969. #if defined(resetautorun)
  3970. volatile int autorun = 12; // Fudge to keep code size the same
  3971. #else
  3972. volatile int autorun = 13;
  3973. #endif
  3974. if (autorun == 12) autorunimage();
  3975. }
  3976. // Come here after error
  3977. delay(100); while (Serial.available()) Serial.read();
  3978. clrflag(NOESC); BreakLevel = 0;
  3979. for (int i=0; i<TRACEMAX; i++) TraceDepth[i] = 0;
  3980. #if defined(sdcardsupport)
  3981. SDpfile.close(); SDgfile.close();
  3982. #endif
  3983. #if defined(lisplibrary)
  3984. if (!tstflag(LIBRARYLOADED)) { setflag(LIBRARYLOADED); loadfromlibrary(NULL); }
  3985. #endif
  3986. repl(NULL);
  3987. }