compiler_new.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359
  1. #include "minilisp.h"
  2. #include "reader.h"
  3. #include "writer.h"
  4. #include "alloc.h"
  5. #include "compiler_new.h"
  6. #include "stream.h"
  7. #include "utf8.c"
  8. #define env_t StrMap
  9. static env_t* global_env = NULL;
  10. //#define CHECK_BOUNDS // enforce boundaries of array put/get
  11. #define ARG_SPILLOVER 3 // max 4 args (0-3) via regs, rest via stack
  12. #define LBDREG R4 // register base used for passing args to functions
  13. static int debug_mode = 0;
  14. env_entry* lookup_global_symbol(char* name) {
  15. env_entry* res;
  16. int found = sm_get(global_env, name, (void**)&res);
  17. //printf("[lookup] %s res: %p\n",name,res);
  18. if (!found) return NULL;
  19. return res;
  20. }
  21. Cell* insert_symbol(Cell* symbol, Cell* cell, env_t** env) {
  22. env_entry* e;
  23. int found = sm_get(*env, symbol->addr, (void**)&e);
  24. //printf("sm_get res: %d\r\n",found);
  25. if (found) {
  26. e->cell = cell;
  27. //printf("[insert_symbol] update %s entry at %p (cell: %p value: %d)\r\n",symbol->addr,e,e->cell,e->cell->value);
  28. return e->cell;
  29. }
  30. e = malloc(sizeof(env_entry));
  31. memcpy(e->name, (char*)symbol->addr, symbol->size);
  32. e->cell = cell;
  33. //printf("[insert_symbol] %s entry at %p (cell: %p)\r\n",symbol->addr,e,e->cell);
  34. sm_put(*env, e->name, e);
  35. return e->cell;
  36. }
  37. Cell* insert_global_symbol(Cell* symbol, Cell* cell) {
  38. return insert_symbol(symbol, cell, &global_env);
  39. }
  40. #define TMP_PRINT_BUFSZ 1024
  41. static FILE* jit_out;
  42. static Cell* cell_heap_start;
  43. static int label_skip_count = 0;
  44. static char temp_print_buffer[TMP_PRINT_BUFSZ];
  45. static Cell* consed_type_error;
  46. static Cell* reusable_type_error;
  47. static Cell* reusable_nil;
  48. #ifdef CPU_ARM
  49. #include "jit_arm_raw.c"
  50. #define PTRSZ 4
  51. #endif
  52. #ifdef CPU_X64
  53. #include "jit_x64.c"
  54. #define PTRSZ 8
  55. #endif
  56. #ifdef CPU_X86
  57. #include "jit_x86.c"
  58. #define PTRSZ 4
  59. #endif
  60. Cell* lisp_print(Cell* arg) {
  61. lisp_write(arg, temp_print_buffer, TMP_PRINT_BUFSZ);
  62. printf("%s\r\n",temp_print_buffer);
  63. return arg;
  64. }
  65. void load_int(int dreg, Arg arg, Frame* f) {
  66. if (arg.type == ARGT_CONST) {
  67. // argument is a constant like 123, "foo"
  68. jit_movi(dreg, (jit_word_t)arg.cell->value);
  69. }
  70. else if (arg.type == ARGT_CELL) {
  71. if (arg.cell == NULL) {
  72. // not sure what this is
  73. //if (dreg!=R0) jit_movr(dreg, R0);
  74. if (dreg!=R1+arg.slot) {
  75. jit_movr(dreg, R1+arg.slot); // FIXME: really true?
  76. }
  77. jit_ldr(dreg);
  78. } else {
  79. // argument is a cell pointer
  80. jit_lea(dreg, arg.cell);
  81. jit_ldr(dreg);
  82. }
  83. }
  84. else if (arg.type == ARGT_ENV) {
  85. // argument is an environment table entry, load e->cell->value
  86. jit_lea(dreg, arg.env);
  87. jit_ldr(dreg);
  88. jit_ldr(dreg);
  89. }
  90. else if (arg.type == ARGT_REG) {
  91. // argument comes from a register
  92. jit_movr(dreg, LBDREG+arg.slot);
  93. jit_ldr(dreg);
  94. }
  95. else if (arg.type == ARGT_INT) {
  96. if (dreg!=R1+arg.slot) {
  97. jit_movr(dreg, R1+arg.slot); // FIXME: really true?
  98. }
  99. }
  100. else if (arg.type == ARGT_STACK) {
  101. jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
  102. jit_ldr(dreg);
  103. }
  104. else if (arg.type == ARGT_STACK_INT) {
  105. jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
  106. }
  107. else {
  108. jit_movi(dreg, 0xdeadbeef);
  109. }
  110. }
  111. void load_cell(int dreg, Arg arg, Frame* f) {
  112. if (arg.type == ARGT_CELL || arg.type == ARGT_CONST) {
  113. if (arg.cell == NULL) {
  114. // not sure what this is
  115. jit_movr(dreg, R1+arg.slot); // FIXME: really true?
  116. } else {
  117. // argument is a cell pointer
  118. jit_lea(dreg, arg.cell);
  119. }
  120. }
  121. else if (arg.type == ARGT_ENV) {
  122. jit_lea(dreg, arg.env);
  123. jit_ldr(dreg);
  124. }
  125. else if (arg.type == ARGT_REG) {
  126. jit_movr(dreg, LBDREG+arg.slot);
  127. }
  128. else if (arg.type == ARGT_STACK) {
  129. jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
  130. }
  131. else if (arg.type == ARGT_STACK_INT) {
  132. // FIXME possible ARGR0 clobbering
  133. int adjust = 0;
  134. if (dreg!=ARGR0) {jit_push(ARGR0,ARGR0); adjust++;}
  135. if (dreg!=R0) {jit_push(R0,R0); adjust++;}
  136. jit_ldr_stack(ARGR0, PTRSZ*(arg.slot+f->sp+adjust));
  137. jit_call(alloc_int, "alloc_int");
  138. jit_movr(dreg,R0);
  139. if (dreg!=R0) jit_pop(R0,R0);
  140. if (dreg!=ARGR0) jit_pop(ARGR0,ARGR0);
  141. }
  142. else {
  143. jit_movi(dreg, 0xdeadcafe);
  144. }
  145. }
  146. int get_sym_frame_idx(char* argname, Arg* fn_frame, int ignore_regs) {
  147. if (!fn_frame) return -1;
  148. for (int i=0; i<MAXFRAME; i++) {
  149. if (fn_frame[i].name) {
  150. //printf("<< get_sym_frame_idx %i (type %d, reg = %d, looking for %s): %s\n",i,fn_frame[i].type,ARGT_REG,argname,fn_frame[i].name);
  151. if (!((fn_frame[i].type == ARGT_REG) && ignore_regs)) {
  152. if (!strcmp(argname, fn_frame[i].name)) {
  153. //printf("!! get_sym_frame_idx %i (type %d): %s\n",i,fn_frame[i].type,fn_frame[i].name);
  154. //printf("returning %d\n",i);
  155. return i;
  156. }
  157. }
  158. }
  159. }
  160. return -1;
  161. }
  162. // TODO: optimize!
  163. int push_frame_regs(Arg* fn_frame) {
  164. if (!fn_frame) return 0;
  165. int pushreg=0;
  166. int pushstack=0;
  167. for (int i=0; i<MAXFRAME; i++) {
  168. if (fn_frame[i].type == ARGT_REG) {
  169. pushreg++;
  170. }
  171. }
  172. //printf("pushing %d frame regs\n",pushreg);
  173. if (pushreg) {
  174. jit_push(LBDREG,LBDREG+pushreg-1);
  175. }
  176. return pushreg;
  177. }
  178. int pop_frame_regs(Arg* fn_frame) {
  179. if (!fn_frame) return 0;
  180. int pushreg=0;
  181. int pushstack=0;
  182. for (int i=0; i<MAXFRAME; i++) {
  183. if (fn_frame[i].type == ARGT_REG) {
  184. pushreg++;
  185. }
  186. }
  187. //printf("popping %d frame regs\n",pushreg);
  188. if (pushreg) {
  189. jit_pop(LBDREG,LBDREG+pushreg-1);
  190. }
  191. return pushreg;
  192. }
  193. static char* analyze_buffer[MAXFRAME];
  194. int analyze_fn(Cell* expr, Cell* parent, int num_lets) {
  195. if (expr->tag == TAG_SYM) {
  196. env_entry* op_env = lookup_global_symbol(expr->addr);
  197. if (op_env) {
  198. Cell* op = op_env->cell;
  199. if (op->tag == TAG_BUILTIN) {
  200. //printf("analyze_fn: found builtin: %s\n",expr->addr);
  201. if (op->value == BUILTIN_LET) {
  202. Cell* sym = car(cdr(parent));
  203. if (sym) {
  204. int existing = 0;
  205. for (int i=0; i<num_lets; i++) {
  206. if (!strcmp(analyze_buffer[i], sym->addr)) {
  207. //printf("-- we already know local %s\r\n",sym->addr);
  208. existing = 1;
  209. break;
  210. }
  211. }
  212. if (!existing) {
  213. analyze_buffer[num_lets] = sym->addr;
  214. num_lets++;
  215. }
  216. } else {
  217. printf("!! analyze error: malformed let!\r\n");
  218. }
  219. }
  220. }
  221. }
  222. }
  223. else if (expr->tag == TAG_CONS) {
  224. if (car(expr)) {
  225. num_lets = analyze_fn(car(expr), expr, num_lets);
  226. }
  227. if (cdr(expr)) {
  228. num_lets = analyze_fn(cdr(expr), expr, num_lets);
  229. }
  230. }
  231. return num_lets;
  232. }
  233. int compile_expr(Cell* expr, Frame* frame, int return_type) {
  234. if (!expr) return 0;
  235. if (!frame) return 0;
  236. int compiled_type = TAG_ANY;
  237. Arg* fn_frame = frame->f;
  238. if (expr->tag != TAG_CONS) {
  239. if (expr->tag == TAG_SYM) {
  240. int arg_frame_idx = get_sym_frame_idx(expr->addr, fn_frame, 0);
  241. if (arg_frame_idx>=0) {
  242. load_cell(R0, fn_frame[arg_frame_idx], frame);
  243. return compiled_type;
  244. }
  245. env_entry* env = lookup_global_symbol(expr->addr);
  246. if (env) {
  247. Cell* value = env->cell;
  248. jit_movi(R0,(jit_word_t)env);
  249. jit_ldr(R0);
  250. return value->tag; // FIXME TODO forbid later type change
  251. } else {
  252. printf("undefined symbol %s\n",expr->addr);
  253. jit_movi(R0,0);
  254. return 0;
  255. }
  256. } else {
  257. // return the expr
  258. jit_movi(R0,(jit_word_t)expr);
  259. return compiled_type;
  260. }
  261. return 0;
  262. }
  263. cell_heap_start = get_cell_heap();
  264. Cell* opsym = car(expr);
  265. Cell* args = cdr(expr);
  266. Cell* orig_args = args; // keep around for specials forms like DO
  267. Cell* signature_args = NULL;
  268. if (!opsym || opsym->tag != TAG_SYM) {
  269. printf("[compile_expr] error: non-symbol in operator position.\n");
  270. return 0;
  271. }
  272. env_entry* op_env = lookup_global_symbol(opsym->addr);
  273. if (!op_env || !op_env->cell) {
  274. printf("[compile_expr] error: undefined symbol %s in operator position.\n",opsym->addr);
  275. return 0;
  276. }
  277. Cell* op = op_env->cell;
  278. int is_let = 0;
  279. //printf("op tag: %d\n",op->tag);
  280. if (op->tag == TAG_BUILTIN) {
  281. signature_args = op->next;
  282. if (op->value == BUILTIN_LET) {
  283. is_let = 1;
  284. }
  285. } else if (op->tag == TAG_LAMBDA) {
  286. signature_args = car((Cell*)(op->addr));
  287. } else {
  288. printf("[compile-expr] error: non-lambda symbol %s in operator position.\n",opsym->addr);
  289. return 0;
  290. }
  291. //printf("[op] %s\n",debug_buf);
  292. //lisp_write(signature_args, debug_buf, sizeof(debug_buf));
  293. //printf("[sig] %s\n",debug_buf);
  294. if (debug_mode) {
  295. push_frame_regs(frame->f);
  296. char* debug_buf = malloc(256);
  297. lisp_write(expr, debug_buf, 256);
  298. jit_push(R0, ARGR1);
  299. jit_lea(ARGR0, debug_buf);
  300. jit_lea(ARGR1, frame);
  301. jit_call(debug_handler,"dbg");
  302. jit_pop(R0, ARGR1);
  303. pop_frame_regs(frame->f);
  304. }
  305. // first, we need a signature
  306. int argi = 0;
  307. Arg argdefs[MAXARGS];
  308. do {
  309. Cell* arg = car(args);
  310. Cell* signature_arg = car(signature_args);
  311. char arg_name[32];
  312. snprintf(arg_name,sizeof(arg_name),"a%d",argi+1,arg_name,10);
  313. // 1. is the arg the required type? i.e. a pointer or a number?
  314. if (signature_arg && signature_arg->tag == TAG_CONS) {
  315. // named argument
  316. snprintf(arg_name,sizeof(arg_name),car(signature_arg)->addr);
  317. signature_arg = cdr(signature_arg);
  318. }
  319. if (arg && (!signature_args || signature_arg)) {
  320. int given_tag = arg->tag;
  321. if (is_let && argi==1) {
  322. int type_hint = -1;
  323. // check the symbol to see if we already have type information
  324. int fidx = get_sym_frame_idx(argdefs[0].cell->addr, fn_frame, 1);
  325. if (fidx>=0) {
  326. //printf("existing type information for %s: %d\r\n", argdefs[0].cell->addr,fn_frame[fidx].type);
  327. type_hint = fn_frame[fidx].type;
  328. }
  329. if (given_tag == TAG_INT || type_hint == ARGT_STACK_INT) {
  330. //printf("INT mode of let\r\n");
  331. // let prefers raw integers!
  332. signature_arg->value = TAG_INT;
  333. } else {
  334. //printf("ANY mode of let\r\n");
  335. // but cells are ok, too
  336. signature_arg->value = TAG_ANY;
  337. }
  338. }
  339. if (!signature_args) {
  340. // any number of arguments allowed
  341. argdefs[argi].cell = arg;
  342. argdefs[argi].type = ARGT_CELL;
  343. }
  344. else if (signature_arg->value == TAG_LAMBDA) {
  345. // lazy evaluation by form
  346. argdefs[argi].cell = arg;
  347. argdefs[argi].type = ARGT_LAMBDA;
  348. }
  349. else if (arg->tag == TAG_CONS) {
  350. // eager evaluation
  351. // nested expression
  352. if (argi>0) {
  353. // save registers
  354. // FIXME RETHINK
  355. jit_push(R1,R1+argi-1);
  356. frame->sp+=(1+argi-1);
  357. }
  358. given_tag = compile_expr(arg, frame, signature_arg->value);
  359. if (given_tag<1) return given_tag; // failure
  360. argdefs[argi].cell = NULL; // cell is in R0 at runtime
  361. argdefs[argi].slot = argi;
  362. if (given_tag == TAG_INT) {
  363. argdefs[argi].type = ARGT_INT;
  364. jit_movr(R1+argi,ARGR0);
  365. } else {
  366. argdefs[argi].type = ARGT_CELL;
  367. jit_movr(R1+argi,R0);
  368. }
  369. if (argi>0) {
  370. jit_pop(R1,R1+argi-1);
  371. frame->sp-=(1+argi-1);
  372. }
  373. }
  374. else if (given_tag == TAG_SYM && signature_arg->value != TAG_SYM) {
  375. // symbol given, lookup (indirect)
  376. //printf("indirect symbol lookup (name: %p)\n",arg->value);
  377. int arg_frame_idx = get_sym_frame_idx(arg->addr, fn_frame, 0);
  378. // argument passed to function in register
  379. if (arg_frame_idx>=0) {
  380. argdefs[argi] = fn_frame[arg_frame_idx];
  381. //printf("argument %s from stack frame.\n", arg->addr);
  382. } else {
  383. argdefs[argi].env = lookup_global_symbol((char*)arg->addr);
  384. argdefs[argi].type = ARGT_ENV;
  385. //printf("argument %s from environment.\n", arg->addr);
  386. }
  387. //printf("arg_frame_idx: %d\n",arg_frame_idx);
  388. if (!argdefs[argi].env && arg_frame_idx<0) {
  389. printf("undefined symbol %s given for argument %s.\n",arg->addr,arg_name);
  390. return 0;
  391. }
  392. }
  393. else if (given_tag == signature_arg->value || signature_arg->value==TAG_ANY) {
  394. argdefs[argi].cell = arg;
  395. argdefs[argi].slot = argi-1;
  396. argdefs[argi].type = ARGT_CELL;
  397. if (given_tag == TAG_SYM || given_tag == TAG_CONS || given_tag == TAG_INT || given_tag == TAG_STR || given_tag == TAG_BYTES) {
  398. argdefs[argi].type = ARGT_CONST;
  399. //printf("const arg of type %d at %p\n",arg->tag,arg);
  400. }
  401. } else {
  402. // check if we can typecast
  403. // else, fail with type error
  404. printf("!! type mismatch for argument %s (given %s, expected %s)!\n",arg_name,tag_to_str(given_tag),tag_to_str(signature_arg->value));
  405. return 0;
  406. }
  407. } else {
  408. if (!arg && signature_arg) {
  409. // missing arguments
  410. printf("!! argument %s missing!\n",arg_name);
  411. return 0;
  412. } else if (arg && !signature_arg) {
  413. // surplus arguments
  414. printf("!! surplus arguments!\n");
  415. return 0;
  416. }
  417. }
  418. argi++;
  419. } while (argi<MAXARGS && (args = cdr(args)) && (!signature_args || (signature_args = cdr(signature_args))));
  420. if (op->tag == TAG_BUILTIN) {
  421. switch (op->value) {
  422. case BUILTIN_BITAND: {
  423. load_int(ARGR0,argdefs[0], frame);
  424. load_int(R2,argdefs[1], frame);
  425. jit_andr(ARGR0,R2);
  426. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  427. else compiled_type = TAG_INT;
  428. break;
  429. }
  430. case BUILTIN_BITOR: {
  431. load_int(ARGR0,argdefs[0], frame);
  432. load_int(R2,argdefs[1], frame);
  433. jit_orr(ARGR0,R2);
  434. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  435. else compiled_type = TAG_INT;
  436. break;
  437. }
  438. case BUILTIN_BITXOR: {
  439. load_int(ARGR0,argdefs[0], frame);
  440. load_int(R2,argdefs[1], frame);
  441. jit_xorr(ARGR0,R2);
  442. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  443. else compiled_type = TAG_INT;
  444. break;
  445. }
  446. case BUILTIN_SHL: {
  447. load_int(ARGR0,argdefs[0], frame);
  448. load_int(R2,argdefs[1], frame);
  449. jit_shlr(ARGR0,R2);
  450. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  451. else compiled_type = TAG_INT;
  452. break;
  453. }
  454. case BUILTIN_SHR: {
  455. load_int(ARGR0,argdefs[0], frame);
  456. load_int(R2,argdefs[1], frame);
  457. jit_shrr(ARGR0,R2);
  458. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  459. else compiled_type = TAG_INT;
  460. break;
  461. }
  462. case BUILTIN_ADD: {
  463. load_int(ARGR0,argdefs[0], frame);
  464. load_int(R2,argdefs[1], frame);
  465. jit_addr(ARGR0,R2);
  466. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  467. else compiled_type = TAG_INT;
  468. break;
  469. }
  470. case BUILTIN_SUB: {
  471. load_int(ARGR0,argdefs[0], frame);
  472. load_int(R2,argdefs[1], frame);
  473. jit_subr(ARGR0,R2);
  474. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  475. else compiled_type = TAG_INT;
  476. break;
  477. }
  478. case BUILTIN_MUL: {
  479. load_int(ARGR0,argdefs[0], frame);
  480. load_int(R2,argdefs[1], frame);
  481. jit_mulr(ARGR0,R2);
  482. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  483. else compiled_type = TAG_INT;
  484. break;
  485. }
  486. case BUILTIN_DIV: {
  487. load_int(ARGR0,argdefs[0], frame);
  488. load_int(R2,argdefs[1], frame);
  489. jit_divr(ARGR0,R2);
  490. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  491. else compiled_type = TAG_INT;
  492. break;
  493. }
  494. case BUILTIN_MOD: {
  495. load_int(ARGR0,argdefs[0], frame);
  496. load_int(R2,argdefs[1], frame);
  497. jit_modr(ARGR0,R2);
  498. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  499. else compiled_type = TAG_INT;
  500. break;
  501. }
  502. case BUILTIN_GT: {
  503. load_int(ARGR0,argdefs[0], frame);
  504. load_int(R2,argdefs[1], frame);
  505. jit_subr(R2,ARGR0);
  506. jit_movi(ARGR0,0);
  507. jit_movi(R2,1);
  508. jit_movneg(ARGR0,R2);
  509. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  510. else compiled_type = TAG_INT;
  511. break;
  512. }
  513. case BUILTIN_LT: {
  514. load_int(ARGR0,argdefs[0], frame);
  515. load_int(R2,argdefs[1], frame);
  516. jit_subr(ARGR0,R2);
  517. jit_movi(ARGR0,0);
  518. jit_movi(R2,1);
  519. jit_movneg(ARGR0,R2);
  520. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  521. else compiled_type = TAG_INT;
  522. break;
  523. }
  524. case BUILTIN_DEF: {
  525. // TODO in the future, we could pre-allocate symbols
  526. // and especially their types based on type inference
  527. jit_lea(ARGR0,argdefs[0].cell); // load symbol address
  528. load_cell(ARGR1,argdefs[1],frame);
  529. push_frame_regs(frame->f);
  530. jit_call2(insert_global_symbol, "insert_global_symbol");
  531. pop_frame_regs(frame->f);
  532. break;
  533. }
  534. case BUILTIN_LET: {
  535. if (!frame->f) {
  536. printf("<error: let is not allowed on global level, only in fn>\r\n");
  537. return 0;
  538. }
  539. int is_int = 0;
  540. int offset = MAXARGS + frame->locals;
  541. int fidx = get_sym_frame_idx(argdefs[0].cell->addr, fn_frame, 0);
  542. // el cheapo type inference
  543. if (1 &&
  544. (argdefs[1].type == ARGT_INT ||
  545. argdefs[1].type == ARGT_STACK_INT ||
  546. (argdefs[1].type == ARGT_CONST && argdefs[1].cell->tag == TAG_INT) ||
  547. (fidx>=0 && fn_frame[fidx].type == ARGT_STACK_INT) // already defined as int TODO: error on attempted type change
  548. )) {
  549. load_int(R0, argdefs[1], frame);
  550. is_int = 1;
  551. compiled_type = TAG_INT;
  552. } else {
  553. load_cell(R0, argdefs[1], frame);
  554. compiled_type = TAG_ANY;
  555. }
  556. int is_reg = 0;
  557. if (fidx >= 0) {
  558. // existing stack entry
  559. offset = fidx;
  560. //printf("+~ frame entry %s, existing stack-local idx %d\n",fn_frame[offset].name,fn_frame[offset].slot);
  561. if (fn_frame[offset].type == ARGT_REG) {
  562. is_reg = 1;
  563. }
  564. } else {
  565. fn_frame[offset].name = argdefs[0].cell->addr;
  566. fn_frame[offset].cell = NULL;
  567. if (is_int) {
  568. fn_frame[offset].type = ARGT_STACK_INT;
  569. } else {
  570. fn_frame[offset].type = ARGT_STACK;
  571. }
  572. fn_frame[offset].slot = frame->locals;
  573. //printf("++ frame entry %s, new stack-local idx %d, is_int %d\n",fn_frame[offset].name,fn_frame[offset].slot,is_int);
  574. frame->locals++;
  575. }
  576. if (!is_reg) {
  577. jit_str_stack(R0,PTRSZ*(fn_frame[offset].slot+frame->sp));
  578. }
  579. if (compiled_type == TAG_INT && return_type == TAG_ANY) {
  580. jit_movr(ARGR0,R0);
  581. jit_call(alloc_int, "alloc_int");
  582. compiled_type = TAG_ANY;
  583. }
  584. if (is_reg) {
  585. jit_movr(LBDREG + fn_frame[offset].slot, R0);
  586. printf("let %s to reg: %d\r\n",fn_frame[offset].name, LBDREG + fn_frame[offset].slot);
  587. }
  588. break;
  589. }
  590. case BUILTIN_FN: {
  591. if (argi<2) {
  592. printf("error: trying to define fn without body.\n");
  593. return 0;
  594. }
  595. // body
  596. Cell* fn_body = argdefs[argi-2].cell;
  597. // estimate stack space for locals
  598. int num_lets = analyze_fn(fn_body,NULL,0);
  599. // scan args (build signature)
  600. Cell* fn_args = alloc_nil();
  601. Arg fn_new_frame[MAXFRAME];
  602. for (int i=0; i<MAXFRAME; i++) {
  603. fn_new_frame[i].type = 0;
  604. fn_new_frame[i].slot = -1;
  605. fn_new_frame[i].name = NULL;
  606. }
  607. int spo_count = 0;
  608. int fn_argc = 0;
  609. for (int j=argi-3; j>=0; j--) {
  610. Cell* arg = alloc_cons(alloc_sym(argdefs[j].cell->addr),alloc_int(TAG_ANY));
  611. fn_args = alloc_cons(arg,fn_args);
  612. if (j>=ARG_SPILLOVER) { // max args passed in registers
  613. fn_new_frame[j].type = ARGT_STACK;
  614. fn_new_frame[j].slot = num_lets + 2 + ((argi-3)-j);
  615. spo_count++;
  616. }
  617. else {
  618. fn_new_frame[j].type = ARGT_REG;
  619. fn_new_frame[j].slot = j;
  620. }
  621. fn_new_frame[j].name = argdefs[j].cell->addr;
  622. fn_argc++;
  623. //printf("arg j %d: %s\r\n",j,fn_new_frame[j].name);
  624. }
  625. //char sig_debug[128];
  626. //lisp_write(fn_args, sig_debug, sizeof(sig_debug));
  627. //printf("signature: %s\n",sig_debug);
  628. //lisp_write(fn_body, sig_debug, sizeof(sig_debug));
  629. Cell* lambda = alloc_lambda(alloc_cons(fn_args,fn_body));
  630. lambda->next = 0;
  631. char label_fn[64];
  632. char label_fe[64];
  633. sprintf(label_fn,"f0_%p",lambda);
  634. sprintf(label_fe,"f1_%p",lambda);
  635. jit_jmp(label_fe);
  636. jit_label(label_fn);
  637. jit_movi(R2,(jit_word_t)lambda|STACK_FRAME_MARKER);
  638. jit_push(R2,R2);
  639. jit_dec_stack(num_lets*PTRSZ);
  640. Frame* nframe_ptr;
  641. Frame nframe = {fn_new_frame, 0, 0, frame->stack_end};
  642. if (debug_mode) {
  643. // in debug mode, we need a copy of the frame definition at runtime
  644. nframe_ptr = malloc(sizeof(Frame));
  645. memcpy(nframe_ptr, &nframe, sizeof(Frame));
  646. Arg* nargs_ptr = malloc(sizeof(Arg)*MAXFRAME);
  647. memcpy(nargs_ptr, nframe.f, sizeof(Arg)*MAXFRAME);
  648. nframe_ptr->f = nargs_ptr;
  649. printf("frame copied: %p args: %p\r\n",nframe_ptr,nframe_ptr->f);
  650. } else {
  651. nframe_ptr = &nframe;
  652. }
  653. int tag = compile_expr(fn_body, nframe_ptr, TAG_ANY); // new frame, fresh sp
  654. if (!tag) return 0;
  655. //printf(">> fn has %d args and %d locals. predicted locals: %d\r\n",fn_argc,nframe.locals,num_lets);
  656. jit_inc_stack(num_lets*PTRSZ);
  657. jit_inc_stack(PTRSZ);
  658. jit_ret();
  659. jit_label(label_fe);
  660. jit_lea(R0,lambda);
  661. #ifdef CPU_ARM
  662. Label* fn_lbl = find_label(label_fn);
  663. //printf("fn_lbl idx: %d code: %p\r\n",fn_lbl->idx,code);
  664. lambda->next = code + fn_lbl->idx;
  665. //printf("fn_lbl next: %p\r\n",lambda->next);
  666. #endif
  667. break;
  668. }
  669. case BUILTIN_IF: {
  670. // load the condition
  671. load_int(R0, argdefs[0], frame);
  672. char label_skip[64];
  673. sprintf(label_skip,"else_%d",++label_skip_count);
  674. // compare to zero
  675. jit_cmpi(R0,0);
  676. jit_je(label_skip);
  677. int tag = compile_expr(argdefs[1].cell, frame, return_type);
  678. if (!tag) return 0;
  679. // else?
  680. if (argdefs[2].cell) {
  681. char label_end[64];
  682. sprintf(label_end,"endif_%d",++label_skip_count);
  683. jit_jmp(label_end);
  684. jit_label(label_skip);
  685. tag = compile_expr(argdefs[2].cell, frame, return_type);
  686. if (!tag) return 0;
  687. jit_label(label_end);
  688. } else {
  689. jit_label(label_skip);
  690. }
  691. break;
  692. }
  693. case BUILTIN_WHILE: {
  694. // load the condition
  695. char label_loop[64];
  696. sprintf(label_loop,"loop_%d",++label_skip_count);
  697. char label_skip[64];
  698. sprintf(label_skip,"skip_%d",label_skip_count);
  699. jit_label(label_loop);
  700. int compiled_type = compile_expr(argdefs[0].cell, frame, TAG_INT);
  701. if (!compiled_type) return 0;
  702. if (compiled_type != TAG_INT) {
  703. jit_ldr(R0);
  704. jit_cmpi(R0,0);
  705. } else {
  706. jit_cmpi(ARGR0,0);
  707. }
  708. //load_int(R1,argdefs[0]);
  709. // compare to zero
  710. jit_je(label_skip);
  711. int tag = compile_expr(argdefs[1].cell, frame, return_type);
  712. if (!tag) return 0;
  713. jit_jmp(label_loop);
  714. jit_label(label_skip);
  715. break;
  716. }
  717. case BUILTIN_DO: {
  718. args = orig_args;
  719. Cell* arg;
  720. if (!car(args)) {
  721. printf("<empty (do) not allowed>\r\n");
  722. return 0;
  723. }
  724. while ((arg = car(args))) {
  725. int tag;
  726. if (car(cdr(args))) {
  727. // discard all returns except for the last one
  728. tag = compile_expr(arg, frame, TAG_VOID);
  729. } else {
  730. tag = compile_expr(arg, frame, return_type);
  731. }
  732. if (!tag) return 0;
  733. args = cdr(args);
  734. }
  735. break;
  736. }
  737. case BUILTIN_LIST: {
  738. args = orig_args;
  739. Cell* arg;
  740. int n = 0;
  741. while ((arg = car(args))) {
  742. int tag = compile_expr(arg, frame, TAG_ANY);
  743. if (!tag) return 0;
  744. jit_push(R0,R0);
  745. frame->sp++;
  746. args = cdr(args);
  747. n++;
  748. }
  749. jit_call(alloc_nil, "list:alloc_nil");
  750. jit_movr(ARGR1,R0);
  751. for (int i=0; i<n; i++) {
  752. jit_pop(ARGR0,ARGR0);
  753. frame->sp--;
  754. jit_call2(alloc_cons, "list:alloc_cons");
  755. jit_movr(ARGR1,R0);
  756. }
  757. break; // FIXME
  758. }
  759. case BUILTIN_QUOTE: {
  760. args = orig_args;
  761. if (!car(args)) {
  762. printf("<empty (quote) not allowed>\r\n");
  763. return 0;
  764. }
  765. Cell* arg = car(args);
  766. jit_lea(R0,arg);
  767. break;
  768. }
  769. case BUILTIN_CAR: {
  770. load_cell(R0,argdefs[0], frame);
  771. // type check -------------------
  772. jit_movr(R1,R0);
  773. jit_addi(R1,2*PTRSZ);
  774. jit_ldr(R1);
  775. jit_lea(R2,consed_type_error);
  776. jit_cmpi(R1,TAG_CONS);
  777. jit_movne(R0,R2);
  778. // ------------------------------
  779. jit_ldr(R0);
  780. jit_lea(R2,reusable_nil);
  781. jit_cmpi(R0,0); // check for null cell
  782. jit_moveq(R0,R2);
  783. break;
  784. }
  785. case BUILTIN_CDR: {
  786. load_cell(R0,argdefs[0], frame);
  787. jit_addi(R0,PTRSZ);
  788. // type check -------------------
  789. jit_movr(R1,R0);
  790. jit_addi(R1,PTRSZ); // because already added PTRSZ
  791. jit_ldr(R1);
  792. jit_lea(R2,consed_type_error);
  793. jit_cmpi(R1,TAG_CONS);
  794. jit_movne(R0,R2);
  795. // ------------------------------
  796. jit_ldr(R0);
  797. jit_lea(R2,reusable_nil);
  798. jit_cmpi(R0,0); // check for null cell
  799. jit_moveq(R0,R2);
  800. break;
  801. }
  802. case BUILTIN_CONS: {
  803. load_cell(ARGR0,argdefs[0], frame);
  804. load_cell(ARGR1,argdefs[1], frame);
  805. jit_call2(alloc_cons,"alloc_cons");
  806. break;
  807. }
  808. case BUILTIN_CONCAT: {
  809. load_cell(ARGR0,argdefs[0], frame);
  810. load_cell(ARGR1,argdefs[1], frame);
  811. jit_call2(alloc_concat,"alloc_concat");
  812. break;
  813. }
  814. case BUILTIN_SUBSTR: {
  815. load_cell(ARGR0,argdefs[0], frame);
  816. load_int(ARGR1,argdefs[1], frame);
  817. load_int(ARGR2,argdefs[2], frame);
  818. jit_call3(alloc_substr,"alloc_substr");
  819. break;
  820. }
  821. case BUILTIN_GET: {
  822. load_cell(R1,argdefs[0], frame);
  823. load_int(R2,argdefs[1], frame); // offset -> R2
  824. char label_skip[64];
  825. sprintf(label_skip,"skip_%d",++label_skip_count);
  826. char label_ok[64];
  827. sprintf(label_ok,"ok_%d",label_skip_count);
  828. // init r3
  829. jit_movi(R3, 0);
  830. // todo: compile-time checking would be much more awesome
  831. // type check
  832. jit_addi(R1,2*PTRSZ);
  833. jit_ldr(R1);
  834. jit_cmpi(R1,TAG_BYTES); // todo: better perf with mask?
  835. jit_je(label_ok);
  836. jit_cmpi(R1,TAG_STR);
  837. jit_je(label_ok);
  838. // wrong type
  839. jit_jmp(label_skip);
  840. // good type
  841. jit_label(label_ok);
  842. load_cell(R0,argdefs[0], frame);
  843. #ifdef CHECK_BOUNDS
  844. // bounds check -----
  845. jit_movr(R1,R0);
  846. jit_addi(R1,PTRSZ);
  847. jit_ldr(R1);
  848. jit_cmpr(R2,R1);
  849. jit_jge(label_skip);
  850. // -------------------
  851. #endif
  852. jit_movr(R1,R0);
  853. jit_ldr(R1); // string address
  854. jit_addr(R1,R2);
  855. jit_ldrb(R1); // data in r3
  856. jit_label(label_skip);
  857. jit_movr(ARGR0, R3);
  858. if (return_type == TAG_ANY) jit_call(alloc_int, "alloc_int");
  859. else compiled_type = TAG_INT;
  860. break;
  861. }
  862. case BUILTIN_PUT: {
  863. char label_skip[64];
  864. sprintf(label_skip,"skip_%d",++label_skip_count);
  865. load_int(R3,argdefs[2], frame); // byte to store -> R3
  866. load_int(R2,argdefs[1], frame); // offset -> R2
  867. load_cell(R0,argdefs[0], frame);
  868. #ifdef CHECK_BOUNDS
  869. // bounds check -----
  870. jit_movr(R1,R0);
  871. jit_addi(R1,PTRSZ);
  872. jit_ldr(R1);
  873. jit_cmpr(R2,R1);
  874. jit_jge(label_skip);
  875. // -------------------
  876. #endif
  877. jit_movr(R1,R0);
  878. jit_ldr(R1); // string address
  879. jit_addr(R1,R2);
  880. jit_strb(R1); // address is in r1, data in r3
  881. jit_label(label_skip);
  882. break;
  883. }
  884. case BUILTIN_GET32: {
  885. load_cell(R3,argdefs[0], frame);
  886. load_int(R2,argdefs[1], frame); // offset -> R2
  887. jit_ldr(R3); // string address
  888. jit_addr(R3,R2);
  889. jit_ldrw(R3); // load to r3
  890. jit_movr(ARGR0, R3); // FIXME
  891. jit_call(alloc_int,"alloc_int");
  892. break;
  893. }
  894. case BUILTIN_PUT32: {
  895. char label_skip[64];
  896. sprintf(label_skip,"skip_%d",++label_skip_count);
  897. load_int(R3,argdefs[2], frame); // word to store -> R3
  898. load_int(R2,argdefs[1], frame); // offset -> R2
  899. load_cell(R1,argdefs[0], frame);
  900. #ifdef CHECK_BOUNDS
  901. // bounds check -----
  902. jit_movr(R1,R0);
  903. jit_addi(R1,PTRSZ);
  904. jit_ldr(R1);
  905. jit_cmpr(R2,R1);
  906. jit_jge(label_skip);
  907. // -------------------
  908. #endif
  909. // TODO: 32-bit align
  910. jit_movr(R1,R0);
  911. jit_ldr(R1); // string address
  912. jit_addr(R1,R2);
  913. jit_strw(R1); // store from r3
  914. jit_label(label_skip);
  915. jit_movr(R0,R1);
  916. jit_call(alloc_int,"debug");
  917. break;
  918. }
  919. case BUILTIN_MMAP: {
  920. load_cell(ARGR0,argdefs[0], frame);
  921. jit_call(fs_mmap,"fs_mmap");
  922. break;
  923. }
  924. case BUILTIN_ALLOC: {
  925. load_int(ARGR0,argdefs[0], frame);
  926. jit_call(alloc_num_bytes,"alloc_bytes");
  927. break;
  928. }
  929. case BUILTIN_ALLOC_STR: {
  930. load_int(ARGR0,argdefs[0], frame);
  931. jit_call(alloc_num_string,"alloc_string");
  932. break;
  933. }
  934. case BUILTIN_BYTES_TO_STR: {
  935. load_cell(ARGR0,argdefs[0], frame);
  936. jit_call(alloc_string_from_bytes,"alloc_string_to_bytes");
  937. break;
  938. }
  939. case BUILTIN_WRITE: {
  940. load_cell(ARGR0,argdefs[0], frame);
  941. load_cell(ARGR1,argdefs[1], frame);
  942. jit_call2(lisp_write_to_cell,"lisp_write_to_cell");
  943. break;
  944. }
  945. case BUILTIN_READ: {
  946. load_cell(ARGR0,argdefs[0], frame);
  947. jit_call(read_string_cell,"read_string_cell");
  948. break;
  949. }
  950. case BUILTIN_EVAL: {
  951. load_cell(ARGR0,argdefs[0], frame);
  952. jit_call(platform_eval,"platform_eval");
  953. break;
  954. }
  955. case BUILTIN_SIZE: {
  956. load_cell(ARGR0,argdefs[0], frame);
  957. jit_addi(ARGR0,PTRSZ); // fetch size -> R0
  958. jit_ldr(ARGR0);
  959. if (return_type == TAG_ANY) {
  960. jit_call(alloc_int, "alloc_int");
  961. } else if (return_type == TAG_INT) {
  962. jit_movr(R0,ARGR0);
  963. compiled_type = TAG_INT;
  964. }
  965. break;
  966. }
  967. case BUILTIN_GC: {
  968. push_frame_regs(frame->f);
  969. jit_lea(ARGR0,global_env);
  970. jit_movi(ARGR1,(jit_word_t)frame->stack_end);
  971. jit_movr(ARGR2,RSP);
  972. jit_call3(collect_garbage,"collect_garbage");
  973. pop_frame_regs(frame->f);
  974. break;
  975. }
  976. case BUILTIN_SYMBOLS: {
  977. jit_lea(ARGR0,global_env);
  978. jit_call(list_symbols,"list_symbols");
  979. break;
  980. }
  981. case BUILTIN_DEBUG: {
  982. //jit_call(platform_debug,"platform_debug");
  983. break;
  984. }
  985. case BUILTIN_PRINT: {
  986. load_cell(ARGR0,argdefs[0], frame);
  987. push_frame_regs(frame->f);
  988. jit_call(lisp_print,"lisp_print");
  989. pop_frame_regs(frame->f);
  990. break;
  991. }
  992. case BUILTIN_MOUNT: {
  993. load_cell(ARGR0,argdefs[0], frame);
  994. load_cell(ARGR1,argdefs[1], frame);
  995. jit_call2(fs_mount,"fs_mount");
  996. break;
  997. }
  998. case BUILTIN_OPEN: {
  999. load_cell(ARGR0,argdefs[0], frame);
  1000. push_frame_regs(frame->f);
  1001. jit_call(fs_open,"fs_open");
  1002. pop_frame_regs(frame->f);
  1003. break;
  1004. }
  1005. case BUILTIN_RECV: {
  1006. load_cell(ARGR0,argdefs[0], frame);
  1007. push_frame_regs(frame->f);
  1008. jit_call(stream_read,"stream_read");
  1009. pop_frame_regs(frame->f);
  1010. break;
  1011. }
  1012. case BUILTIN_SEND: {
  1013. load_cell(ARGR0,argdefs[0], frame);
  1014. load_cell(ARGR1,argdefs[1], frame);
  1015. // FIXME clobbers stuff
  1016. push_frame_regs(frame->f);
  1017. jit_call2(stream_write,"stream_write");
  1018. pop_frame_regs(frame->f);
  1019. break;
  1020. }
  1021. }
  1022. } else {
  1023. // λλλ lambda call λλλ
  1024. // save our args
  1025. int pushed = push_frame_regs(frame->f);
  1026. frame->sp+=pushed;
  1027. /*Cell* dbg1 = alloc_string_copy("---- debug stack save ----");
  1028. Cell* dbg2 = alloc_string_copy("---- end debug stack ----");
  1029. push_frame_regs(frame->f);
  1030. jit_lea(ARGR0,dbg1);
  1031. jit_call(lisp_print,"debug stack");
  1032. for (int i=0; i<pushed; i++) {
  1033. jit_ldr_stack(ARGR0, i*PTRSZ);
  1034. jit_call(lisp_print,"debug stack");
  1035. }
  1036. jit_lea(ARGR0,dbg2);
  1037. jit_call(lisp_print,"debug stack");
  1038. pop_frame_regs(frame->f);*/
  1039. /*if (argi>1) {
  1040. jit_push(LBDREG, LBDREG+argi-2);
  1041. frame->sp+=(1+argi-2);
  1042. }*/
  1043. int spo_adjust = 0;
  1044. for (int j=0; j<argi-1; j++) {
  1045. if (j>=ARG_SPILLOVER) {
  1046. // pass arg on stack
  1047. load_cell(R0, argdefs[j], frame);
  1048. jit_push(R0,R0);
  1049. spo_adjust++;
  1050. frame->sp++;
  1051. } else {
  1052. // pass arg in reg (LBDREG + slot)
  1053. if (argdefs[j].type == ARGT_REG) {
  1054. if (argdefs[j].slot<j) {
  1055. // register already clobbered, load from stack
  1056. printf("-- loading clobbered reg %d from stack to reg %d\n",argdefs[j].slot,LBDREG+j);
  1057. jit_ldr_stack(LBDREG+j, (pushed-1-argdefs[j].slot)*PTRSZ);
  1058. } else {
  1059. // no need to move a reg into itself
  1060. if (argdefs[j].slot!=j) {
  1061. load_cell(LBDREG+j, argdefs[j], frame);
  1062. }
  1063. }
  1064. }
  1065. else {
  1066. load_cell(LBDREG+j, argdefs[j], frame);
  1067. }
  1068. }
  1069. }
  1070. jit_lea(R0,op_env);
  1071. jit_ldr(R0); // load cell
  1072. jit_addi(R0,PTRSZ); // &cell->next
  1073. jit_ldr(R0); // cell->next
  1074. jit_callr(R0);
  1075. if (spo_adjust) {
  1076. jit_inc_stack(spo_adjust*PTRSZ);
  1077. frame->sp-=spo_adjust;
  1078. }
  1079. pop_frame_regs(frame->f);
  1080. frame->sp-=pushed;
  1081. /*if (argi>1) {
  1082. jit_pop(LBDREG, LBDREG+argi-2);
  1083. frame->sp-=(1+argi-2);
  1084. }*/
  1085. }
  1086. #ifdef CPU_X64
  1087. fflush(jit_out);
  1088. #endif
  1089. // at this point, registers R1-R6 are filled, execute
  1090. return compiled_type;
  1091. }
  1092. env_t* get_global_env() {
  1093. return global_env;
  1094. }
  1095. void init_compiler() {
  1096. //memdump(0x6f460,0x200,0);
  1097. //uart_getc();
  1098. //printf("malloc test: %p\r\n",malloc(1024));
  1099. printf("[compiler] creating global env hash table…\r\n");
  1100. global_env = sm_new(1000);
  1101. printf("[compiler] init_allocator…\r\n");
  1102. init_allocator();
  1103. reusable_nil = alloc_nil();
  1104. reusable_type_error = alloc_error(ERR_INVALID_PARAM_TYPE);
  1105. consed_type_error = alloc_cons(reusable_type_error,reusable_nil);
  1106. insert_symbol(alloc_sym("nil"), reusable_nil, &global_env);
  1107. insert_symbol(alloc_sym("type_error"), consed_type_error, &global_env);
  1108. printf("[compiler] inserting symbols…\r\n");
  1109. insert_symbol(alloc_sym("def"), alloc_builtin(BUILTIN_DEF, alloc_list((Cell*[]){alloc_int(TAG_SYM), alloc_int(TAG_ANY)}, 2)), &global_env);
  1110. insert_symbol(alloc_sym("let"), alloc_builtin(BUILTIN_LET, alloc_list((Cell*[]){alloc_int(TAG_SYM), alloc_int(TAG_ANY)}, 2)), &global_env);
  1111. insert_symbol(alloc_sym("+"), alloc_builtin(BUILTIN_ADD, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1112. insert_symbol(alloc_sym("-"), alloc_builtin(BUILTIN_SUB, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1113. insert_symbol(alloc_sym("*"), alloc_builtin(BUILTIN_MUL, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1114. insert_symbol(alloc_sym("/"), alloc_builtin(BUILTIN_DIV, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1115. insert_symbol(alloc_sym("%"), alloc_builtin(BUILTIN_MOD, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1116. insert_symbol(alloc_sym("bitand"), alloc_builtin(BUILTIN_BITAND, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1117. insert_symbol(alloc_sym("bitor"), alloc_builtin(BUILTIN_BITOR, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1118. insert_symbol(alloc_sym("bitxor"), alloc_builtin(BUILTIN_BITOR, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1119. insert_symbol(alloc_sym("shl"), alloc_builtin(BUILTIN_SHL, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1120. insert_symbol(alloc_sym("shr"), alloc_builtin(BUILTIN_SHR, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1121. printf("[compiler] arithmetic…\r\n");
  1122. insert_symbol(alloc_sym("lt"), alloc_builtin(BUILTIN_LT, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1123. insert_symbol(alloc_sym("gt"), alloc_builtin(BUILTIN_GT, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_INT)}, 2)), &global_env);
  1124. printf("[compiler] compare…\r\n");
  1125. insert_symbol(alloc_sym("if"), alloc_builtin(BUILTIN_IF, alloc_list((Cell*[]){alloc_int(TAG_INT), alloc_int(TAG_LAMBDA), alloc_int(TAG_LAMBDA)}, 3)), &global_env);
  1126. insert_symbol(alloc_sym("fn"), alloc_builtin(BUILTIN_FN, NULL), &global_env);
  1127. insert_symbol(alloc_sym("while"), alloc_builtin(BUILTIN_WHILE, NULL), &global_env);
  1128. insert_symbol(alloc_sym("print"), alloc_builtin(BUILTIN_PRINT, alloc_list((Cell*[]){alloc_int(TAG_ANY)}, 1)), &global_env);
  1129. insert_symbol(alloc_sym("do"), alloc_builtin(BUILTIN_DO, NULL), &global_env);
  1130. printf("[compiler] flow…\r\n");
  1131. insert_symbol(alloc_sym("car"), alloc_builtin(BUILTIN_CAR, alloc_list((Cell*[]){alloc_int(TAG_CONS)}, 1)), &global_env);
  1132. insert_symbol(alloc_sym("cdr"), alloc_builtin(BUILTIN_CDR, alloc_list((Cell*[]){alloc_int(TAG_CONS)}, 1)), &global_env);
  1133. insert_symbol(alloc_sym("cons"), alloc_builtin(BUILTIN_CONS, alloc_list((Cell*[]){alloc_int(TAG_ANY), alloc_int(TAG_ANY)}, 2)), &global_env);
  1134. insert_symbol(alloc_sym("list"), alloc_builtin(BUILTIN_LIST, NULL), &global_env);
  1135. insert_symbol(alloc_sym("quote"), alloc_builtin(BUILTIN_QUOTE, NULL), &global_env);
  1136. //insert_symbol(alloc_sym("map"), alloc_builtin(BUILTIN_MAP), &global_env);
  1137. printf("[compiler] lists…\r\n");
  1138. insert_symbol(alloc_sym("concat"), alloc_builtin(BUILTIN_CONCAT, alloc_list((Cell*[]){alloc_int(TAG_STR), alloc_int(TAG_STR)}, 2)), &global_env);
  1139. insert_symbol(alloc_sym("substr"), alloc_builtin(BUILTIN_SUBSTR, alloc_list((Cell*[]){alloc_int(TAG_STR), alloc_int(TAG_INT), alloc_int(TAG_INT)}, 3)), &global_env);
  1140. insert_symbol(alloc_sym("get"), alloc_builtin(BUILTIN_GET, alloc_list((Cell*[]){alloc_int(TAG_STR), alloc_int(TAG_INT)}, 2)), &global_env);
  1141. insert_symbol(alloc_sym("put"), alloc_builtin(BUILTIN_PUT, alloc_list((Cell*[]){alloc_int(TAG_STR), alloc_int(TAG_INT), alloc_int(TAG_INT)}, 3)), &global_env);
  1142. insert_symbol(alloc_sym("get32"), alloc_builtin(BUILTIN_GET32, alloc_list((Cell*[]){alloc_int(TAG_BYTES), alloc_int(TAG_INT)}, 2)), &global_env);
  1143. insert_symbol(alloc_sym("put32"), alloc_builtin(BUILTIN_PUT32, alloc_list((Cell*[]){alloc_int(TAG_BYTES), alloc_int(TAG_INT), alloc_int(TAG_INT)}, 3)), &global_env);
  1144. insert_symbol(alloc_sym("size"), alloc_builtin(BUILTIN_SIZE, alloc_list((Cell*[]){alloc_int(TAG_STR)}, 1)), &global_env);
  1145. insert_symbol(alloc_sym("alloc"), alloc_builtin(BUILTIN_ALLOC, alloc_list((Cell*[]){alloc_int(TAG_INT)}, 1)), &global_env);
  1146. insert_symbol(alloc_sym("alloc-str"), alloc_builtin(BUILTIN_ALLOC_STR, alloc_list((Cell*[]){alloc_int(TAG_INT)}, 1)), &global_env);
  1147. insert_symbol(alloc_sym("bytes->str"), alloc_builtin(BUILTIN_BYTES_TO_STR, alloc_list((Cell*[]){alloc_int(TAG_ANY)}, 1)), &global_env);
  1148. printf("[compiler] strings…\r\n");
  1149. /*insert_symbol(alloc_sym("uget"), alloc_builtin(BUILTIN_UGET), &global_env);
  1150. insert_symbol(alloc_sym("uput"), alloc_builtin(BUILTIN_UPUT), &global_env);
  1151. insert_symbol(alloc_sym("usize"), alloc_builtin(BUILTIN_USIZE), &global_env);
  1152. printf("[compiler] get/put…\r\n");*/
  1153. insert_symbol(alloc_sym("write"), alloc_builtin(BUILTIN_WRITE, alloc_list((Cell*[]){alloc_int(TAG_ANY), alloc_int(TAG_STR)},2)), &global_env);
  1154. insert_symbol(alloc_sym("read"), alloc_builtin(BUILTIN_READ, alloc_list((Cell*[]){alloc_int(TAG_STR)},1)), &global_env);
  1155. insert_symbol(alloc_sym("eval"), alloc_builtin(BUILTIN_EVAL, alloc_list((Cell*[]){alloc_int(TAG_ANY)},1)), &global_env);
  1156. insert_symbol(alloc_sym("mount"), alloc_builtin(BUILTIN_MOUNT, alloc_list((Cell*[]){alloc_int(TAG_STR), alloc_int(TAG_CONS)},2)), &global_env);
  1157. insert_symbol(alloc_sym("open"), alloc_builtin(BUILTIN_OPEN, alloc_list((Cell*[]){alloc_int(TAG_STR)},1)), &global_env);
  1158. insert_symbol(alloc_sym("mmap"), alloc_builtin(BUILTIN_MMAP, alloc_list((Cell*[]){alloc_int(TAG_STR)},1)), &global_env);
  1159. insert_symbol(alloc_sym("recv"), alloc_builtin(BUILTIN_RECV, alloc_list((Cell*[]){alloc_int(TAG_STREAM)},1)), &global_env);
  1160. insert_symbol(alloc_sym("send"), alloc_builtin(BUILTIN_SEND, alloc_list((Cell*[]){alloc_int(TAG_STREAM),alloc_int(TAG_ANY)},2)), &global_env);
  1161. printf("[compiler] write/eval…\r\n");
  1162. insert_symbol(alloc_sym("gc"), alloc_builtin(BUILTIN_GC, NULL), &global_env);
  1163. insert_symbol(alloc_sym("symbols"), alloc_builtin(BUILTIN_SYMBOLS, NULL), &global_env);
  1164. insert_symbol(alloc_sym("debug"), alloc_builtin(BUILTIN_DEBUG, NULL), &global_env);
  1165. int num_syms = sm_get_count(global_env);
  1166. printf("sledge knows %u symbols. enter (symbols) to see them.\r\n", num_syms);
  1167. }