compiler.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641
  1. #include "minilisp.h"
  2. #include "reader.h"
  3. #include "writer.h"
  4. #include "alloc.h"
  5. #include "machine.h"
  6. #include "blit.h"
  7. #include <math.h>
  8. void memdump(jit_word_t start,uint32_t len,int raw);
  9. typedef enum builtin_t {
  10. BUILTIN_ADD,
  11. BUILTIN_SUB,
  12. BUILTIN_MUL,
  13. BUILTIN_DIV,
  14. BUILTIN_MOD,
  15. BUILTIN_LT,
  16. BUILTIN_GT,
  17. BUILTIN_EQ,
  18. BUILTIN_WHILE,
  19. BUILTIN_DEF,
  20. BUILTIN_IF ,
  21. BUILTIN_FN ,
  22. BUILTIN_CAR,
  23. BUILTIN_CDR,
  24. BUILTIN_CONS,
  25. BUILTIN_LIST,
  26. BUILTIN_ALLOC,
  27. BUILTIN_ALLOC_STR,
  28. BUILTIN_CONCAT,
  29. BUILTIN_SUBSTR,
  30. BUILTIN_GET,
  31. BUILTIN_PUT,
  32. BUILTIN_SIZE,
  33. BUILTIN_UGET,
  34. BUILTIN_UPUT,
  35. BUILTIN_USIZE,
  36. BUILTIN_TYPE,
  37. BUILTIN_LET,
  38. BUILTIN_QUOTE,
  39. BUILTIN_MAP,
  40. BUILTIN_DO,
  41. BUILTIN_EVAL,
  42. BUILTIN_WRITE,
  43. BUILTIN_PRINT,
  44. BUILTIN_PIXEL,
  45. BUILTIN_FLIP,
  46. BUILTIN_RECTFILL,
  47. BUILTIN_BLIT,
  48. BUILTIN_BLIT_MONO,
  49. BUILTIN_BLIT_MONO_INV,
  50. BUILTIN_BLIT_STRING,
  51. BUILTIN_INKEY,
  52. BUILTIN_ALIEN,
  53. BUILTIN_GC,
  54. BUILTIN_SYMBOLS,
  55. BUILTIN_LOAD,
  56. BUILTIN_SAVE,
  57. BUILTIN_UDP_POLL,
  58. BUILTIN_UDP_SEND,
  59. BUILTIN_TCP_CONNECT,
  60. BUILTIN_TCP_BIND,
  61. BUILTIN_TCP_SEND,
  62. BUILTIN_SIN,
  63. BUILTIN_COS,
  64. BUILTIN_SQRT
  65. } builtin_t;
  66. #define env_t StrMap
  67. static env_t* global_env = NULL;
  68. static Cell* coerce_int_cell; // recycled cell used to return coereced integers
  69. static Cell* error_cell; // recycled cell used to return errors
  70. // store JIT states for nested jitting
  71. static size_t* jit_state_stack;
  72. int jit_state_stack_usage = 0;
  73. Cell* lookup_global_symbol(char* name) {
  74. //HASH_FIND_STR(global_env, name, res);
  75. env_entry* res;
  76. int found = sm_get(global_env, name, (void**)&res);
  77. if (!found) return NULL;
  78. return res->cell;
  79. }
  80. Cell* lookup_symbol(char* name, env_t** env) {
  81. env_entry* res;
  82. //HASH_FIND_STR(*env, name, res);
  83. int found = sm_get(*env, name, (void**)&res);
  84. if (!found) return NULL;
  85. return res->cell;
  86. }
  87. env_entry* intern_symbol(Cell* symbol, env_t** env) {
  88. env_entry* e;
  89. //HASH_FIND_STR(*env, symbol->addr, e);
  90. int found = sm_get(*env, symbol->addr, (void**)&e);
  91. if (!found) {
  92. e = malloc(sizeof(env_entry));
  93. strcpy(e->name, (char*)symbol->addr);
  94. e->cell = NULL;
  95. //HASH_ADD_STR(*env, name, e);
  96. sm_put(*env, e->name, &e);
  97. }
  98. //printf("intern: %s at %p cell %p\n",symbol->addr,e,e->cell);
  99. return e;
  100. }
  101. Cell* insert_symbol(Cell* symbol, Cell* cell, env_t** env) {
  102. env_entry* e;
  103. printf("sm_get %s\r\n",symbol->addr);
  104. //HASH_FIND_STR(*env, symbol->addr, e);
  105. int found = sm_get(*env, symbol->addr, (void**)&e);
  106. printf("sm_get res: %d\r\n",found);
  107. /*if (cell) {
  108. printf("insert_symbol %s <- %x\n",symbol->addr,cell->value);
  109. } else {
  110. printf("insert_symbol %s <- NULL\n",symbol->addr);
  111. }*/
  112. if (found) {
  113. e->cell = cell;
  114. return e->cell;
  115. }
  116. printf("++ alloc env entry %s (%d), symbol size %d\r\n",symbol->addr,sizeof(env_entry),symbol->size);
  117. e = malloc(sizeof(env_entry));
  118. memcpy(e->name, (char*)symbol->addr, symbol->size);
  119. e->cell = cell;
  120. //HASH_ADD_STR(*env, name, e);
  121. sm_put(*env, e->name, &e);
  122. return e->cell;
  123. }
  124. static int stack_reg = 0;
  125. void debug_push(jit_word_t val, jit_word_t sp) {
  126. printf("XX push %p <- %lx stack_base: %p\n",sp,val,stack_base);
  127. }
  128. void debug_pop(jit_word_t val, jit_word_t sp) {
  129. printf("XX pop %p -> %lx\n",sp,val);
  130. }
  131. jit_word_t debug_tmp = 0;
  132. void stack_push(int reg, void** sp)
  133. {
  134. jit_ldi(JIT_V0, sp);
  135. jit_str(JIT_V0, reg);
  136. jit_addi(JIT_V0, JIT_V0, sizeof(jit_word_t));
  137. jit_sti(sp, JIT_V0);
  138. //printf("stack_push sp: %p\n",*sp);
  139. //*sp += sizeof(jit_word_t);
  140. /*jit_sti(&debug_tmp, reg);
  141. jit_prepare();
  142. jit_pushargr(reg);
  143. jit_pushargr(JIT_V0);
  144. jit_finishi(debug_push);
  145. jit_ldi(reg, &debug_tmp);*/
  146. /*if (stack_reg == 0) {
  147. jit_movr(JIT_V0, reg);
  148. } else if (stack_reg == 1) {
  149. jit_movr(JIT_V1, reg);
  150. } else if (stack_reg == 2) {
  151. jit_movr(JIT_V2, reg);
  152. }
  153. stack_reg = (stack_reg+1)%4;*/
  154. }
  155. void stack_pop(int reg, void** sp)
  156. {
  157. //*sp -= sizeof(jit_word_t);
  158. /*printf("stack_pop sp: %p\n",*sp);
  159. if (*sp<stack_base) {
  160. printf("stack underflow!\n");
  161. exit(2);
  162. }*/
  163. jit_ldi(JIT_V0, sp);
  164. jit_subi(JIT_V0, JIT_V0, sizeof(jit_word_t));
  165. jit_ldr(reg, JIT_V0);
  166. jit_sti(sp, JIT_V0);
  167. /*jit_sti(&debug_tmp, reg);
  168. jit_prepare();
  169. jit_pushargr(reg);
  170. jit_pushargr(JIT_V0);
  171. jit_finishi(debug_pop);
  172. jit_ldi(reg, &debug_tmp);*/
  173. /*stack_reg = stack_reg-1;
  174. if (stack_reg<0) stack_reg = 0;
  175. if (stack_reg == 0) {
  176. jit_movr(reg, JIT_V0);
  177. } else if (stack_reg == 1) {
  178. jit_movr(reg, JIT_V1);
  179. } else if (stack_reg == 2) {
  180. jit_movr(reg, JIT_V2);
  181. }*/
  182. }
  183. void stack_set(int reg, void** sp)
  184. {
  185. jit_sti(sp, JIT_V0);
  186. }
  187. int compile_applic(int retreg, Cell* list, tag_t required);
  188. static Cell* debug_current_expr;
  189. int argnum_error(char* usage) {
  190. char tmp[1024];
  191. lisp_write(debug_current_expr,tmp,1023);
  192. printf("argument error in %s (%p). correct usage: %s.\n",tmp,debug_current_expr,usage);
  193. jit_movi(JIT_R0, (jit_word_t)error_cell);
  194. return 0;
  195. }
  196. Cell* int_cell_regs;
  197. int box_int(int retreg, tag_t required) {
  198. if (required == TAG_PURE_INT || required == TAG_VOID) return 1;
  199. if (required != TAG_INT && required != TAG_ANY) {
  200. printf("<cannot cast int result to tag %d>",required);
  201. return 0;
  202. }
  203. //printf("-- box_int retreg: %d\n",retreg);
  204. jit_prepare();
  205. jit_pushargr(retreg);
  206. jit_finishi(alloc_int);
  207. jit_retval(retreg);
  208. return 1;
  209. }
  210. int unbox_int(int retreg) {
  211. jit_ldr(retreg, retreg);
  212. return 1;
  213. }
  214. // returns 1 on success
  215. // returns 0 on failure (type mismatch)
  216. int compile_arg(int retreg, Cell* arg, tag_t required) {
  217. if (!arg) {
  218. return argnum_error("missing argument");
  219. }
  220. debug_current_expr = arg;
  221. /*char buffer2[512];
  222. char buffer[512];
  223. lisp_write(arg, buffer2, 400);
  224. sprintf(buffer,"c_arg %s tag %d\n",buffer2,required);
  225. jit_note(buffer, __LINE__);*/
  226. jit_word_t tag = TAG_PURE_INT; // null = 0
  227. tag = arg->tag;
  228. if (tag == TAG_SYM) {
  229. char* sym = arg->addr;
  230. env_entry* e = intern_symbol(arg, &global_env);
  231. if (!e->cell) {
  232. // undefined symbol
  233. if (required == TAG_INT || required == TAG_PURE_INT || required == TAG_ANY || required == TAG_VOID) {
  234. // return non-existence (zero)
  235. e->cell = alloc_int(0);
  236. } else if (required == TAG_CONS) {
  237. // FIXME adhoc
  238. e->cell = alloc_nil();
  239. } else {
  240. printf("<compile_arg: undefined symbol %s>\n",sym);
  241. return 0;
  242. }
  243. }
  244. arg = e->cell;
  245. tag = arg->tag;
  246. // FIXME this assumes that symbol table entries' tags never change
  247. // load cell from symbol table
  248. jit_movi(retreg, (jit_word_t)e);
  249. jit_ldr(retreg, retreg);
  250. }
  251. else if (tag == TAG_CONS) {
  252. return compile_applic(retreg, arg, required);
  253. }
  254. else {
  255. // load cell directly
  256. jit_movi(retreg, (jit_word_t)arg);
  257. }
  258. //printf("arg: %p, tag: %d, required: %d\n",arg,tag,required);
  259. if (tag == TAG_INT) {
  260. if (required == TAG_PURE_INT) {
  261. unbox_int(retreg);
  262. return 1;
  263. }
  264. else if (required == TAG_INT || required == TAG_ANY || required == TAG_VOID) {
  265. return 1;
  266. }
  267. else {
  268. printf("<type mismatch. got boxed int, need %d>\n",required);
  269. return 0;
  270. }
  271. }
  272. else if (tag == TAG_PURE_INT) {
  273. if (required == TAG_PURE_INT || required == TAG_VOID) {
  274. return 1;
  275. }
  276. else if (required == TAG_INT || required == TAG_ANY) {
  277. char tmp[1024];
  278. lisp_write(arg,tmp,1023);
  279. printf("++ compile_arg int allocation at: %s\n",tmp);
  280. // box int
  281. jit_prepare();
  282. jit_pushargr(retreg);
  283. jit_finishi(alloc_int);
  284. jit_retval(retreg);
  285. // FIXME: mark this allocation as temporary
  286. // until "consumed"?
  287. } else {
  288. printf("<type mismatch. got unboxed int, need %d>\n",required);
  289. return 0;
  290. }
  291. }
  292. else {
  293. if (required == TAG_PURE_INT) {
  294. // other cells can't be coerced to pure integers, so we return existence, 1
  295. jit_movi(retreg, 1);
  296. return 1;
  297. }
  298. if (required == TAG_ANY || required == TAG_VOID || tag == required) {
  299. return 1;
  300. }
  301. printf("<type mismatch. got %d, need %d>\n",tag,required);
  302. return 0;
  303. }
  304. }
  305. #define ARITH_ARGS() \
  306. if (!compile_arg(JIT_R0, car(args), TAG_PURE_INT)) return 0;\
  307. stack_push(JIT_R0, &stack_ptr);\
  308. if (!compile_arg(JIT_R1, car(cdr(args)), TAG_PURE_INT)) return 0;\
  309. stack_pop(JIT_R0, &stack_ptr);\
  310. int compile_add(int retreg, Cell* args, tag_t required) {
  311. ARITH_ARGS();
  312. jit_addr(retreg, JIT_R0, JIT_R1);
  313. return box_int(retreg, required);
  314. }
  315. int compile_sub(int retreg, Cell* args, tag_t required) {
  316. ARITH_ARGS();
  317. jit_subr(retreg, JIT_R0, JIT_R1);
  318. return box_int(retreg, required);
  319. }
  320. int compile_mul(int retreg, Cell* args, tag_t required) {
  321. ARITH_ARGS();
  322. jit_mulr(retreg, JIT_R0, JIT_R1);
  323. return box_int(retreg, required);
  324. }
  325. int compile_div(int retreg, Cell* args, tag_t required) {
  326. ARITH_ARGS();
  327. jit_divr(retreg, JIT_R0, JIT_R1);
  328. return box_int(retreg, required);
  329. }
  330. int compile_mod(int retreg, Cell* args, tag_t required) {
  331. ARITH_ARGS();
  332. //stack_push(JIT_R2, &stack_ptr);
  333. jit_movr(JIT_R2, JIT_R0);
  334. jit_divr(JIT_R0, JIT_R0, JIT_R1);
  335. jit_mulr(JIT_R0, JIT_R0, JIT_R1);
  336. jit_subr(retreg, JIT_R2, JIT_R0);
  337. //stack_pop(JIT_R2, &stack_ptr);
  338. return box_int(retreg, required);
  339. }
  340. int compile_lt(int retreg, Cell* args, tag_t required) {
  341. ARITH_ARGS();
  342. jit_ltr(retreg, JIT_R0, JIT_R1);
  343. return box_int(retreg, required);
  344. }
  345. int compile_gt(int retreg, Cell* args, tag_t required) {
  346. ARITH_ARGS();
  347. jit_gtr(retreg, JIT_R0, JIT_R1);
  348. return box_int(retreg, required);
  349. }
  350. // FIXME: cheap way of detecting (tail) recursion
  351. // later, manage this as a part of compiler state
  352. // that is passed around
  353. static Cell* currently_compiling_fn_sym = NULL;
  354. static Cell* currently_compiling_fn_op = NULL;
  355. static jit_node_t* currently_compiling_fn_label = NULL;
  356. void undefined_fn_stub() {
  357. printf("!! undefined_fn_stub() called.\n");
  358. }
  359. int compile_def(int retreg, Cell* args, tag_t required) {
  360. //if (!car(args) || !cdr(args) || !car(cdr(args))) return argnum_error("(def symbol definition)");
  361. Cell* sym = car(args);
  362. Cell* value = car(cdr(args));
  363. int detect_fn = 0;
  364. // analysis of what we are defining
  365. if (value) {
  366. if (value->tag == TAG_CONS) {
  367. Cell* opsym = car(value);
  368. if (opsym && opsym->tag == TAG_SYM) {
  369. Cell* op = lookup_symbol(opsym->addr, &global_env);
  370. if (op && op->value == BUILTIN_FN) {
  371. // we are binding a function
  372. currently_compiling_fn_sym = sym;
  373. detect_fn = 1;
  374. printf("-- compiling fn %s\r\n",currently_compiling_fn_sym->addr);
  375. // FIXME: recursion is broken
  376. env_entry* stub_e = intern_symbol(sym, &global_env);
  377. stub_e->cell = alloc_lambda(0);
  378. stub_e->cell->next = (void*)undefined_fn_stub;
  379. }
  380. }
  381. }
  382. }
  383. int success = 0;
  384. if (required == TAG_PURE_INT) {
  385. success = compile_arg(retreg, value, TAG_INT);
  386. } else if (required == TAG_VOID) {
  387. success = compile_arg(retreg, value, TAG_ANY);
  388. } else {
  389. success = compile_arg(retreg, value, required);
  390. }
  391. if (!success) {
  392. char tmp[1024];
  393. lisp_write(value,tmp,1023);
  394. printf("<type mismatch in def %s, required %d, got: %s>\n",sym->addr,required,tmp);
  395. return 0;
  396. }
  397. //printf("interning: %s\n",sym->addr);
  398. env_entry* e = intern_symbol(sym, &global_env);
  399. if (!e->cell) {
  400. e->cell = alloc_int(0); // reserve at compile time
  401. }
  402. jit_sti(&e->cell, retreg);
  403. if (required == TAG_PURE_INT) {
  404. unbox_int(retreg);
  405. }
  406. if (detect_fn) {
  407. currently_compiling_fn_sym = NULL;
  408. currently_compiling_fn_label = NULL;
  409. }
  410. return 1;
  411. }
  412. static char temp_print_buffer[1024];
  413. Cell* do_print(Cell* arg) {
  414. lisp_write(arg, temp_print_buffer, sizeof(temp_print_buffer)-1);
  415. printf("%s\r\n",temp_print_buffer);
  416. return arg;
  417. }
  418. int compile_print(int retreg, Cell* args, tag_t required) {
  419. if (!car(args)) return argnum_error("(print a)");
  420. Cell* arg = car(args);
  421. int r = compile_arg(retreg, arg, TAG_ANY);
  422. if (!r) {
  423. printf("<could not convert print arg to TAG_ANY>\r\n");
  424. return 0;
  425. }
  426. jit_prepare();
  427. jit_pushargr(retreg);
  428. jit_finishi(do_print);
  429. jit_retval(retreg);
  430. if (required == TAG_PURE_INT) {
  431. jit_movi(retreg, 0);
  432. }
  433. return 1;
  434. }
  435. Cell* make_symbol_list() {
  436. Cell* end = alloc_nil();
  437. /*for (env_entry* e=global_env; e != NULL; e=e->hh.next) {
  438. end = alloc_cons(alloc_string_copy(e->name), end);
  439. }*/
  440. return end;
  441. }
  442. int compile_symbol_list(int retreg) {
  443. jit_prepare();
  444. jit_finishi(make_symbol_list);
  445. jit_retval(retreg);
  446. return 1;
  447. }
  448. int compile_gc(int retreg) {
  449. jit_prepare();
  450. jit_pushargi((jit_word_t)global_env);
  451. jit_finishi(collect_garbage);
  452. jit_retval(retreg);
  453. return 1;
  454. }
  455. int compile_do(int retreg, Cell* args, tag_t required) {
  456. if (!car(args)) return argnum_error("(do op1 op2 …)");
  457. int is_last = !(car(cdr(args)));
  458. int success = compile_arg(retreg, car(args), is_last?required:TAG_VOID);
  459. if (!success) return 0;
  460. while ((args = cdr(args)) && car(args)) {
  461. is_last = !(car(cdr(args)));
  462. success = compile_arg(retreg, car(args), is_last?required:TAG_VOID);
  463. if (!success) return 0;
  464. }
  465. return 1;
  466. }
  467. static int num_funcs = 0;
  468. void push_jit_state() {
  469. *jit_state_stack = (jit_word_t)_jit;
  470. jit_state_stack++;
  471. jit_state_stack_usage++;
  472. }
  473. void pop_jit_state() {
  474. jit_state_stack--;
  475. _jit = (jit_state_t*)*jit_state_stack;
  476. jit_state_stack_usage--;
  477. }
  478. int compile_fn(int retreg, Cell* args, tag_t required) {
  479. if (!car(args)) {
  480. argnum_error("(fn arg1 arg2 … (body))");
  481. return 0;
  482. }
  483. // args 0..n-2 = parameter symbols
  484. // arg n-1 = body
  485. num_funcs++;
  486. Cell* args_saved = args;
  487. #ifdef DEBUG
  488. if (currently_compiling_fn_sym) {
  489. printf("-- compile_fn %s\r\n",currently_compiling_fn_sym->addr);
  490. } else {
  491. printf("-- compile_fn (closure)\r\n");
  492. }
  493. #endif
  494. // skip to the body
  495. //printf("args: %p %s %p\n",car(args),car(args)->addr,args->next);
  496. while (car(args) && cdr(args) && car(cdr(args))) {
  497. //printf("arg: %p %s %p\n",args,car(args)->addr,args->next);
  498. Cell* sym = car(args);
  499. args = cdr(args);
  500. }
  501. //printf("body: %p %d %p\n",args,args->tag,args->addr);
  502. if (jit_state_stack_usage>=49) {
  503. printf("<compile_fn error: jit_state_stack overflow.>\r\n");
  504. return 0;
  505. }
  506. push_jit_state();
  507. _jit = jit_new_state();
  508. jit_node_t* fn_label = jit_note(__FILE__, __LINE__);
  509. jit_prolog();
  510. jit_node_t* fn_body_label = jit_label();
  511. Cell* res = alloc_lambda(args_saved);
  512. // store info for potential recursion
  513. // currently_compiling_fn_label = fn_body_label;
  514. currently_compiling_fn_label = fn_label;
  515. currently_compiling_fn_op = res;
  516. // compile body
  517. // TODO: save _jit_saved on a stack
  518. int success = compile_arg(JIT_R0, car(args), TAG_ANY);
  519. if (success) {
  520. jit_retr(JIT_R0);
  521. jit_epilog();
  522. // res->addr will point to the args
  523. res->next = jit_emit();
  524. //printf("-- emitted at %p in %p\n",res->next,res);
  525. //memdump(res->next,0x100,0);
  526. /*#ifdef DEBUG
  527. printf("<assembled: %p>\n",res->next);
  528. jit_disassemble();
  529. printf("--------------------------------------\n");
  530. #endif*/
  531. }
  532. jit_clear_state();
  533. pop_jit_state();
  534. if (success) {
  535. // return the allocated lambda
  536. jit_movi(retreg, (jit_word_t)res);
  537. } else {
  538. if (currently_compiling_fn_sym) {
  539. printf("<could not compile_fn %s>\r\n",currently_compiling_fn_sym->addr);
  540. } else {
  541. printf("<could not compile_fn (anonymous)>\r\n");
  542. }
  543. jit_movi(retreg, 0);
  544. }
  545. return success;
  546. }
  547. // args in this case is an array of Cells
  548. Cell* call_dynamic_lambda(Cell** lbd_and_args, int args_supplied) {
  549. Cell* lbd = lbd_and_args[0];
  550. Cell** args = &lbd_and_args[1];
  551. // TODO: typecheck for TAG_LAMBDA
  552. Cell* pargs = (Cell*)lbd->addr;
  553. /*char buf[128];
  554. lisp_write(pargs, buf, 128);
  555. printf("-- dyn lambda formal params are %s\n",buf);*/
  556. // 1. push and clobber environment
  557. Cell** stack = malloc(args_supplied*sizeof(Cell*));
  558. for (int i=0; i<args_supplied; i++) {
  559. if (car(cdr(pargs))) {
  560. Cell* parg = car(pargs);
  561. env_entry* arge = intern_symbol(parg, &global_env);
  562. //static char buf[256];
  563. //lisp_write(args[i],buf,255);
  564. //printf("-- dyn arg %d (%s): %s\r\n",i,parg->addr,buf);
  565. stack[i] = arge->cell;
  566. // clobber
  567. arge->cell = args[i];
  568. } else {
  569. printf("-! too many args supplied\n");
  570. break;
  571. }
  572. pargs = cdr(pargs);
  573. }
  574. // 2. dispatch
  575. Cell* result = (Cell*)((funcptr)lbd->next)();
  576. // 3. pop clobbered environment
  577. pargs = (Cell*)lbd->addr;
  578. for (int i=0; i<args_supplied; i++) {
  579. if (car(cdr(pargs))) {
  580. Cell* parg = car(pargs);
  581. env_entry* arge = intern_symbol(parg, &global_env);
  582. // restore
  583. arge->cell = stack[i];
  584. } else {
  585. break;
  586. }
  587. pargs = cdr(pargs);
  588. }
  589. free(stack);
  590. return result;
  591. }
  592. int compile_dynamic_lambda(int retreg, int lbd_reg, Cell* args, tag_t requires, env_t** env) {
  593. // apply a function whose parameters we only learn at runtime
  594. // push the actual lambda to call
  595. stack_push(JIT_R0, &stack_ptr);
  596. // push any args
  597. int success = 0;
  598. int i = 0;
  599. while (i<10 && car(args)) {
  600. int res = compile_arg(JIT_R0, car(args), TAG_ANY);
  601. if (!res) {
  602. printf("<could not compile dynamic fn arg %d\n>",i);
  603. success = 0;
  604. // store new value
  605. }
  606. stack_push(JIT_R0, &stack_ptr);
  607. i++;
  608. args = cdr(args);
  609. }
  610. jit_prepare();
  611. jit_subi(JIT_V0, JIT_V0, (1+i)*sizeof(jit_word_t)); // layout: lbd,arg0,arg1,arg2... FIXME: hardcore stack hack
  612. stack_set(JIT_V0, &stack_ptr);
  613. jit_pushargr(JIT_V0);
  614. jit_pushargi(i);
  615. jit_finishi(call_dynamic_lambda);
  616. jit_retval(retreg);
  617. success = 1;
  618. return success;
  619. }
  620. // compile application of a compiled function
  621. int compile_lambda(int retreg, Cell* lbd, Cell* args, tag_t requires, env_t** env, int recursion) {
  622. jit_node_t* ret_label = jit_note(__FILE__, __LINE__);
  623. //printf("<lambda: %p>\n",lbd->next);
  624. Cell* args_orig = args;
  625. Cell* pargs = (Cell*)lbd->addr;
  626. Cell* pargs_orig = pargs;
  627. env_entry* arges[10]; // max args 10
  628. int i = 0;
  629. int success = 1;
  630. // pass 0: save old symbol values
  631. while (i<10 && car(args) && car(pargs)) {
  632. // ignore the last arg, which is the function body
  633. if (car(cdr(pargs))) {
  634. Cell* sym = car(pargs);
  635. /*char buffer[64];
  636. sprintf(buffer,"save arg: %d %s\n",i,sym->addr);
  637. jit_note(buffer, __LINE__);*/
  638. // FIXME: possible optimization when pushing the same arg twice
  639. // (in subcall), but rare?
  640. //printf("prototype sym: %p\n",sym);
  641. env_entry* arge = intern_symbol(sym, env);
  642. jit_ldi(JIT_R0, &arge->cell);
  643. stack_push(JIT_R0, &stack_ptr);
  644. int res = compile_arg(JIT_R0, car(args), TAG_ANY);
  645. if (!res) {
  646. printf("<could not compile fn arg %d\n>",i);
  647. success = 0;
  648. // store new value
  649. } else {
  650. jit_sti(&arge->cell, JIT_R0);
  651. }
  652. arges[i] = arge;
  653. i++;
  654. }
  655. pargs = cdr(pargs);
  656. args = cdr(args);
  657. }
  658. // pass 3: jump/call
  659. // TODO: tail recursion
  660. if (!success) {
  661. // TODO: pop stack
  662. return 0;
  663. }
  664. if (recursion == 1) {
  665. printf("++ recursion\r\n");
  666. //jit_note("jump to lambda as recursion\n",__LINE__);
  667. // get jump address at runtime
  668. jit_movi(JIT_R0, (jit_word_t)currently_compiling_fn_op);
  669. jit_ldxi(JIT_R0, JIT_R0, sizeof(jit_word_t)); // *(r0 + 1) -> r0
  670. jit_prepare();
  671. jit_finishr(JIT_R0);
  672. jit_retval(retreg);
  673. //jit_node_t* rec_jump = jit_calli(currently_compiling_fn_label);
  674. //jit_patch_at(rec_jump, );
  675. } else {
  676. //jit_note("call lambda as function\n",__LINE__);
  677. jit_prepare();
  678. jit_finishi(lbd->next);
  679. jit_retval(retreg);
  680. }
  681. // pass 4: restore environment
  682. if (recursion<2) {
  683. jit_movr(JIT_V1, retreg); // fixme: how to ensure this is a clobber-free reg?
  684. // after call, restore old symbol values from the stack (in reverse order)
  685. for (int j=i-1; j>=0; j--) {
  686. // pop value
  687. env_entry* arge = arges[j];
  688. stack_pop(JIT_R0, &stack_ptr);
  689. jit_sti(&arge->cell, JIT_R0); // restore any overwritten value
  690. }
  691. jit_movr(retreg, JIT_V1);
  692. }
  693. if (requires == TAG_PURE_INT) {
  694. return unbox_int(retreg);
  695. }
  696. return 1;
  697. }
  698. int compile_if(int retreg, Cell* args, tag_t requires) {
  699. if (!car(args) || !car(cdr(args)) || !cdr(cdr(args))) return argnum_error("(if condition then-body [else-body])");
  700. jit_node_t *jump, *jump2, *else_label, *exit_label;
  701. // lbl1:
  702. int r = compile_arg(retreg, car(args), TAG_PURE_INT);
  703. if (!r) {
  704. printf("<could not compile if's condition>\n");
  705. return 0;
  706. }
  707. // cmp r0, 1
  708. // beq lbl2
  709. jump = jit_beqi(retreg, 0);
  710. // then
  711. r = compile_arg(retreg, car(cdr(args)), requires);
  712. if (!r) {
  713. printf("<could not compile if's then-branch>\n");
  714. return 0;
  715. }
  716. // exit
  717. jump2 = jit_jmpi();
  718. else_label = jit_label();
  719. // else
  720. if (car(cdr(cdr(args)))) {
  721. r = compile_arg(retreg, car(cdr(cdr(args))), requires);
  722. if (!r) {
  723. printf("<could not compile if's else-branch>\n");
  724. return 0;
  725. }
  726. }
  727. exit_label = jit_label();
  728. jit_patch_at(jump, else_label);
  729. jit_patch_at(jump2, exit_label);
  730. return 1;
  731. }
  732. int compile_while(int retreg, Cell* args, tag_t requires) {
  733. if (!car(args) || !car(cdr(args))) return argnum_error("(while condition (body))");
  734. jit_node_t *jump, *jump2, *loop_label, *exit_label;
  735. // lbl1:
  736. loop_label = jit_label();
  737. int r = compile_arg(retreg, car(args), TAG_PURE_INT);
  738. if (!r) {
  739. printf("<could not compile while's condition>\n");
  740. return 0;
  741. }
  742. // cmp r0, 1
  743. // beq lbl2
  744. jump = jit_beqi(retreg, 0);
  745. r = compile_arg(retreg, car(cdr(args)), requires);
  746. if (!r) {
  747. printf("<could not compile while's body>\n");
  748. return 0;
  749. }
  750. // lbl2:
  751. jump2 = jit_jmpi();
  752. exit_label = jit_label();
  753. jit_patch_at(jump, exit_label);
  754. jit_patch_at(jump2, loop_label);
  755. return 1;
  756. }
  757. int compile_quote(int retreg, Cell* args, tag_t requires) {
  758. if (!car(args)) return argnum_error("(quote arg)");
  759. jit_movi(JIT_R0, (jit_word_t)car(args));
  760. return 1;
  761. }
  762. jit_word_t do_car(Cell* cell) {
  763. if (!cell) return 0;
  764. if (cell->tag != TAG_CONS) return 0;
  765. return (jit_word_t)(cell->addr?cell->addr:0);
  766. }
  767. jit_word_t do_car_int(Cell* cell) {
  768. if (!cell) return 0;
  769. if (cell->tag != TAG_CONS) return 0;
  770. Cell* carc = cell->addr;
  771. if (!carc) return 0;
  772. return carc->value;
  773. }
  774. int compile_car(int retreg, Cell* args, tag_t requires) {
  775. if (!car(args)) return argnum_error("(car list)");
  776. Cell* arg = car(args);
  777. // TODO check success
  778. int success = compile_arg(retreg, arg, TAG_ANY);
  779. if (success) {
  780. jit_prepare();
  781. jit_pushargr(retreg);
  782. if (requires == TAG_PURE_INT) {
  783. jit_finishi(do_car_int);
  784. } else {
  785. jit_finishi(do_car);
  786. }
  787. jit_retval(retreg);
  788. //jit_ldr(JIT_R0, JIT_R0); // car r0 = r0->addr
  789. } else {
  790. printf("<non-cons argument to cdr>\n");
  791. return 0;
  792. }
  793. return 1;
  794. }
  795. jit_word_t do_cdr(Cell* cell) {
  796. if (!cell) return 0;
  797. if (cell->tag != TAG_CONS) return 0;
  798. return (jit_word_t)(cell->next?cell->next:0);
  799. }
  800. int compile_cdr(int retreg, Cell* args, tag_t requires) {
  801. if (!car(args)) return argnum_error("(cdr list)");
  802. Cell* arg = car(args);
  803. int success = compile_arg(retreg, arg, TAG_ANY);
  804. if (success) {
  805. jit_prepare();
  806. jit_pushargr(retreg);
  807. jit_finishi(do_cdr);
  808. jit_retval(retreg);
  809. } else {
  810. printf("<non-cons argument to cdr>\n");
  811. return 0;
  812. //jit_ldxi(JIT_R0, JIT_R0, sizeof(jit_word_t)); // cdr r0 = r0 + one word = r0->next
  813. }
  814. return 1;
  815. }
  816. int compile_cons(int retreg, Cell* args, tag_t requires) {
  817. if (!car(args) || !car(cdr(args))) return argnum_error("(cons new-item list)");
  818. compile_arg(JIT_R0, car(args), TAG_ANY); // FIXME check success
  819. stack_push(JIT_R0, &stack_ptr);
  820. compile_arg(JIT_R1, car(cdr(args)), TAG_ANY); // FIXME check success
  821. stack_pop(JIT_R0, &stack_ptr);
  822. jit_prepare();
  823. jit_pushargr(JIT_R0);
  824. jit_pushargr(JIT_R1);
  825. jit_finishi(alloc_cons);
  826. jit_retval(retreg);
  827. return 1;
  828. }
  829. int compile_list(int retreg, Cell* args, tag_t requires) {
  830. // (list 1)
  831. // compile_arg -> R0
  832. // nil -> R1
  833. int num_items = 0;
  834. while (car(args)) {
  835. int success = compile_arg(JIT_R0, car(args), TAG_ANY);
  836. if (success) {
  837. stack_push(JIT_R0, &stack_ptr);
  838. } else {
  839. while (num_items--) {
  840. // unwind stack
  841. stack_pop(JIT_R1, &stack_ptr);
  842. }
  843. printf("<error compiling list item %d>\r\n",num_items);
  844. jit_movi(retreg, 0);
  845. return 0;
  846. }
  847. args = cdr(args);
  848. num_items++;
  849. }
  850. jit_prepare();
  851. jit_finishi(alloc_nil);
  852. jit_retval(JIT_R1);
  853. jit_movr(JIT_R0, JIT_R1);
  854. while (num_items--) {
  855. jit_prepare();
  856. stack_pop(JIT_R0, &stack_ptr);
  857. jit_pushargr(JIT_R0);
  858. jit_pushargr(JIT_R1);
  859. jit_finishi(alloc_cons);
  860. jit_retval(JIT_R1);
  861. }
  862. jit_movr(retreg, JIT_R1);
  863. return 1;
  864. }
  865. Cell* do_map(Cell* fn, Cell* list) {
  866. // map is special: save only 1 arg
  867. /*char buf[512];
  868. lisp_write(fn,buf,511);
  869. printf("~~ map fn: %p %s\r\n",fn,buf);*/
  870. Cell* argsym = car(((Cell*)fn->addr));
  871. env_entry* e = intern_symbol(argsym, &global_env);
  872. Cell* saved = e->cell;
  873. Cell* result = alloc_nil();
  874. while (car(list)) {
  875. e->cell = car(list);
  876. Cell* res = (Cell*)((funcptr)fn->next)();
  877. list = cdr(list);
  878. result = alloc_cons(res, result);
  879. }
  880. e->cell = saved;
  881. // TODO: build result list
  882. return result;
  883. }
  884. // test: (map (fn x (+ x 1)) (list 1 2 3))
  885. int compile_map(int retreg, Cell* args, tag_t requires) {
  886. // (map fn list)
  887. compile_arg(JIT_R0, car(args), TAG_ANY);
  888. stack_push(JIT_R0, &stack_ptr);
  889. compile_arg(JIT_R1, car(cdr(args)), TAG_ANY);
  890. stack_pop(JIT_R0, &stack_ptr);
  891. jit_prepare();
  892. jit_pushargr(JIT_R0);
  893. jit_pushargr(JIT_R1);
  894. jit_finishi(do_map);
  895. jit_retval(retreg);
  896. return 1;
  897. }
  898. // alloc allocates a bytes object with specified size
  899. // will contain zeroes
  900. int compile_alloc(int retreg, Cell* args, tag_t requires) {
  901. if (!car(args)) return argnum_error("(alloc size)");
  902. Cell* size_arg = car(args);
  903. compile_arg(retreg, size_arg, TAG_PURE_INT); // FIXME check success
  904. jit_prepare();
  905. jit_pushargr(retreg);
  906. jit_finishi(alloc_num_bytes);
  907. jit_retval(retreg); // returns fresh cell
  908. return 1;
  909. }
  910. // alloc_str allocates a string object with specified bytes size
  911. // will contain zeroes
  912. int compile_alloc_str(int retreg, Cell* args, tag_t requires) {
  913. if (!car(args)) return argnum_error("(alloc-str size)");
  914. Cell* size_arg = car(args);
  915. compile_arg(retreg, size_arg, TAG_PURE_INT);
  916. jit_prepare();
  917. jit_pushargr(retreg);
  918. jit_finishi(alloc_num_string);
  919. jit_retval(retreg); // returns fresh cell
  920. return 1;
  921. }
  922. // concat allocates a new string combining two strings or buffers
  923. int compile_concat(int retreg, Cell* args, tag_t requires) {
  924. if (!car(args)) return argnum_error("(concat str1 str2)");
  925. if (!car(cdr(args))) return argnum_error("(concat str1 str2)");
  926. Cell* arg1 = car(args);
  927. compile_arg(JIT_R0, arg1, TAG_ANY);
  928. stack_push(JIT_R0, &stack_ptr);
  929. Cell* arg2 = car(cdr(args));
  930. compile_arg(JIT_R1, arg2, TAG_ANY);
  931. stack_pop(JIT_R0, &stack_ptr);
  932. jit_prepare();
  933. jit_pushargr(JIT_R0);
  934. jit_pushargr(JIT_R1);
  935. jit_finishi(alloc_concat);
  936. jit_retval(retreg); // returns fresh cell
  937. return 1;
  938. }
  939. int compile_substr(int retreg, Cell* args, tag_t requires) {
  940. if (!car(args)) return argnum_error("(substr str1 from len)");
  941. if (!car(cdr(args))) return argnum_error("(substr str1 from len)");
  942. if (!car(cdr(cdr(args)))) return argnum_error("(substr str1 from len)");
  943. Cell* arg3 = car(cdr(cdr(args)));
  944. int success = compile_arg(JIT_R0, arg3, TAG_PURE_INT);
  945. stack_push(JIT_R0, &stack_ptr);
  946. Cell* arg2 = car(cdr(args));
  947. success = compile_arg(JIT_R0, arg2, TAG_PURE_INT);
  948. stack_push(JIT_R0, &stack_ptr);
  949. Cell* arg1 = car(args);
  950. success = compile_arg(JIT_R0, arg1, TAG_ANY);
  951. jit_prepare();
  952. jit_pushargr(JIT_R0);
  953. stack_pop(JIT_R0, &stack_ptr);
  954. jit_pushargr(JIT_R0);
  955. stack_pop(JIT_R0, &stack_ptr);
  956. jit_pushargr(JIT_R0);
  957. jit_finishi(alloc_substr);
  958. jit_retval(retreg); // returns fresh cell
  959. return 1;
  960. }
  961. // write
  962. // allocates a string object and writes s-expression dump of object
  963. // into it
  964. int compile_write(int retreg, Cell* args, tag_t requires) {
  965. if (!car(args)) return argnum_error("(write buffer object)");
  966. Cell* buf_arg = car(args);
  967. compile_arg(JIT_R0, buf_arg, TAG_ANY);
  968. stack_push(JIT_R0, &stack_ptr);
  969. Cell* obj_arg = car(cdr(args));
  970. compile_arg(JIT_R1, obj_arg, TAG_ANY);
  971. stack_pop(JIT_R0, &stack_ptr);
  972. jit_prepare();
  973. jit_pushargr(JIT_R1); // object Cell*
  974. //jit_ldxi(JIT_R1, JIT_R0, sizeof(jit_word_t)); // buffer size
  975. jit_movi(JIT_R1, 1023);
  976. jit_ldr(JIT_R0, JIT_R0);
  977. jit_pushargr(JIT_R0); // buffer char*
  978. jit_pushargr(JIT_R1); // buffer size
  979. jit_finishi(lisp_write);
  980. // FIXME
  981. //jit_retval(retreg); // return target buffer cell
  982. jit_movi(retreg, 0);
  983. return 1;
  984. }
  985. #include "utf8.c"
  986. #include "compile_vector.c"
  987. #include "compile_file_io.c"
  988. #include "compile_input.c"
  989. #include "compile_eval.c"
  990. #include "compile_net.c"
  991. #include "compile_gfx.c"
  992. #include "compile_math.c"
  993. // 0 = failure
  994. // 1 = success
  995. int compile_applic(int retreg, Cell* list, tag_t required) {
  996. jit_note("compile_applic",__LINE__);
  997. debug_current_expr = list;
  998. Cell* op_cell = car(list);
  999. char* fn_name = NULL;
  1000. if (!op_cell) {
  1001. printf("-- apply empty list\n");
  1002. jit_movi(JIT_R0, 0); // will it crash? :3
  1003. return 0;
  1004. }
  1005. int recursion = 0;
  1006. if (op_cell->tag == TAG_SYM) {
  1007. fn_name = op_cell->addr;
  1008. if (fn_name && currently_compiling_fn_sym) {
  1009. //printf("-- fn: %s currently_compiling_fn_sym: %s\n",fn_name,currently_compiling_fn_sym->addr);
  1010. if (strcmp(currently_compiling_fn_sym->addr, fn_name) == 0) {
  1011. // recursion!
  1012. op_cell = currently_compiling_fn_op;
  1013. recursion = 1;
  1014. }
  1015. }
  1016. if (!recursion) {
  1017. op_cell = lookup_symbol(fn_name, &global_env);
  1018. }
  1019. if (!op_cell) {
  1020. // dynamic call?
  1021. //return compile_dynamic_lambda(retreg, car(list), cdr(list), required, &global_env);
  1022. char buf[128];
  1023. lisp_write(list,buf,127);
  1024. printf("<compile_applic: undefined symbol %s near '%s'>\n",fn_name,buf);
  1025. jit_movi(JIT_R0, 0);
  1026. return 0;
  1027. }
  1028. }
  1029. else if (op_cell->tag == TAG_LAMBDA) {
  1030. // direct lambda
  1031. printf("~~ direct lambda\r\n");
  1032. }
  1033. else if (op_cell->tag == TAG_CONS) {
  1034. printf("~~ cons\r\n");
  1035. if (compile_applic(JIT_R0, op_cell, required)) {
  1036. return compile_dynamic_lambda(retreg, JIT_R0, cdr(list), required, &global_env);
  1037. } else {
  1038. return 0;
  1039. }
  1040. }
  1041. else {
  1042. printf("<error:can only apply sym or lambda, got (tag:%d)>\n",op_cell->tag);
  1043. jit_movi(JIT_R0, 0);
  1044. return 0;
  1045. }
  1046. jit_word_t op = op_cell->value;
  1047. if (op_cell->tag == TAG_LAMBDA) {
  1048. if (recursion) {
  1049. printf("-- compile lambda recursion %p\n",op_cell);
  1050. }
  1051. return compile_lambda(retreg, op_cell, cdr(list), required, &global_env, recursion);
  1052. }
  1053. Cell* args = cdr(list);
  1054. switch (op) {
  1055. case BUILTIN_ADD:
  1056. return compile_add(retreg, args, required);
  1057. break;
  1058. case BUILTIN_SUB:
  1059. return compile_sub(retreg, args, required);
  1060. break;
  1061. case BUILTIN_MUL:
  1062. return compile_mul(retreg, args, required);
  1063. break;
  1064. case BUILTIN_DIV:
  1065. return compile_div(retreg, args, required);
  1066. break;
  1067. case BUILTIN_MOD:
  1068. return compile_mod(retreg, args, required);
  1069. break;
  1070. case BUILTIN_LT:
  1071. return compile_lt(retreg, args, required);
  1072. break;
  1073. case BUILTIN_GT:
  1074. return compile_gt(retreg, args, required);
  1075. break;
  1076. case BUILTIN_IF:
  1077. return compile_if(retreg, args, required);
  1078. break;
  1079. case BUILTIN_WHILE:
  1080. return compile_while(retreg, args, required);
  1081. break;
  1082. case BUILTIN_DO:
  1083. return compile_do(retreg, args, required);
  1084. break;
  1085. case BUILTIN_FN:
  1086. return compile_fn(retreg, args, required);
  1087. break;
  1088. case BUILTIN_DEF:
  1089. return compile_def(retreg, args, required);
  1090. break;
  1091. case BUILTIN_QUOTE:
  1092. return compile_quote(retreg, args, required);
  1093. break;
  1094. case BUILTIN_CAR:
  1095. return compile_car(retreg, args, required);
  1096. break;
  1097. case BUILTIN_CDR:
  1098. return compile_cdr(retreg, args, required);
  1099. break;
  1100. case BUILTIN_CONS:
  1101. return compile_cons(retreg, args, required);
  1102. break;
  1103. case BUILTIN_LIST:
  1104. return compile_list(retreg, args, required);
  1105. break;
  1106. case BUILTIN_MAP:
  1107. return compile_map(retreg, args, required);
  1108. break;
  1109. case BUILTIN_ALLOC:
  1110. return compile_alloc(retreg, args, required);
  1111. break;
  1112. case BUILTIN_ALLOC_STR:
  1113. return compile_alloc_str(retreg, args, required);
  1114. break;
  1115. case BUILTIN_CONCAT:
  1116. return compile_concat(retreg, args, required);
  1117. break;
  1118. case BUILTIN_SUBSTR:
  1119. return compile_substr(retreg, args, required);
  1120. break;
  1121. case BUILTIN_WRITE:
  1122. return compile_write(retreg, args, required);
  1123. break;
  1124. case BUILTIN_EVAL:
  1125. return compile_eval(retreg, args, required);
  1126. break;
  1127. case BUILTIN_GET:
  1128. return compile_get(retreg, args, required);
  1129. break;
  1130. case BUILTIN_PUT:
  1131. return compile_put(retreg, args, required);
  1132. break;
  1133. case BUILTIN_SIZE:
  1134. return compile_size(retreg, args, required);
  1135. break;
  1136. case BUILTIN_UGET:
  1137. return compile_uget(retreg, args, required);
  1138. break;
  1139. case BUILTIN_UPUT:
  1140. return compile_uput(retreg, args, required);
  1141. break;
  1142. case BUILTIN_USIZE:
  1143. return compile_usize(retreg, args, required);
  1144. break;
  1145. case BUILTIN_PRINT:
  1146. return compile_print(retreg, args, required);
  1147. break;
  1148. case BUILTIN_PIXEL:
  1149. return compile_pixel(retreg, args);
  1150. break;
  1151. case BUILTIN_RECTFILL:
  1152. return compile_rect_fill(retreg, args);
  1153. break;
  1154. case BUILTIN_FLIP:
  1155. return compile_flip(retreg);
  1156. break;
  1157. case BUILTIN_BLIT:
  1158. return compile_blit(retreg, args);
  1159. break;
  1160. case BUILTIN_BLIT_MONO:
  1161. return compile_blit_mono(retreg, args);
  1162. break;
  1163. case BUILTIN_BLIT_MONO_INV:
  1164. return compile_blit_mono_inv(retreg, args);
  1165. break;
  1166. case BUILTIN_BLIT_STRING:
  1167. return compile_blit_string(retreg, args, required);
  1168. break;
  1169. case BUILTIN_SIN:
  1170. return compile_sin(retreg, args, required);
  1171. break;
  1172. case BUILTIN_COS:
  1173. return compile_cos(retreg, args, required);
  1174. break;
  1175. case BUILTIN_SQRT:
  1176. return compile_sqrt(retreg, args, required);
  1177. break;
  1178. case BUILTIN_INKEY:
  1179. return compile_get_key(retreg, args, required);
  1180. break;
  1181. case BUILTIN_GC:
  1182. return compile_gc(retreg);
  1183. break;
  1184. case BUILTIN_SYMBOLS:
  1185. return compile_symbol_list(retreg);
  1186. break;
  1187. case BUILTIN_LOAD:
  1188. return compile_load(retreg, args, required);
  1189. break;
  1190. case BUILTIN_SAVE:
  1191. return compile_save(retreg, args, required);
  1192. break;
  1193. // TODO refactor networking
  1194. case BUILTIN_UDP_POLL:
  1195. return compile_udp_poll(retreg, args);
  1196. break;
  1197. case BUILTIN_UDP_SEND:
  1198. return compile_udp_send(retreg, args);
  1199. break;
  1200. case BUILTIN_TCP_CONNECT:
  1201. return compile_tcp_connect(retreg, args);
  1202. break;
  1203. case BUILTIN_TCP_SEND:
  1204. return compile_tcp_send(retreg, args);
  1205. break;
  1206. case BUILTIN_TCP_BIND:
  1207. return compile_tcp_bind(retreg, args);
  1208. break;
  1209. }
  1210. return 0;
  1211. }
  1212. void memdump(jit_word_t start,uint32_t len,int raw) {
  1213. for (uint32_t i=0; i<len;) {
  1214. if (!raw) printf("%08x | ",start+i);
  1215. for (uint32_t x=0; x<16; x++) {
  1216. printf("%02x ",*((uint8_t*)start+i+x));
  1217. }
  1218. if (!raw)
  1219. for (uint32_t x=0; x<16; x++) {
  1220. uint8_t c = *((uint8_t*)start+i+x);
  1221. if (c>=32 && c<=128) {
  1222. printf("%c",c);
  1223. } else {
  1224. printf(".");
  1225. }
  1226. }
  1227. printf("\r\n");
  1228. i+=16;
  1229. }
  1230. printf("\r\n\r\n");
  1231. }
  1232. void init_compiler() {
  1233. //memdump(0x6f460,0x200,0);
  1234. //uart_getc();
  1235. //printf("malloc test: %p\r\n",malloc(1024));
  1236. printf("[compiler] creating global env hash table…\r\n");
  1237. global_env = sm_new(1000);
  1238. printf("[compiler] init_allocator…\r\n");
  1239. init_allocator();
  1240. int_cell_regs = (Cell*)malloc(10*sizeof(Cell));
  1241. for (int i=0; i<10; i++) {
  1242. int_cell_regs[i].tag = TAG_INT;
  1243. int_cell_regs[i].value = 0;
  1244. }
  1245. jit_state_stack = (void*)malloc(3*50*sizeof(void*));
  1246. error_cell = alloc_error(0);
  1247. printf("[compiler] inserting symbols…\r\n");
  1248. insert_symbol(alloc_sym("+"), alloc_builtin(BUILTIN_ADD), &global_env);
  1249. insert_symbol(alloc_sym("-"), alloc_builtin(BUILTIN_SUB), &global_env);
  1250. insert_symbol(alloc_sym("*"), alloc_builtin(BUILTIN_MUL), &global_env);
  1251. insert_symbol(alloc_sym("/"), alloc_builtin(BUILTIN_DIV), &global_env);
  1252. insert_symbol(alloc_sym("%"), alloc_builtin(BUILTIN_MOD), &global_env);
  1253. printf("[compiler] arithmetic…\r\n");
  1254. insert_symbol(alloc_sym("lt"), alloc_builtin(BUILTIN_LT), &global_env);
  1255. insert_symbol(alloc_sym("gt"), alloc_builtin(BUILTIN_GT), &global_env);
  1256. printf("[compiler] compare…\r\n");
  1257. insert_symbol(alloc_sym("if"), alloc_builtin(BUILTIN_IF), &global_env);
  1258. insert_symbol(alloc_sym("while"), alloc_builtin(BUILTIN_WHILE), &global_env);
  1259. insert_symbol(alloc_sym("def"), alloc_builtin(BUILTIN_DEF), &global_env);
  1260. insert_symbol(alloc_sym("print"), alloc_builtin(BUILTIN_PRINT), &global_env);
  1261. insert_symbol(alloc_sym("do"), alloc_builtin(BUILTIN_DO), &global_env);
  1262. insert_symbol(alloc_sym("fn"), alloc_builtin(BUILTIN_FN), &global_env);
  1263. printf("[compiler] flow…\r\n");
  1264. insert_symbol(alloc_sym("quote"), alloc_builtin(BUILTIN_QUOTE), &global_env);
  1265. insert_symbol(alloc_sym("car"), alloc_builtin(BUILTIN_CAR), &global_env);
  1266. insert_symbol(alloc_sym("cdr"), alloc_builtin(BUILTIN_CDR), &global_env);
  1267. insert_symbol(alloc_sym("cons"), alloc_builtin(BUILTIN_CONS), &global_env);
  1268. insert_symbol(alloc_sym("list"), alloc_builtin(BUILTIN_LIST), &global_env);
  1269. insert_symbol(alloc_sym("map"), alloc_builtin(BUILTIN_MAP), &global_env);
  1270. printf("[compiler] lists…\r\n");
  1271. insert_symbol(alloc_sym("concat"), alloc_builtin(BUILTIN_CONCAT), &global_env);
  1272. insert_symbol(alloc_sym("substr"), alloc_builtin(BUILTIN_SUBSTR), &global_env);
  1273. insert_symbol(alloc_sym("alloc"), alloc_builtin(BUILTIN_ALLOC), &global_env);
  1274. insert_symbol(alloc_sym("alloc-str"), alloc_builtin(BUILTIN_ALLOC_STR), &global_env);
  1275. printf("[compiler] strings…\r\n");
  1276. insert_symbol(alloc_sym("get"), alloc_builtin(BUILTIN_GET), &global_env);
  1277. insert_symbol(alloc_sym("uget"), alloc_builtin(BUILTIN_UGET), &global_env);
  1278. insert_symbol(alloc_sym("put"), alloc_builtin(BUILTIN_PUT), &global_env);
  1279. insert_symbol(alloc_sym("uput"), alloc_builtin(BUILTIN_UPUT), &global_env);
  1280. insert_symbol(alloc_sym("size"), alloc_builtin(BUILTIN_SIZE), &global_env);
  1281. insert_symbol(alloc_sym("usize"), alloc_builtin(BUILTIN_USIZE), &global_env);
  1282. printf("[compiler] get/put…\r\n");
  1283. insert_symbol(alloc_sym("write"), alloc_builtin(BUILTIN_WRITE), &global_env);
  1284. insert_symbol(alloc_sym("eval"), alloc_builtin(BUILTIN_EVAL), &global_env);
  1285. printf("[compiler] write/eval…\r\n");
  1286. insert_symbol(alloc_sym("pixel"), alloc_builtin(BUILTIN_PIXEL), &global_env);
  1287. insert_symbol(alloc_sym("rectfill"), alloc_builtin(BUILTIN_RECTFILL), &global_env);
  1288. insert_symbol(alloc_sym("flip"), alloc_builtin(BUILTIN_FLIP), &global_env);
  1289. insert_symbol(alloc_sym("blit"), alloc_builtin(BUILTIN_BLIT), &global_env);
  1290. insert_symbol(alloc_sym("blit-mono"), alloc_builtin(BUILTIN_BLIT_MONO), &global_env);
  1291. insert_symbol(alloc_sym("blit-mono-inv"), alloc_builtin(BUILTIN_BLIT_MONO_INV), &global_env);
  1292. insert_symbol(alloc_sym("blit-string"), alloc_builtin(BUILTIN_BLIT_STRING), &global_env);
  1293. insert_symbol(alloc_sym("inkey"), alloc_builtin(BUILTIN_INKEY), &global_env);
  1294. printf("[compiler] graphics…\r\n");
  1295. insert_symbol(alloc_sym("gc"), alloc_builtin(BUILTIN_GC), &global_env);
  1296. insert_symbol(alloc_sym("symbols"), alloc_builtin(BUILTIN_SYMBOLS), &global_env);
  1297. insert_symbol(alloc_sym("load"), alloc_builtin(BUILTIN_LOAD), &global_env);
  1298. insert_symbol(alloc_sym("save"), alloc_builtin(BUILTIN_SAVE), &global_env);
  1299. printf("[compiler] gc/load/save…\r\n");
  1300. insert_symbol(alloc_sym("udp-poll"), alloc_builtin(BUILTIN_UDP_POLL), &global_env);
  1301. insert_symbol(alloc_sym("udp-send"), alloc_builtin(BUILTIN_UDP_SEND), &global_env);
  1302. printf("[compiler] udp…\r\n");
  1303. insert_symbol(alloc_sym("tcp-bind"), alloc_builtin(BUILTIN_TCP_BIND), &global_env);
  1304. insert_symbol(alloc_sym("tcp-connect"), alloc_builtin(BUILTIN_TCP_CONNECT), &global_env);
  1305. insert_symbol(alloc_sym("tcp-send"), alloc_builtin(BUILTIN_TCP_SEND), &global_env);
  1306. printf("[compiler] tcp…\r\n");
  1307. insert_symbol(alloc_sym("sin"), alloc_builtin(BUILTIN_SIN), &global_env);
  1308. insert_symbol(alloc_sym("cos"), alloc_builtin(BUILTIN_COS), &global_env);
  1309. insert_symbol(alloc_sym("sqrt"), alloc_builtin(BUILTIN_SQRT), &global_env);
  1310. printf("[compiler] math.\r\n");
  1311. //int num_syms=HASH_COUNT(global_env);
  1312. int num_syms = sm_get_count(global_env);
  1313. printf("sledge knows %u symbols. enter (symbols) to see them.\r\n", num_syms);
  1314. }