compiler_new.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911
  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. #ifdef CPU_X86
  12. #define ARG_SPILLOVER 0
  13. #else
  14. #define ARG_SPILLOVER 3 // max 4 args via regs, rest via stack
  15. #endif
  16. #define LBDREG R4 // register base used for passing args to functions
  17. #define DEBUG_ASM_SRC
  18. static int debug_mode = 0;
  19. env_entry* lookup_global_symbol(char* name) {
  20. env_entry* res;
  21. int found = sm_get(global_env, name, (void**)&res);
  22. //printf("[lookup] %s res: %p\n",name,res);
  23. if (!found) return NULL;
  24. return res;
  25. }
  26. Cell* insert_symbol(Cell* symbol, Cell* cell, env_t** env) {
  27. env_entry* e;
  28. int found = sm_get(*env, symbol->ar.addr, (void**)&e);
  29. if (found) {
  30. e->cell = cell;
  31. //printf("[insert_symbol] update %s entry at %p (cell: %p value: %d)\r\n",symbol->ar.addr,e,e->cell,e->cell->ar.value);
  32. return e->cell;
  33. }
  34. e = malloc(sizeof(env_entry));
  35. int ret = snprintf(e->name, MAX_SYMBOL_SIZE, "%s", (char*)symbol->ar.addr);
  36. if (ret >= MAX_SYMBOL_SIZE) {
  37. printf("[insert_symbol] max symbol size exceeded by %d\n", ret - MAX_SYMBOL_SIZE + 1);
  38. free(e);
  39. return alloc_nil();
  40. }
  41. e->cell = cell;
  42. //printf("[insert_symbol] %s entry at %p (cell: %p)\r\n",symbol->ar.addr,e,e->cell);
  43. sm_put(*env, e->name, e);
  44. return e->cell;
  45. }
  46. Cell* insert_global_symbol(Cell* symbol, Cell* cell) {
  47. return insert_symbol(symbol, cell, &global_env);
  48. }
  49. #define TMP_PRINT_BUFSZ 1024
  50. static FILE* jit_out;
  51. static Cell* cell_heap_start;
  52. static int label_skip_count = 0;
  53. static char temp_print_buffer[TMP_PRINT_BUFSZ];
  54. static Cell* consed_type_error;
  55. static Cell* prototype_type_error;
  56. static Cell* prototype_nil;
  57. static Cell* prototype_int;
  58. static Cell* prototype_any;
  59. static Cell* prototype_void;
  60. static Cell* prototype_struct;
  61. static Cell* prototype_struct_def;
  62. static Cell* prototype_stream;
  63. static Cell* prototype_string;
  64. static Cell* prototype_symbol;
  65. static Cell* prototype_lambda;
  66. static Cell* prototype_cons;
  67. #ifdef CPU_ARM
  68. #include "jit_arm_raw.c"
  69. #define PTRSZ 4
  70. #endif
  71. #ifdef CPU_X64
  72. #include "jit_x64.c"
  73. #define PTRSZ 8
  74. #endif
  75. #ifdef CPU_X86
  76. #include "jit_x86.c"
  77. #define PTRSZ 4
  78. #endif
  79. #ifdef __AMIGA
  80. #include "jit_m68k.c"
  81. #define PTRSZ 4
  82. #endif
  83. void debug_break(Cell* arg) {
  84. printf("argr0: %p\r\n",arg);
  85. exit(0);
  86. }
  87. Cell* lisp_print(Cell* arg) {
  88. lisp_write(arg, temp_print_buffer, TMP_PRINT_BUFSZ);
  89. printf("%s\r\n",temp_print_buffer);
  90. return arg;
  91. }
  92. void load_int(int dreg, Arg arg, Frame* f) {
  93. if (arg.type == ARGT_CONST) {
  94. // argument is a constant like 123, "foo"
  95. jit_movi(dreg, (jit_word_t)arg.cell->ar.value);
  96. }
  97. else if (arg.type == ARGT_ENV) {
  98. // argument is an environment table entry, load e->cell->ar.value
  99. jit_lea(dreg, arg.env);
  100. jit_ldr(dreg);
  101. jit_ldr(dreg);
  102. }
  103. else if (arg.type == ARGT_REG) {
  104. // argument comes from a register
  105. jit_movr(dreg, arg.slot);
  106. jit_ldr(dreg);
  107. }
  108. else if (arg.type == ARGT_REG_INT) {
  109. if (dreg!=arg.slot) {
  110. jit_movr(dreg, arg.slot);
  111. }
  112. }
  113. else if (arg.type == ARGT_STACK) {
  114. //printf("loading int from stack slot %d + sp %d to reg %d\n",arg.slot,f->sp,dreg);
  115. jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
  116. jit_ldr(dreg);
  117. }
  118. else if (arg.type == ARGT_STACK_INT) {
  119. //printf("loading int from stack_int sp %d - slot %d to reg %d\n",f->sp,arg.slot,dreg);
  120. jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
  121. }
  122. else {
  123. jit_movi(dreg, 0xdeadbeef);
  124. }
  125. }
  126. void load_cell(int dreg, Arg arg, Frame* f) {
  127. if (arg.type == ARGT_CONST) {
  128. // argument is a constant like 123, "foo"
  129. jit_movi(dreg, (jit_word_t)arg.cell);
  130. }
  131. else if (arg.type == ARGT_ENV) {
  132. jit_lea(dreg, arg.env);
  133. jit_ldr(dreg);
  134. }
  135. else if (arg.type == ARGT_REG) {
  136. jit_movr(dreg, arg.slot);
  137. }
  138. else if (arg.type == ARGT_REG_INT) {
  139. jit_call(alloc_int, "alloc_int");
  140. jit_movr(dreg,R0);
  141. }
  142. else if (arg.type == ARGT_STACK) {
  143. //printf("loading cell from stack slot %d + sp %d to reg %d\n",arg.slot,f->sp,dreg);
  144. jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
  145. }
  146. else if (arg.type == ARGT_STACK_INT) {
  147. int adjust = 0;
  148. //printf("loading cell from stack_int sp %d - slot %d + adjust %d = %d to reg %d\n",f->sp,arg.slot,adjust,f->sp-arg.slot+adjust,dreg);
  149. if (dreg!=ARGR0) {jit_push(ARGR0,ARGR0); adjust++;}
  150. if (dreg!=R0) {jit_push(R0,R0); adjust++;}
  151. jit_ldr_stack(ARGR0, PTRSZ*(f->sp-arg.slot+adjust));
  152. jit_call(alloc_int, "alloc_int");
  153. jit_movr(dreg,R0);
  154. if (dreg!=R0) jit_pop(R0,R0);
  155. if (dreg!=ARGR0) jit_pop(ARGR0,ARGR0);
  156. }
  157. else {
  158. printf("<load_cell unhandled arg.type: %d>\r\n",arg.type);
  159. jit_movi(dreg, 0xdeadcafe);
  160. }
  161. }
  162. int get_sym_frame_idx(char* argname, Arg* fn_frame, int ignore_regs) {
  163. int i;
  164. if (!fn_frame) return -1;
  165. for (i=0; i<MAXFRAME; i++) {
  166. if (fn_frame[i].name) {
  167. //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);
  168. if (!((fn_frame[i].type == ARGT_REG) && ignore_regs)) {
  169. if (!strcmp(argname, fn_frame[i].name)) {
  170. //printf("!! get_sym_frame_idx %i (type %d): %s\n",i,fn_frame[i].type,fn_frame[i].name);
  171. //printf("returning %d\n",i);
  172. return i;
  173. }
  174. }
  175. }
  176. }
  177. return -1;
  178. }
  179. // TODO: optimize!
  180. int push_frame_regs(Arg* fn_frame) {
  181. int pushreg=0;
  182. int i;
  183. if (!fn_frame) return 0;
  184. for (i=0; i<MAXFRAME; i++) {
  185. if (fn_frame[i].type == ARGT_REG) {
  186. pushreg++;
  187. }
  188. }
  189. //printf("pushing %d frame regs\n",pushreg);
  190. if (pushreg) {
  191. jit_push(LBDREG,LBDREG+pushreg-1);
  192. }
  193. return pushreg;
  194. }
  195. int pop_frame_regs(Arg* fn_frame) {
  196. int pushreg=0;
  197. int i;
  198. if (!fn_frame) return 0;
  199. for (i=0; i<MAXFRAME; i++) {
  200. if (fn_frame[i].type == ARGT_REG) {
  201. pushreg++;
  202. }
  203. }
  204. //printf("popping %d frame regs\n",pushreg);
  205. if (pushreg) {
  206. jit_pop(LBDREG,LBDREG+pushreg-1);
  207. }
  208. return pushreg;
  209. }
  210. static char* analyze_buffer[MAXFRAME];
  211. int analyze_fn(Cell* expr, Cell* parent, int num_lets) {
  212. if (expr->tag == TAG_SYM) {
  213. env_entry* op_env = lookup_global_symbol(expr->ar.addr);
  214. if (op_env) {
  215. Cell* op = op_env->cell;
  216. if (op->tag == TAG_BUILTIN) {
  217. //printf("analyze_fn: found builtin: %s\n",expr->ar.addr);
  218. if (op->ar.value == BUILTIN_LET) {
  219. Cell* sym = car(cdr(parent));
  220. if (sym) {
  221. int existing = 0, i;
  222. for (i=0; i<num_lets; i++) {
  223. if (!strcmp(analyze_buffer[i], sym->ar.addr)) {
  224. //printf("-- we already know local %s\r\n",sym->ar.addr);
  225. existing = 1;
  226. break;
  227. }
  228. }
  229. if (!existing) {
  230. analyze_buffer[num_lets] = sym->ar.addr;
  231. num_lets++;
  232. }
  233. } else {
  234. printf("<analyze_fn error: malformed let!>\r\n");
  235. }
  236. }
  237. }
  238. }
  239. }
  240. else if (expr->tag == TAG_CONS) {
  241. if (car(expr)) {
  242. num_lets = analyze_fn(car(expr), expr, num_lets);
  243. }
  244. if (cdr(expr)) {
  245. num_lets = analyze_fn(cdr(expr), expr, num_lets);
  246. }
  247. }
  248. return num_lets;
  249. }
  250. int compatible_type(int given, int required) {
  251. if (given == required) return 1;
  252. if ((given == TAG_STR || given == TAG_BYTES) &&
  253. (required == TAG_STR || required == TAG_BYTES)) return 1;
  254. return 0;
  255. }
  256. Cell* clean_return(int args_pushed, Frame* frame, Cell* compiled_type) {
  257. if (args_pushed) {
  258. jit_inc_stack(args_pushed*PTRSZ);
  259. frame->sp-=args_pushed;
  260. }
  261. return compiled_type;
  262. }
  263. // returns a prototype cell that can be used for type information
  264. Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
  265. Cell* compiled_type = prototype_any;
  266. Arg* fn_frame = frame->f;
  267. Cell* opsym, *args, *orig_args, *signature_args, *op, *orig_op=NULL;
  268. env_entry* op_env;
  269. char* op_name;
  270. int is_let = 0;
  271. int argi = 0;
  272. int args_pushed = 0;
  273. Arg argdefs[MAXARGS];
  274. if (!expr) return 0;
  275. if (!frame) return 0;
  276. if (expr->tag != TAG_CONS) {
  277. if (expr->tag == TAG_SYM) {
  278. int arg_frame_idx = get_sym_frame_idx(expr->ar.addr, fn_frame, 0);
  279. env_entry* env;
  280. if (arg_frame_idx>=0) {
  281. load_cell(R0, fn_frame[arg_frame_idx], frame);
  282. return compiled_type;
  283. }
  284. env = lookup_global_symbol(expr->ar.addr);
  285. if (env) {
  286. Cell* value = env->cell;
  287. jit_movi(R0,(jit_word_t)env);
  288. jit_ldr(R0);
  289. return value; // FIXME TODO forbid later type change
  290. } else {
  291. printf("<undefined symbol %s>\r\n",(char*)expr->ar.addr);
  292. jit_movi(R0,0);
  293. return 0;
  294. }
  295. } else {
  296. // return the expr
  297. jit_movi(R0,(jit_word_t)expr);
  298. return compiled_type;
  299. }
  300. return 0;
  301. }
  302. cell_heap_start = get_cell_heap();
  303. opsym = car(expr);
  304. args = cdr(expr);
  305. orig_args = args; // keep around for specials forms like DO
  306. signature_args = NULL;
  307. if (!opsym || opsym->tag != TAG_SYM) {
  308. printf("<error: non-symbol in operator position>\r\n");
  309. return 0;
  310. }
  311. op_name = (char*)opsym->ar.addr;
  312. op_env = lookup_global_symbol(op_name);
  313. if (!op_env || !op_env->cell) {
  314. printf("<error: undefined symbol %s in operator position>\r\n",op_name);
  315. return 0;
  316. }
  317. op = op_env->cell;
  318. //printf("op tag: %d\n",op->tag);
  319. if (op->tag == TAG_BUILTIN) {
  320. signature_args = op->dr.next;
  321. if (op->ar.value == BUILTIN_LET) {
  322. is_let = 1;
  323. }
  324. }
  325. else if (op->tag == TAG_LAMBDA) {
  326. signature_args = car((Cell*)(op->ar.addr));
  327. }
  328. else if (op->tag == TAG_STRUCT_DEF) {
  329. signature_args = NULL;
  330. orig_op = op;
  331. op_env = lookup_global_symbol("new");
  332. op = op_env->cell;
  333. }
  334. else {
  335. printf("<error: non-lambda/struct symbol %s in operator position>\r\n",(char*)opsym->ar.addr);
  336. return 0;
  337. }
  338. //printf("[op] %s\n",debug_buf);
  339. //lisp_write(signature_args, debug_buf, sizeof(debug_buf));
  340. //printf("[sig] %s\n",debug_buf);
  341. #ifdef DEBUG_ASM_SRC
  342. char* debug_buf = malloc(256);
  343. lisp_write(expr, debug_buf, 255);
  344. jit_comment(debug_buf);
  345. free(debug_buf);
  346. #endif
  347. if (debug_mode) {
  348. char* debug_buf = malloc(256);
  349. push_frame_regs(frame->f);
  350. lisp_write(expr, debug_buf, 256);
  351. jit_push(R0, ARGR1);
  352. jit_lea(ARGR0, debug_buf);
  353. jit_lea(ARGR1, frame);
  354. jit_call(debug_handler,"dbg");
  355. jit_pop(R0, ARGR1);
  356. pop_frame_regs(frame->f);
  357. }
  358. // first, we need a signature
  359. do {
  360. Cell* arg = car(args);
  361. Cell* signature_arg = car(signature_args);
  362. char arg_name[32];
  363. snprintf(arg_name,sizeof(arg_name),"a%d",argi+1);
  364. // 1. is the arg the required type? i.e. a pointer or a number?
  365. if (signature_arg && signature_arg->tag == TAG_CONS) {
  366. // named argument
  367. snprintf(arg_name,sizeof(arg_name),"%s",(char*)(car(signature_arg)->ar.addr));
  368. //printf("named arg: %s\r\n",arg_name);
  369. signature_arg = cdr(signature_arg);
  370. }
  371. /*if (signature_args) {
  372. char dbg[256];
  373. lisp_write(signature_args,dbg,256);
  374. printf("!! %s sig: %s\r\n",opsym->ar.addr,dbg);
  375. }*/
  376. if (arg && (!signature_args || signature_arg)) {
  377. int given_tag = arg->tag;
  378. int sig_tag = 0;
  379. if (signature_arg) sig_tag = signature_arg->tag;
  380. if (is_let && argi==1) {
  381. int type_hint = -1;
  382. // check the symbol to see if we already have type information
  383. int fidx = get_sym_frame_idx(argdefs[0].cell->ar.addr, fn_frame, 1);
  384. if (fidx>=0) {
  385. //printf("existing type information for %s: %d\r\n", argdefs[0].cell->ar.addr,fn_frame[fidx].type);
  386. type_hint = fn_frame[fidx].type;
  387. }
  388. if (given_tag == TAG_INT || type_hint == ARGT_STACK_INT) {
  389. //printf("INT mode of let\r\n");
  390. // let prefers raw integers!
  391. sig_tag = TAG_INT;
  392. signature_arg = prototype_int;
  393. } else {
  394. //printf("ANY mode of let\r\n");
  395. // but cells are ok, too
  396. sig_tag = TAG_ANY;
  397. signature_arg = prototype_any;
  398. }
  399. }
  400. if (!signature_args) {
  401. // any number of arguments allowed
  402. argdefs[argi].cell = arg;
  403. argdefs[argi].type = ARGT_STACK;
  404. }
  405. else if (sig_tag == TAG_LAMBDA) {
  406. // lazy evaluation by form
  407. argdefs[argi].cell = arg;
  408. argdefs[argi].type = ARGT_LAMBDA;
  409. }
  410. else if (arg->tag == TAG_CONS) {
  411. // eager evaluation
  412. // nested expression
  413. Cell* cons_type = compile_expr(arg, frame, signature_arg);
  414. if (!cons_type) return NULL; // failure
  415. given_tag = cons_type->tag;
  416. argdefs[argi].cell = NULL; // cell is in R0 at runtime
  417. argdefs[argi].slot = ++frame->sp; // record sp at this point
  418. if (given_tag == TAG_INT) {
  419. argdefs[argi].type = ARGT_STACK_INT;
  420. } else {
  421. argdefs[argi].type = ARGT_STACK;
  422. }
  423. if (given_tag == TAG_STRUCT) {
  424. // struct extraction
  425. Cell** fields = cons_type->ar.addr;
  426. Cell** def_fields = fields[0]->ar.addr;
  427. argdefs[argi].type_name = def_fields[0]->ar.addr;
  428. //printf("!!! nested struct name extracted: %s (arg# %d argt %d) !!!\r\n",argdefs[argi].type_name,argi,argdefs[argi].type);
  429. }
  430. jit_push(R0,R0);
  431. args_pushed++;
  432. }
  433. else if (given_tag == TAG_SYM && sig_tag != TAG_SYM) {
  434. // symbol given, lookup (indirect)
  435. //printf("indirect symbol lookup (name: %p)\n",arg->ar.value);
  436. int arg_frame_idx = get_sym_frame_idx(arg->ar.addr, fn_frame, 0);
  437. // argument passed to function in register
  438. if (arg_frame_idx>=0) {
  439. argdefs[argi] = fn_frame[arg_frame_idx];
  440. //printf("argument %s from stack frame.\n", arg->ar.addr);
  441. //printf("-> cell %p slot %d type %d\n", fn_frame[arg_frame_idx].cell, fn_frame[arg_frame_idx].slot, fn_frame[arg_frame_idx].type);
  442. } else {
  443. argdefs[argi].env = lookup_global_symbol((char*)arg->ar.addr);
  444. argdefs[argi].type = ARGT_ENV;
  445. //printf("argument %i:%s from environment.\n", argi, arg->ar.addr);
  446. }
  447. //printf("arg_frame_idx: %d\n",arg_frame_idx);
  448. if (!argdefs[argi].env && arg_frame_idx<0) {
  449. printf("<undefined symbol %s given for argument %s of %s>\r\n",(char*)arg->ar.addr,arg_name,op_name);
  450. return 0;
  451. }
  452. }
  453. else if (compatible_type(given_tag, sig_tag) || sig_tag==TAG_ANY) {
  454. argdefs[argi].cell = arg;
  455. argdefs[argi].slot = argi-1;
  456. argdefs[argi].type = ARGT_CONST;
  457. if (given_tag == TAG_SYM || given_tag == TAG_CONS || given_tag == TAG_INT || given_tag == TAG_STR || given_tag == TAG_BYTES) {
  458. //argdefs[argi].type = ARGT_CONST;
  459. }
  460. //printf("const arg of type %d at %p\n",arg->tag,arg);
  461. } else {
  462. // check if we can typecast
  463. // else, fail with type error
  464. printf("<type mismatch for argument %s of %s (given %s, expected %s)>\r\n",arg_name,op_name,tag_to_str(given_tag),tag_to_str(sig_tag));
  465. return 0;
  466. }
  467. } else {
  468. if (!arg && signature_arg) {
  469. // missing arguments
  470. printf("<argument %s of %s missing!>\r\n",arg_name,op_name);
  471. return 0;
  472. } else if (arg && !signature_arg) {
  473. // surplus arguments
  474. printf("<surplus arguments to %s!>\r\n",op_name);
  475. return 0;
  476. }
  477. }
  478. argi++;
  479. } while (argi<MAXARGS && (args = cdr(args)) && (!signature_args || (signature_args = cdr(signature_args))));
  480. // args are prepared, execute op
  481. if (op->tag == TAG_BUILTIN) {
  482. switch (op->ar.value) {
  483. case BUILTIN_BITAND: {
  484. load_int(ARGR0,argdefs[0], frame);
  485. load_int(R2,argdefs[1], frame);
  486. jit_andr(ARGR0,R2);
  487. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  488. else {
  489. compiled_type = prototype_int;
  490. jit_movr(R0,ARGR0);
  491. }
  492. break;
  493. }
  494. case BUILTIN_BITNOT: {
  495. load_int(ARGR0,argdefs[0], frame);
  496. jit_notr(ARGR0);
  497. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  498. else {
  499. compiled_type = prototype_int;
  500. jit_movr(R0,ARGR0);
  501. }
  502. break;
  503. }
  504. case BUILTIN_BITOR: {
  505. load_int(ARGR0,argdefs[0], frame);
  506. load_int(R2,argdefs[1], frame);
  507. jit_orr(ARGR0,R2);
  508. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  509. else {
  510. compiled_type = prototype_int;
  511. jit_movr(R0,ARGR0);
  512. }
  513. break;
  514. }
  515. case BUILTIN_BITXOR: {
  516. load_int(ARGR0,argdefs[0], frame);
  517. load_int(R2,argdefs[1], frame);
  518. jit_xorr(ARGR0,R2);
  519. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  520. else {
  521. compiled_type = prototype_int;
  522. jit_movr(R0,ARGR0);
  523. }
  524. break;
  525. }
  526. case BUILTIN_SHL: {
  527. load_int(ARGR0,argdefs[0], frame);
  528. load_int(R2,argdefs[1], frame);
  529. jit_shlr(ARGR0,R2);
  530. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  531. else {
  532. compiled_type = prototype_int;
  533. jit_movr(R0,ARGR0);
  534. }
  535. break;
  536. }
  537. case BUILTIN_SHR: {
  538. load_int(ARGR0,argdefs[0], frame);
  539. load_int(R2,argdefs[1], frame);
  540. jit_shrr(ARGR0,R2);
  541. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  542. else {
  543. compiled_type = prototype_int;
  544. jit_movr(R0,ARGR0);
  545. }
  546. break;
  547. }
  548. case BUILTIN_ADD: {
  549. load_int(ARGR0,argdefs[0], frame);
  550. load_int(R2,argdefs[1], frame);
  551. jit_addr(ARGR0,R2);
  552. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  553. else {
  554. compiled_type = prototype_int;
  555. jit_movr(R0,ARGR0);
  556. }
  557. break;
  558. }
  559. case BUILTIN_SUB: {
  560. load_int(ARGR0,argdefs[0], frame);
  561. load_int(R2,argdefs[1], frame);
  562. jit_subr(ARGR0,R2);
  563. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  564. else {
  565. compiled_type = prototype_int;
  566. jit_movr(R0,ARGR0);
  567. }
  568. break;
  569. }
  570. case BUILTIN_MUL: {
  571. load_int(ARGR0,argdefs[0], frame);
  572. load_int(R2,argdefs[1], frame);
  573. jit_mulr(ARGR0,R2);
  574. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  575. else {
  576. compiled_type = prototype_int;
  577. jit_movr(R0,ARGR0);
  578. }
  579. break;
  580. }
  581. case BUILTIN_DIV: {
  582. load_int(ARGR0,argdefs[0], frame);
  583. load_int(R2,argdefs[1], frame);
  584. jit_divr(ARGR0,R2);
  585. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  586. else {
  587. compiled_type = prototype_int;
  588. jit_movr(R0,ARGR0);
  589. }
  590. break;
  591. }
  592. case BUILTIN_MOD: {
  593. load_int(ARGR0,argdefs[0], frame);
  594. load_int(R2,argdefs[1], frame);
  595. jit_modr(ARGR0,R2);
  596. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  597. else {
  598. compiled_type = prototype_int;
  599. jit_movr(R0,ARGR0);
  600. }
  601. break;
  602. }
  603. case BUILTIN_GT: {
  604. load_int(ARGR0,argdefs[0], frame);
  605. load_int(R2,argdefs[1], frame);
  606. jit_movi(R3,0);
  607. jit_subr(ARGR0,R2);
  608. jit_movneg(ARGR0,R3);
  609. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  610. else {
  611. compiled_type = prototype_int;
  612. jit_movr(R0,ARGR0);
  613. }
  614. break;
  615. }
  616. case BUILTIN_LT: {
  617. load_int(R2,argdefs[0], frame);
  618. load_int(ARGR0,argdefs[1], frame);
  619. jit_movi(R3,0);
  620. jit_subr(ARGR0,R2);
  621. jit_movneg(ARGR0,R3);
  622. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  623. else {
  624. compiled_type = prototype_int;
  625. jit_movr(R0,ARGR0);
  626. }
  627. break;
  628. }
  629. case BUILTIN_EQ: {
  630. load_int(R1, argdefs[0], frame);
  631. load_int(R2, argdefs[1], frame);
  632. jit_movi(R0,0);
  633. jit_movi(R3,1);
  634. jit_cmpr(R1,R2);
  635. jit_moveq(R0,R3);
  636. if (return_type->tag == TAG_ANY) {
  637. jit_movr(ARGR0,R0);
  638. jit_call(alloc_int, "alloc_int");
  639. }
  640. else {
  641. compiled_type = prototype_int;
  642. // int is in R0 already
  643. }
  644. break;
  645. }
  646. case BUILTIN_DEF: {
  647. // TODO in the future, we could pre-allocate symbols
  648. // and especially their types based on type inference
  649. jit_lea(ARGR0,argdefs[0].cell); // load symbol address
  650. load_cell(ARGR1,argdefs[1],frame);
  651. push_frame_regs(frame->f);
  652. jit_call2(insert_global_symbol, "insert_global_symbol");
  653. pop_frame_regs(frame->f);
  654. break;
  655. }
  656. case BUILTIN_LET: {
  657. int is_int, offset, fidx, is_reg;
  658. if (!frame->f) {
  659. printf("<error: let is not allowed on global level, only in fn>\r\n");
  660. return 0;
  661. }
  662. is_int = 0;
  663. is_reg = 0;
  664. offset = MAXARGS + frame->locals;
  665. fidx = get_sym_frame_idx(argdefs[0].cell->ar.addr, fn_frame, 0);
  666. if (fidx >= 0) {
  667. // existing stack entry
  668. offset = fidx;
  669. //printf("+~ frame entry %s, existing stack-local idx %d (type %d)\n",fn_frame[offset].name,fn_frame[offset].slot,fn_frame[offset].type);
  670. // is_int from existing entry
  671. if (fn_frame[offset].type == ARGT_REG_INT ||
  672. fn_frame[offset].type == ARGT_STACK_INT) {
  673. is_int = 1;
  674. }
  675. if (fn_frame[offset].type == ARGT_REG_INT ||
  676. fn_frame[offset].type == ARGT_REG) {
  677. is_reg = 1;
  678. }
  679. } else {
  680. if ((argdefs[1].type == ARGT_REG_INT ||
  681. argdefs[1].type == ARGT_STACK_INT ||
  682. (argdefs[1].type == ARGT_CONST && argdefs[1].cell->tag == TAG_INT)
  683. )) {
  684. is_int = 1;
  685. }
  686. // create new stack entry for this let
  687. fn_frame[offset].name = argdefs[0].cell->ar.addr;
  688. fn_frame[offset].type_name = argdefs[1].type_name; // copy inferred type
  689. fn_frame[offset].cell = NULL;
  690. if (is_int) {
  691. fn_frame[offset].type = ARGT_STACK_INT;
  692. //printf("new let %s inferred INT\n",argdefs[0].cell->ar.addr);
  693. } else {
  694. fn_frame[offset].type = ARGT_STACK;
  695. //printf("new let %s inferred ANY\n",argdefs[0].cell->ar.addr);
  696. }
  697. fn_frame[offset].slot = -frame->locals;
  698. #ifdef DEBUG_ASM_SRC
  699. debug_buf = malloc(256);
  700. snprintf(debug_buf,255,"++ frame entry %s, new stack-local idx %d, is_int %d\n",fn_frame[offset].name,fn_frame[offset].slot,is_int);
  701. jit_comment(debug_buf);
  702. free(debug_buf);
  703. #endif
  704. frame->locals++;
  705. if (frame->locals+MAXARGS>=MAXFRAME) {
  706. printf("<error: too many locals (maximum %d)>\r\n",MAXFRAME-MAXARGS);
  707. }
  708. }
  709. if (is_int) {
  710. jit_comment("(let) load int");
  711. load_int(R0, argdefs[1], frame);
  712. compiled_type = prototype_int;
  713. } else {
  714. jit_comment("(let) load cell");
  715. load_cell(R0, argdefs[1], frame);
  716. compiled_type = prototype_any;
  717. }
  718. if (!is_reg) {
  719. jit_comment("(let) store to stack");
  720. jit_str_stack(R0,PTRSZ*(frame->sp-fn_frame[offset].slot));
  721. }
  722. if (is_reg) {
  723. #ifdef DEBUG_ASM_SRC
  724. debug_buf = malloc(256);
  725. snprintf(debug_buf,255,"(let) store %s to reg %d",fn_frame[offset].name,fn_frame[offset].slot);
  726. jit_comment(debug_buf);
  727. free(debug_buf);
  728. #endif
  729. jit_movr(fn_frame[offset].slot, R0);
  730. }
  731. if (compiled_type->tag == TAG_INT && return_type->tag == TAG_ANY) {
  732. jit_comment("(let) box int");
  733. jit_movr(ARGR0,R0);
  734. jit_call(alloc_int, "alloc_int");
  735. compiled_type = prototype_any;
  736. } else {
  737. }
  738. break;
  739. }
  740. case BUILTIN_FN: {
  741. Cell* fn_body, *fn_args, *lambda;
  742. Arg fn_new_frame[MAXFRAME];
  743. int num_lets, i, j, spo_count, fn_argc;
  744. Cell* compiled_type;
  745. char label_fn[64];
  746. char label_fe[64];
  747. Frame* nframe_ptr;
  748. Frame nframe = {fn_new_frame, 0, 0, frame->stack_end};
  749. #if CPU_ARM||__AMIGA||CPU_X86
  750. Label* fn_lbl;
  751. #endif
  752. if (argi<2) {
  753. printf("error: trying to define fn without body.\n");
  754. return 0;
  755. }
  756. // body
  757. fn_body = argdefs[argi-2].cell;
  758. // estimate stack space for locals
  759. num_lets = analyze_fn(fn_body,NULL,0);
  760. // scan args (build signature)
  761. fn_args = alloc_nil();
  762. for (i=0; i<MAXFRAME; i++) {
  763. fn_new_frame[i].type = 0;
  764. fn_new_frame[i].slot = -1;
  765. fn_new_frame[i].name = NULL;
  766. }
  767. spo_count = 0;
  768. fn_argc = 0;
  769. for (j=argi-3; j>=0; j--) {
  770. Cell* arg;
  771. Cell* arg_prototype = prototype_any;
  772. fn_new_frame[j].type = 0;
  773. fn_new_frame[j].name = NULL;
  774. fn_new_frame[j].type_name = NULL;
  775. if (j>=ARG_SPILLOVER) { // max args passed in registers
  776. fn_new_frame[j].type = ARGT_STACK;
  777. fn_new_frame[j].slot = -num_lets - (j - ARG_SPILLOVER) - 2;
  778. spo_count++;
  779. }
  780. else {
  781. fn_new_frame[j].type = ARGT_REG;
  782. fn_new_frame[j].slot = j + LBDREG;
  783. }
  784. if (argdefs[j].cell->tag == TAG_SYM) {
  785. fn_new_frame[j].name = argdefs[j].cell->ar.addr;
  786. } else if (argdefs[j].cell->tag == TAG_CONS) {
  787. env_entry* type_env = NULL;
  788. Cell* type_cell = car(cdr(argdefs[j].cell));
  789. if (!type_cell) {
  790. printf("<missing struct-name in (arg-name struct-name) declaration>\r\n");
  791. return 0;
  792. }
  793. if (type_cell->tag!=TAG_SYM) {
  794. printf("<non-symbol struct-name in (arg-name struct-name) declaration>\r\n");
  795. return 0;
  796. }
  797. fn_new_frame[j].name = car(argdefs[j].cell)->ar.addr;
  798. fn_new_frame[j].type_name = type_cell->ar.addr;
  799. type_env = lookup_global_symbol(fn_new_frame[j].type_name);
  800. if (!type_env || !type_env->cell) {
  801. printf("<undefined struct-name %s in (arg-name struct-name) declaration>\r\n",fn_new_frame[j].type_name);
  802. return 0;
  803. }
  804. if (type_env->cell->tag!=TAG_STRUCT_DEF) {
  805. printf("<struct-name %s in (arg-name struct-name) declaration does not resolve to a struct definition>\r\n",fn_new_frame[j].type_name);
  806. return 0;
  807. }
  808. // TODO other types!
  809. arg_prototype = type_env->cell;
  810. } else {
  811. // illegal type
  812. printf("<error: only symbols or (symbol typename) allowed in fn signature>\r\n");
  813. return 0;
  814. }
  815. arg = alloc_cons(alloc_sym(fn_new_frame[j].name),arg_prototype);
  816. fn_args = alloc_cons(arg,fn_args);
  817. fn_argc++;
  818. //printf("arg j %d: %s\r\n",j,fn_new_frame[j].name);
  819. }
  820. //char sig_debug[128];
  821. //lisp_write(fn_args, sig_debug, sizeof(sig_debug));
  822. //printf("signature: %s\n",sig_debug);
  823. //lisp_write(fn_body, sig_debug, sizeof(sig_debug));
  824. lambda = alloc_lambda(alloc_cons(fn_args,fn_body));
  825. lambda->dr.next = 0;
  826. sprintf(label_fn,"L0_%p",lambda);
  827. sprintf(label_fe,"L1_%p",lambda);
  828. jit_jmp(label_fe);
  829. jit_label(label_fn);
  830. jit_movi(R2,(jit_word_t)lambda|STACK_FRAME_MARKER);
  831. jit_push(R2,R2);
  832. jit_dec_stack(num_lets*PTRSZ);
  833. if (debug_mode) {
  834. Arg* nargs_ptr;
  835. // in debug mode, we need a copy of the frame definition at runtime
  836. nframe_ptr = malloc(sizeof(Frame));
  837. memcpy(nframe_ptr, &nframe, sizeof(Frame));
  838. nargs_ptr = malloc(sizeof(Arg)*MAXFRAME);
  839. memcpy(nargs_ptr, nframe.f, sizeof(Arg)*MAXFRAME);
  840. nframe_ptr->f = nargs_ptr;
  841. //printf("frame copied: %p args: %p\r\n",nframe_ptr,nframe_ptr->f);
  842. } else {
  843. nframe_ptr = &nframe;
  844. }
  845. //nframe_ptr->parent_frame = frame;
  846. // TODO here we can introduce function return types
  847. compiled_type = compile_expr(fn_body, nframe_ptr, prototype_any); // new frame, fresh sp
  848. if (!compiled_type) return 0;
  849. //printf(">> fn has %d args and %d locals. predicted locals: %d\r\n",fn_argc,nframe.locals,num_lets);
  850. jit_inc_stack(num_lets*PTRSZ);
  851. jit_inc_stack(PTRSZ);
  852. jit_ret();
  853. jit_label(label_fe);
  854. jit_lea(R0,lambda);
  855. #if CPU_ARM||__AMIGA||CPU_X86
  856. fn_lbl = find_label(label_fn);
  857. //printf("fn_lbl idx: %d code: %p\r\n",fn_lbl->idx,code);
  858. lambda->dr.next = code + fn_lbl->idx;
  859. //printf("fn_lbl next: %p\r\n",lambda->dr.next);
  860. #endif
  861. break;
  862. }
  863. case BUILTIN_IF: {
  864. Cell* then_type=NULL;
  865. Cell* else_type=NULL;
  866. char label_skip[64];
  867. sprintf(label_skip,"Lelse_%d",++label_skip_count);
  868. // load the condition
  869. load_int(R0, argdefs[0], frame);
  870. // compare to zero
  871. jit_cmpi(R0,0);
  872. jit_je(label_skip);
  873. // then
  874. then_type = compile_expr(argdefs[1].cell, frame, return_type);
  875. if (!then_type) return 0;
  876. // else
  877. if (argdefs[2].cell) {
  878. char label_end[64];
  879. sprintf(label_end,"Lendif_%d",++label_skip_count);
  880. jit_jmp(label_end);
  881. jit_label(label_skip);
  882. else_type = compile_expr(argdefs[2].cell, frame, return_type);
  883. if (!else_type) return 0;
  884. jit_label(label_end);
  885. } else {
  886. jit_label(label_skip);
  887. }
  888. if (return_type->tag!=TAG_VOID && then_type && else_type && then_type->tag!=else_type->tag) {
  889. printf("<incompatible then/else types of if: %s/%s, return type: %s>\r\n",tag_to_str(then_type->tag),tag_to_str(else_type->tag),tag_to_str(return_type->tag));
  890. return 0;
  891. }
  892. break;
  893. }
  894. case BUILTIN_WHILE: {
  895. char label_loop[64];
  896. char label_skip[64];
  897. char label_skip2[64];
  898. sprintf(label_loop, "Lloop_%d",++label_skip_count);
  899. sprintf(label_skip, "Lskip_%d",label_skip_count);
  900. sprintf(label_skip2,"Lskip2_%d",label_skip_count);
  901. jit_label(label_loop);
  902. compiled_type = compile_expr(argdefs[0].cell, frame, prototype_int);
  903. if (!compiled_type) return 0;
  904. // load the condition
  905. if (compiled_type->tag != TAG_INT) {
  906. jit_ldr(R0);
  907. }
  908. // compare to zero
  909. jit_cmpi(R0,0);
  910. jit_je(label_skip);
  911. // while body
  912. compiled_type = compile_expr(argdefs[1].cell, frame, return_type);
  913. if (!compiled_type) return 0;
  914. jit_jmp(label_loop);
  915. jit_label(label_skip);
  916. if (return_type->tag == TAG_ANY) {
  917. // if the while never executed, we have to create a zero int cell
  918. // from r0
  919. jit_cmpi(R0,0);
  920. jit_jne(label_skip2);
  921. jit_call(alloc_int,"alloc_int");
  922. jit_label(label_skip2);
  923. }
  924. break;
  925. }
  926. case BUILTIN_DO: {
  927. Cell* arg;
  928. args = orig_args;
  929. if (!car(args)) {
  930. printf("<empty (do) not allowed>\r\n");
  931. return 0;
  932. }
  933. while ((arg = car(args))) {
  934. Cell* compiled_type;
  935. if (car(cdr(args))) {
  936. // discard all returns except for the last one
  937. compiled_type = compile_expr(arg, frame, prototype_void);
  938. } else {
  939. compiled_type = compile_expr(arg, frame, return_type);
  940. }
  941. if (!compiled_type) return 0;
  942. args = cdr(args);
  943. }
  944. break;
  945. }
  946. case BUILTIN_LIST: {
  947. Cell* arg;
  948. int n = 0, i;
  949. args = orig_args;
  950. while ((arg = car(args))) {
  951. Cell* compiled_type = compile_expr(arg, frame, prototype_any);
  952. if (!compiled_type) return 0;
  953. jit_push(R0,R0);
  954. frame->sp++;
  955. args = cdr(args);
  956. n++;
  957. }
  958. jit_call(alloc_nil, "list:alloc_nil");
  959. jit_movr(ARGR1,R0);
  960. for (i=0; i<n; i++) {
  961. jit_pop(ARGR0,ARGR0);
  962. frame->sp--;
  963. jit_call2(alloc_cons, "list:alloc_cons");
  964. jit_movr(ARGR1,R0);
  965. }
  966. break; // FIXME
  967. }
  968. case BUILTIN_STRUCT: {
  969. Cell* key;
  970. Cell* arg;
  971. Cell* name_sym;
  972. int n = 0, i;
  973. args = cdr(orig_args);
  974. name_sym = car(orig_args);
  975. // struct knows its own name
  976. jit_lea(R0,name_sym);
  977. jit_push(R0,R0);
  978. while ((key = car(args))) {
  979. if (key->tag != TAG_SYM) {
  980. printf("<every second argument of struct following the struct's name has to be a symbol>\r\n");
  981. return 0;
  982. }
  983. jit_lea(R0,key);
  984. jit_push(R0,R0);
  985. args = cdr(args);
  986. arg = car(args);
  987. if (!arg) return 0;
  988. args = cdr(args);
  989. Cell* compiled_type = compile_expr(arg, frame, prototype_any);
  990. if (!compiled_type) return 0;
  991. jit_push(R0,R0);
  992. frame->sp+=2;
  993. n+=2;
  994. }
  995. n++; // account for name
  996. jit_movi(ARGR0,n);
  997. jit_call(alloc_struct_def, "struct:alloc_struct_def");
  998. jit_movr(R1,R0);
  999. jit_ldr(R1); // load addr of cell array
  1000. jit_addi(R1,n*PTRSZ);
  1001. for (i=0; i<n; i++) {
  1002. jit_addi(R1,-PTRSZ);
  1003. jit_pop(R3,R3);
  1004. frame->sp--;
  1005. jit_stra(R1); // strw from r3
  1006. }
  1007. // load the struct name
  1008. jit_push(R0,R0);
  1009. jit_movr(ARGR1,R0);
  1010. jit_lea(ARGR0,name_sym);
  1011. push_frame_regs(frame->f);
  1012. jit_call2(insert_global_symbol, "insert_global_symbol");
  1013. pop_frame_regs(frame->f);
  1014. jit_pop(R0,R0);
  1015. break;
  1016. }
  1017. case BUILTIN_NEW: {
  1018. Cell* arg;
  1019. if (orig_op) {
  1020. // (struct-def …)
  1021. arg = orig_op;
  1022. } else {
  1023. // (new struct-def …)
  1024. arg = argdefs[0].env->cell;
  1025. }
  1026. //printf("[new] arg: %p\r\n",arg);
  1027. //printf("[new] struct size %d\r\n",arg->dr.size/2);
  1028. // arg points to struct definition which is TAG_VEC
  1029. if (arg->tag != TAG_STRUCT_DEF) {
  1030. printf("<(new) requires a struct definition>\r\n");
  1031. return 0;
  1032. }
  1033. jit_lea(ARGR0,arg);
  1034. jit_call(alloc_struct,"new:alloc_struct");
  1035. compiled_type = alloc_struct(arg); // prototype
  1036. break;
  1037. }
  1038. case BUILTIN_SGET: {
  1039. Cell* struct_def;
  1040. char* lookup_name = argdefs[1].cell->ar.addr;
  1041. Cell** struct_elements;
  1042. int num_fields;
  1043. int found=0;
  1044. if (argdefs[0].type == ARGT_ENV) {
  1045. struct_def = argdefs[0].env->cell;
  1046. struct_def = car(car(struct_def));
  1047. }
  1048. else if (argdefs[0].type_name) {
  1049. //printf("[sget] arg type name %s\r\n",argdefs[0].type_name);
  1050. env_entry* type_env = lookup_global_symbol(argdefs[0].type_name);
  1051. struct_def = type_env->cell;
  1052. //printf("[sget] struct_def %p\r\n",struct_def);
  1053. }
  1054. else {
  1055. printf("<untyped value passed to sget (field %s)>\r\n",lookup_name);
  1056. return 0;
  1057. }
  1058. // arg points to struct definition which is TAG_VEC
  1059. if (struct_def->tag != TAG_STRUCT_DEF) {
  1060. printf("<(sget) requires a struct>\r\n");
  1061. return 0;
  1062. }
  1063. num_fields = struct_def->dr.size/2;
  1064. struct_elements = (Cell**)(struct_def->ar.addr);
  1065. //printf("[sget] struct_elements %p\r\n",struct_elements);
  1066. //printf("[sget] lookup %s\r\n",lookup_name);
  1067. for (int i=0; i<num_fields; i++) {
  1068. if (!strcmp(lookup_name,(char*)struct_elements[1+i*2]->ar.addr)) {
  1069. //printf("field found at index %d\r\n",i);
  1070. load_cell(R0,argdefs[0],frame);
  1071. jit_ldr(R0);
  1072. jit_addi(R0,(i+1)*PTRSZ);
  1073. jit_ldr(R0);
  1074. found = 1;
  1075. // extract and return the field type (prototype)
  1076. compiled_type = struct_elements[1+i*2+1];
  1077. if (compiled_type->tag != TAG_STRUCT) {
  1078. compiled_type = prototype_any; // FIXME
  1079. }
  1080. break;
  1081. }
  1082. }
  1083. if (!found) {
  1084. printf("<sget field %s not found!>\r\n",lookup_name);
  1085. jit_movi(R0,0);
  1086. return 0;
  1087. }
  1088. break;
  1089. }
  1090. case BUILTIN_SPUT: {
  1091. Cell* struct_def;
  1092. char* lookup_name = argdefs[1].cell->ar.addr;
  1093. Cell** struct_elements;
  1094. int num_fields;
  1095. int found=0;
  1096. if (argdefs[0].type == ARGT_ENV) {
  1097. struct_def = argdefs[0].env->cell;
  1098. struct_def = car(car(struct_def));
  1099. } else if (argdefs[0].type_name) {
  1100. env_entry* type_env = lookup_global_symbol(argdefs[0].type_name);
  1101. if (type_env) {
  1102. struct_def = type_env->cell;
  1103. } else {
  1104. printf("<sput: struct type %s not found.>\r\n",argdefs[0].type_name);
  1105. return 0;
  1106. }
  1107. } else {
  1108. printf("<indirect struct field access not yet implemented.>");
  1109. return 0;
  1110. }
  1111. // arg points to struct definition which is TAG_VEC
  1112. if (struct_def->tag != TAG_STRUCT_DEF) {
  1113. printf("<(sput) requires a struct>\r\n");
  1114. return 0;
  1115. }
  1116. num_fields = struct_def->dr.size/2;
  1117. struct_elements = (Cell**)(struct_def->ar.addr);
  1118. //printf("[sput] lookup %s\r\n",lookup_name);
  1119. for (int i=0; i<num_fields; i++) {
  1120. if (!strcmp(lookup_name,(char*)struct_elements[1+i*2]->ar.addr)) {
  1121. //printf("[sput] field found at index %d\r\n",i);
  1122. load_cell(R2,argdefs[0],frame);
  1123. jit_movr(R0,R2);
  1124. jit_ldr(R2);
  1125. jit_addi(R2,(i+1)*PTRSZ);
  1126. load_cell(R3,argdefs[2],frame); // TODO type check!
  1127. jit_stra(R2);
  1128. found = 1;
  1129. break;
  1130. }
  1131. }
  1132. if (!found) {
  1133. printf("<sput field %s not found!>\r\n",lookup_name);
  1134. jit_movi(R0,0);
  1135. return 0;
  1136. }
  1137. break;
  1138. }
  1139. case BUILTIN_QUOTE: {
  1140. Cell* arg;
  1141. args = orig_args;
  1142. if (!car(args)) {
  1143. printf("<empty (quote) not allowed>\r\n");
  1144. return 0;
  1145. }
  1146. arg = car(args);
  1147. jit_lea(R0,arg);
  1148. break;
  1149. }
  1150. case BUILTIN_CAR: {
  1151. load_cell(R0,argdefs[0], frame);
  1152. // type check -------------------
  1153. jit_movr(R1,R0);
  1154. jit_addi(R1,2*PTRSZ);
  1155. jit_ldr(R1);
  1156. jit_lea(R2,consed_type_error);
  1157. jit_cmpi(R1,TAG_CONS);
  1158. jit_movne(R0,R2);
  1159. // ------------------------------
  1160. jit_ldr(R0);
  1161. jit_lea(R2,prototype_nil);
  1162. jit_cmpi(R0,0); // check for null cell
  1163. jit_moveq(R0,R2);
  1164. break;
  1165. }
  1166. case BUILTIN_CDR: {
  1167. load_cell(R0,argdefs[0], frame);
  1168. jit_addi(R0,PTRSZ);
  1169. // type check -------------------
  1170. jit_movr(R1,R0);
  1171. jit_addi(R1,PTRSZ); // because already added PTRSZ
  1172. jit_ldr(R1);
  1173. jit_lea(R2,consed_type_error);
  1174. jit_cmpi(R1,TAG_CONS);
  1175. jit_movne(R0,R2);
  1176. // ------------------------------
  1177. jit_ldr(R0);
  1178. jit_lea(R2,prototype_nil);
  1179. jit_cmpi(R0,0); // check for null cell
  1180. jit_moveq(R0,R2);
  1181. break;
  1182. }
  1183. case BUILTIN_CONS: {
  1184. load_cell(ARGR0,argdefs[0], frame);
  1185. load_cell(ARGR1,argdefs[1], frame);
  1186. jit_call2(alloc_cons,"alloc_cons");
  1187. break;
  1188. }
  1189. case BUILTIN_CONCAT: {
  1190. load_cell(ARGR0,argdefs[0], frame);
  1191. load_cell(ARGR1,argdefs[1], frame);
  1192. jit_call2(alloc_concat,"alloc_concat");
  1193. break;
  1194. }
  1195. case BUILTIN_SUBSTR: {
  1196. load_cell(ARGR0,argdefs[0], frame);
  1197. load_int(ARGR1,argdefs[1], frame);
  1198. load_int(ARGR2,argdefs[2], frame);
  1199. jit_call3(alloc_substr,"alloc_substr");
  1200. break;
  1201. }
  1202. case BUILTIN_GET8: {
  1203. char label_skip[64];
  1204. char label_ok[64];
  1205. sprintf(label_skip,"Lskip_%d",++label_skip_count);
  1206. sprintf(label_ok,"Lok_%d",label_skip_count);
  1207. load_cell(R1,argdefs[0], frame);
  1208. load_int(R2,argdefs[1], frame); // offset -> R2
  1209. jit_movr(R0,R1); // save original cell in r0
  1210. // todo: compile-time checking would be much more awesome
  1211. // type check
  1212. jit_addi(R1,2*PTRSZ);
  1213. jit_ldr(R1);
  1214. jit_cmpi(R1,TAG_BYTES); // todo: better perf with mask?
  1215. jit_je(label_ok);
  1216. jit_cmpi(R1,TAG_STR);
  1217. jit_je(label_ok);
  1218. // wrong type
  1219. jit_movi(R3, 0);
  1220. jit_jmp(label_skip);
  1221. // good type
  1222. jit_label(label_ok);
  1223. jit_movr(R1,R0); // get original cell from r3
  1224. #ifdef CHECK_BOUNDS
  1225. // bounds check -----
  1226. jit_movr(R1,R0);
  1227. jit_addi(R1,PTRSZ);
  1228. jit_ldr(R1);
  1229. jit_cmpr(R2,R1);
  1230. jit_jge(label_skip);
  1231. // -------------------
  1232. #endif
  1233. jit_movr(R1,R0);
  1234. jit_ldr(R1); // string address
  1235. jit_addr(R1,R2);
  1236. jit_movi(R3, 0);
  1237. jit_ldrb(R1); // data in r3
  1238. jit_label(label_skip);
  1239. jit_movr(ARGR0, R3);
  1240. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  1241. else {
  1242. compiled_type = prototype_int;
  1243. jit_movr(R0,ARGR0);
  1244. }
  1245. break;
  1246. }
  1247. case BUILTIN_GET16: {
  1248. char label_skip[64];
  1249. char label_ok[64];
  1250. sprintf(label_skip,"Lskip_%d",++label_skip_count);
  1251. sprintf(label_ok,"Lok_%d",label_skip_count);
  1252. load_cell(R1,argdefs[0], frame);
  1253. load_int(R2,argdefs[1], frame); // offset -> R2
  1254. jit_movr(R0,R1); // save original cell in r0
  1255. // todo: compile-time checking would be much more awesome
  1256. // type check
  1257. jit_addi(R1,2*PTRSZ);
  1258. jit_ldr(R1);
  1259. jit_cmpi(R1,TAG_BYTES); // todo: better perf with mask?
  1260. jit_je(label_ok);
  1261. jit_cmpi(R1,TAG_STR);
  1262. jit_je(label_ok);
  1263. // wrong type
  1264. jit_movi(R3, 0);
  1265. jit_jmp(label_skip);
  1266. // good type
  1267. jit_label(label_ok);
  1268. jit_movr(R1,R0); // get original cell from r3
  1269. #ifdef CHECK_BOUNDS
  1270. // bounds check -----
  1271. jit_movr(R1,R0);
  1272. jit_addi(R1,PTRSZ);
  1273. jit_ldr(R1);
  1274. jit_cmpr(R2,R1);
  1275. jit_jge(label_skip);
  1276. // -------------------
  1277. #endif
  1278. jit_movr(R1,R0);
  1279. jit_ldr(R1); // string address
  1280. jit_addr(R1,R2);
  1281. jit_movi(R3, 0);
  1282. jit_ldrs(R1); // data in r3
  1283. jit_label(label_skip);
  1284. jit_movr(ARGR0, R3);
  1285. if (return_type->tag == TAG_ANY) jit_call(alloc_int, "alloc_int");
  1286. else {
  1287. compiled_type = prototype_int;
  1288. jit_movr(R0,ARGR0);
  1289. }
  1290. break;
  1291. }
  1292. case BUILTIN_PUT8: {
  1293. char label_skip[64];
  1294. sprintf(label_skip,"Lskip_%d",++label_skip_count);
  1295. load_cell(R0,argdefs[0], frame);
  1296. load_int(R2,argdefs[1], frame); // offset -> R2
  1297. load_int(R3,argdefs[2], frame); // byte to store -> R3
  1298. #ifdef CHECK_BOUNDS
  1299. // bounds check -----
  1300. jit_movr(R1,R0);
  1301. jit_addi(R1,PTRSZ);
  1302. jit_ldr(R1);
  1303. jit_cmpr(R2,R1);
  1304. jit_jge(label_skip);
  1305. // -------------------
  1306. #endif
  1307. jit_movr(R1,R0);
  1308. jit_ldr(R1); // string address
  1309. jit_addr(R1,R2);
  1310. jit_strb(R1); // address is in r1, data in r3
  1311. jit_label(label_skip);
  1312. break;
  1313. }
  1314. case BUILTIN_PUT16: {
  1315. char label_skip[64];
  1316. sprintf(label_skip,"Lskip_%d",++label_skip_count);
  1317. load_cell(R0,argdefs[0], frame);
  1318. load_int(R2,argdefs[1], frame); // offset -> R2
  1319. load_int(R3,argdefs[2], frame); // byte to store -> R3
  1320. #ifdef CHECK_BOUNDS
  1321. // bounds check -----
  1322. jit_movr(R1,R0);
  1323. jit_addi(R1,PTRSZ);
  1324. jit_ldr(R1);
  1325. jit_cmpr(R2,R1);
  1326. jit_jge(label_skip);
  1327. // -------------------
  1328. #endif
  1329. jit_movr(R1,R0);
  1330. jit_ldr(R1); // string address
  1331. jit_addr(R1,R2);
  1332. jit_strs(R1); // address is in r1, data in r3
  1333. jit_label(label_skip);
  1334. break;
  1335. }
  1336. case BUILTIN_GET32: {
  1337. load_int(R2,argdefs[1], frame); // offset -> R2
  1338. load_cell(R3,argdefs[0], frame);
  1339. jit_ldr(R3); // string address
  1340. jit_movi(R1,2); // offset * 4
  1341. jit_shlr(R2,R1);
  1342. jit_addr(R3,R2);
  1343. jit_ldrw(R3); // load to r3
  1344. jit_movr(ARGR0, R3); // FIXME
  1345. jit_call(alloc_int,"alloc_int");
  1346. break;
  1347. }
  1348. case BUILTIN_PUT32: {
  1349. char label_skip[64];
  1350. sprintf(label_skip,"Lskip_%d",++label_skip_count);
  1351. load_cell(R1,argdefs[0], frame);
  1352. load_int(R2,argdefs[1], frame); // offset -> R2
  1353. load_int(R3,argdefs[2], frame); // word to store -> R3
  1354. #ifdef CHECK_BOUNDS
  1355. // bounds check -----
  1356. jit_movr(R1,R0);
  1357. jit_addi(R1,PTRSZ);
  1358. jit_ldr(R1);
  1359. jit_cmpr(R2,R1);
  1360. jit_jge(label_skip);
  1361. // -------------------
  1362. #endif
  1363. // TODO: 32-bit align
  1364. jit_movr(R1,R0);
  1365. jit_ldr(R1); // string address
  1366. jit_addr(R1,R2);
  1367. jit_strw(R1); // store from r3
  1368. jit_label(label_skip);
  1369. jit_movr(R0,R1);
  1370. jit_call(alloc_int,"debug");
  1371. break;
  1372. }
  1373. case BUILTIN_ALLOC: {
  1374. load_int(ARGR0,argdefs[0], frame);
  1375. jit_call(alloc_num_bytes,"alloc_bytes");
  1376. break;
  1377. }
  1378. case BUILTIN_ALLOC_STR: {
  1379. load_int(ARGR0,argdefs[0], frame);
  1380. jit_call(alloc_num_string,"alloc_string");
  1381. break;
  1382. }
  1383. case BUILTIN_BYTES_TO_STR: {
  1384. load_cell(ARGR0,argdefs[0], frame);
  1385. jit_call(alloc_string_from_bytes,"alloc_string_to_bytes");
  1386. break;
  1387. }
  1388. case BUILTIN_WRITE: {
  1389. load_cell(ARGR0,argdefs[0], frame);
  1390. load_cell(ARGR1,argdefs[1], frame);
  1391. jit_host_call_enter();
  1392. jit_call2(lisp_write_to_cell,"lisp_write_to_cell");
  1393. jit_host_call_exit();
  1394. break;
  1395. }
  1396. case BUILTIN_READ: {
  1397. load_cell(ARGR0,argdefs[0], frame);
  1398. jit_host_call_enter();
  1399. jit_call(read_string_cell,"read_string_cell");
  1400. jit_host_call_exit();
  1401. break;
  1402. }
  1403. case BUILTIN_EVAL: {
  1404. load_cell(ARGR0,argdefs[0], frame);
  1405. jit_host_call_enter();
  1406. jit_call(platform_eval,"platform_eval");
  1407. jit_host_call_exit();
  1408. break;
  1409. }
  1410. case BUILTIN_SIZE: {
  1411. load_cell(ARGR0,argdefs[0], frame);
  1412. jit_addi(ARGR0,PTRSZ); // fetch size -> R0
  1413. jit_ldr(ARGR0);
  1414. if (return_type->tag == TAG_ANY) {
  1415. jit_call(alloc_int, "alloc_int");
  1416. } else if (return_type->tag == TAG_INT) {
  1417. jit_movr(R0,ARGR0);
  1418. compiled_type = prototype_int;
  1419. }
  1420. break;
  1421. }
  1422. case BUILTIN_GC: {
  1423. push_frame_regs(frame->f);
  1424. jit_lea(ARGR0,global_env);
  1425. jit_movi(ARGR1,(jit_word_t)frame->stack_end);
  1426. jit_movr(ARGR2,RSP);
  1427. jit_call3(collect_garbage,"collect_garbage");
  1428. pop_frame_regs(frame->f);
  1429. break;
  1430. }
  1431. case BUILTIN_SYMBOLS: {
  1432. jit_lea(ARGR0,global_env);
  1433. jit_call(list_symbols,"list_symbols");
  1434. break;
  1435. }
  1436. case BUILTIN_DEBUG: {
  1437. //jit_call(platform_debug,"platform_debug");
  1438. break;
  1439. }
  1440. case BUILTIN_PRINT: {
  1441. load_cell(ARGR0,argdefs[0], frame);
  1442. push_frame_regs(frame->f);
  1443. jit_host_call_enter();
  1444. jit_call(lisp_print,"lisp_print");
  1445. jit_host_call_exit();
  1446. pop_frame_regs(frame->f);
  1447. break;
  1448. }
  1449. case BUILTIN_MOUNT: {
  1450. load_cell(ARGR0,argdefs[0], frame);
  1451. load_cell(ARGR1,argdefs[1], frame);
  1452. jit_host_call_enter();
  1453. jit_call2(fs_mount,"fs_mount");
  1454. jit_host_call_exit();
  1455. break;
  1456. }
  1457. case BUILTIN_MMAP: {
  1458. load_cell(ARGR0,argdefs[0], frame);
  1459. jit_host_call_enter();
  1460. jit_call(fs_mmap,"fs_mmap");
  1461. jit_host_call_exit();
  1462. break;
  1463. }
  1464. case BUILTIN_OPEN: {
  1465. load_cell(ARGR0,argdefs[0], frame);
  1466. push_frame_regs(frame->f);
  1467. jit_host_call_enter();
  1468. jit_call(fs_open,"fs_open");
  1469. jit_host_call_exit();
  1470. pop_frame_regs(frame->f);
  1471. break;
  1472. }
  1473. case BUILTIN_RECV: {
  1474. load_cell(ARGR0,argdefs[0], frame);
  1475. push_frame_regs(frame->f);
  1476. jit_host_call_enter();
  1477. jit_call(stream_read,"stream_read");
  1478. jit_host_call_exit();
  1479. pop_frame_regs(frame->f);
  1480. break;
  1481. }
  1482. case BUILTIN_SEND: {
  1483. load_cell(ARGR0,argdefs[0], frame);
  1484. load_cell(ARGR1,argdefs[1], frame);
  1485. push_frame_regs(frame->f);
  1486. jit_host_call_enter();
  1487. jit_call2(stream_write,"stream_write");
  1488. jit_host_call_exit();
  1489. pop_frame_regs(frame->f);
  1490. break;
  1491. }
  1492. }
  1493. } else {
  1494. // λλλ lambda call λλλ
  1495. int spo_adjust = 0, j;
  1496. // save our args
  1497. int pushed = push_frame_regs(frame->f);
  1498. frame->sp+=pushed;
  1499. for (j=argi-2; j>=0; j--) {
  1500. if (j>=ARG_SPILLOVER) {
  1501. // pass arg on stack
  1502. load_cell(R0, argdefs[j], frame);
  1503. jit_push(R0,R0);
  1504. spo_adjust++;
  1505. frame->sp++;
  1506. } else {
  1507. // pass arg in reg (LBDREG + slot)
  1508. if (argdefs[j].type == ARGT_REG) {
  1509. // FIXME kludge?
  1510. if (1 || argdefs[j].slot<j+LBDREG) {
  1511. int offset = ((pushed+spo_adjust) - (argdefs[j].slot-LBDREG) - 1);
  1512. // register already clobbered, load from stack
  1513. //printf("-- loading clobbered reg %d from stack offset %d to reg %d\n",argdefs[j].slot,offset,LBDREG+j);
  1514. jit_ldr_stack(LBDREG+j, offset*PTRSZ);
  1515. } else {
  1516. // no need to move a reg into itself
  1517. if (argdefs[j].slot!=j) {
  1518. load_cell(LBDREG+j, argdefs[j], frame);
  1519. }
  1520. }
  1521. }
  1522. else {
  1523. load_cell(LBDREG+j, argdefs[j], frame);
  1524. }
  1525. }
  1526. }
  1527. jit_lea(R0,op_env);
  1528. jit_ldr(R0); // load cell
  1529. jit_addi(R0,PTRSZ); // &cell->dr.next
  1530. jit_ldr(R0); // cell->dr.next
  1531. jit_callr(R0); // the call!
  1532. if (spo_adjust) {
  1533. jit_inc_stack(spo_adjust*PTRSZ);
  1534. frame->sp-=spo_adjust;
  1535. }
  1536. pop_frame_regs(frame->f);
  1537. frame->sp-=pushed;
  1538. }
  1539. #ifdef CPU_X64
  1540. fflush(jit_out);
  1541. #endif
  1542. // at this point, registers R1-R6 are filled, execute
  1543. return clean_return(args_pushed, frame, compiled_type);
  1544. }
  1545. env_t* get_global_env() {
  1546. return global_env;
  1547. }
  1548. void init_compiler() {
  1549. Cell** signature = malloc(sizeof(Cell*)*3);
  1550. //printf("[compiler] creating global env hash table\r\n");
  1551. global_env = sm_new(1000);
  1552. //printf("[compiler] init_allocator\r\n");
  1553. init_allocator();
  1554. prototype_nil = alloc_nil();
  1555. prototype_type_error = alloc_error(ERR_INVALID_PARAM_TYPE);
  1556. consed_type_error = alloc_cons(prototype_type_error,prototype_nil);
  1557. prototype_any = alloc_int(0);
  1558. prototype_any->tag = TAG_ANY;
  1559. prototype_void = alloc_int(0);
  1560. prototype_void->tag = TAG_VOID;
  1561. prototype_symbol = alloc_sym("symbol");
  1562. prototype_int = alloc_int(0);
  1563. prototype_struct = alloc_int(0);
  1564. prototype_struct->tag = TAG_STRUCT;
  1565. prototype_struct_def = alloc_int(0);
  1566. prototype_struct_def->tag = TAG_STRUCT_DEF;
  1567. prototype_stream = alloc_int(0);
  1568. prototype_stream->tag = TAG_STREAM;
  1569. prototype_string = alloc_string_copy("string");
  1570. prototype_lambda = alloc_int(0);
  1571. prototype_lambda->tag = TAG_LAMBDA;
  1572. prototype_cons = alloc_cons(alloc_nil(),alloc_nil());
  1573. insert_symbol(alloc_sym("nil"), prototype_nil, &global_env);
  1574. insert_symbol(alloc_sym("type_error"), consed_type_error, &global_env);
  1575. //printf("[compiler] inserting symbols\r\n");
  1576. signature[0]=prototype_symbol; signature[1]=prototype_any;
  1577. insert_symbol(alloc_sym("def"), alloc_builtin(BUILTIN_DEF, alloc_list(signature, 2)), &global_env);
  1578. insert_symbol(alloc_sym("let"), alloc_builtin(BUILTIN_LET, alloc_list(signature, 2)), &global_env);
  1579. signature[0]=prototype_struct_def; signature[1]=prototype_symbol; signature[2]=prototype_any;
  1580. insert_symbol(alloc_sym("new"), alloc_builtin(BUILTIN_NEW, alloc_list(signature, 1)), &global_env);
  1581. signature[0]=prototype_struct;
  1582. insert_symbol(alloc_sym("sget"), alloc_builtin(BUILTIN_SGET, alloc_list(signature, 2)), &global_env);
  1583. insert_symbol(alloc_sym("sput"), alloc_builtin(BUILTIN_SPUT, alloc_list(signature, 3)), &global_env);
  1584. signature[0]=prototype_int; signature[1]=prototype_int;
  1585. insert_symbol(alloc_sym("+"), alloc_builtin(BUILTIN_ADD, alloc_list(signature, 2)), &global_env);
  1586. insert_symbol(alloc_sym("-"), alloc_builtin(BUILTIN_SUB, alloc_list(signature, 2)), &global_env);
  1587. insert_symbol(alloc_sym("*"), alloc_builtin(BUILTIN_MUL, alloc_list(signature, 2)), &global_env);
  1588. insert_symbol(alloc_sym("/"), alloc_builtin(BUILTIN_DIV, alloc_list(signature, 2)), &global_env);
  1589. insert_symbol(alloc_sym("%"), alloc_builtin(BUILTIN_MOD, alloc_list(signature, 2)), &global_env);
  1590. insert_symbol(alloc_sym("bitand"), alloc_builtin(BUILTIN_BITAND, alloc_list(signature, 2)), &global_env);
  1591. insert_symbol(alloc_sym("bitor"), alloc_builtin(BUILTIN_BITOR, alloc_list(signature, 2)), &global_env);
  1592. insert_symbol(alloc_sym("bitnot"), alloc_builtin(BUILTIN_BITNOT, alloc_list(signature, 1)), &global_env);
  1593. insert_symbol(alloc_sym("bitxor"), alloc_builtin(BUILTIN_BITXOR, alloc_list(signature, 2)), &global_env);
  1594. insert_symbol(alloc_sym("shl"), alloc_builtin(BUILTIN_SHL, alloc_list(signature, 2)), &global_env);
  1595. insert_symbol(alloc_sym("shr"), alloc_builtin(BUILTIN_SHR, alloc_list(signature, 2)), &global_env);
  1596. //printf("[compiler] arithmetic\r\n");
  1597. insert_symbol(alloc_sym("lt"), alloc_builtin(BUILTIN_LT, alloc_list(signature, 2)), &global_env);
  1598. insert_symbol(alloc_sym("gt"), alloc_builtin(BUILTIN_GT, alloc_list(signature, 2)), &global_env);
  1599. insert_symbol(alloc_sym("eq"), alloc_builtin(BUILTIN_EQ, alloc_list(signature, 2)), &global_env);
  1600. //printf("[compiler] compare\r\n");
  1601. signature[0]=prototype_int; signature[1]=prototype_lambda; signature[2]=prototype_lambda;
  1602. insert_symbol(alloc_sym("if"), alloc_builtin(BUILTIN_IF, alloc_list(signature, 3)), &global_env);
  1603. insert_symbol(alloc_sym("fn"), alloc_builtin(BUILTIN_FN, NULL), &global_env);
  1604. insert_symbol(alloc_sym("while"), alloc_builtin(BUILTIN_WHILE, NULL), &global_env);
  1605. insert_symbol(alloc_sym("do"), alloc_builtin(BUILTIN_DO, NULL), &global_env);
  1606. signature[0]=prototype_any;
  1607. insert_symbol(alloc_sym("print"), alloc_builtin(BUILTIN_PRINT, alloc_list(signature, 1)), &global_env);
  1608. //printf("[compiler] flow\r\n");
  1609. signature[0]=prototype_cons;
  1610. insert_symbol(alloc_sym("car"), alloc_builtin(BUILTIN_CAR, alloc_list(signature, 1)), &global_env);
  1611. insert_symbol(alloc_sym("cdr"), alloc_builtin(BUILTIN_CDR, alloc_list(signature, 1)), &global_env);
  1612. signature[0]=prototype_any; signature[1]=prototype_any;
  1613. insert_symbol(alloc_sym("cons"), alloc_builtin(BUILTIN_CONS, alloc_list(signature, 2)), &global_env);
  1614. insert_symbol(alloc_sym("list"), alloc_builtin(BUILTIN_LIST, NULL), &global_env);
  1615. insert_symbol(alloc_sym("quote"), alloc_builtin(BUILTIN_QUOTE, NULL), &global_env);
  1616. insert_symbol(alloc_sym("struct"), alloc_builtin(BUILTIN_STRUCT, NULL), &global_env);
  1617. //insert_symbol(alloc_sym("map"), alloc_builtin(BUILTIN_MAP), &global_env);
  1618. //printf("[compiler] lists\r\n");
  1619. signature[0]=prototype_string;
  1620. signature[1]=prototype_string;
  1621. insert_symbol(alloc_sym("concat"), alloc_builtin(BUILTIN_CONCAT, alloc_list(signature, 2)), &global_env);
  1622. signature[0]=prototype_string;
  1623. signature[1]=prototype_int;
  1624. signature[2]=prototype_int;
  1625. insert_symbol(alloc_sym("substr"), alloc_builtin(BUILTIN_SUBSTR, alloc_list(signature, 3)), &global_env);
  1626. insert_symbol(alloc_sym("put8"), alloc_builtin(BUILTIN_PUT8, alloc_list(signature, 3)), &global_env);
  1627. insert_symbol(alloc_sym("get8"), alloc_builtin(BUILTIN_GET8, alloc_list(signature, 2)), &global_env);
  1628. insert_symbol(alloc_sym("put16"), alloc_builtin(BUILTIN_PUT16, alloc_list(signature, 3)), &global_env);
  1629. insert_symbol(alloc_sym("get16"), alloc_builtin(BUILTIN_GET16, alloc_list(signature, 2)), &global_env);
  1630. insert_symbol(alloc_sym("get32"), alloc_builtin(BUILTIN_GET32, alloc_list(signature, 2)), &global_env);
  1631. insert_symbol(alloc_sym("put32"), alloc_builtin(BUILTIN_PUT32, alloc_list(signature, 3)), &global_env);
  1632. insert_symbol(alloc_sym("size"), alloc_builtin(BUILTIN_SIZE, alloc_list(signature, 1)), &global_env);
  1633. signature[0]=prototype_int;
  1634. insert_symbol(alloc_sym("alloc"), alloc_builtin(BUILTIN_ALLOC, alloc_list(signature, 1)), &global_env);
  1635. insert_symbol(alloc_sym("alloc-str"), alloc_builtin(BUILTIN_ALLOC_STR, alloc_list(signature, 1)), &global_env);
  1636. signature[0]=prototype_any;
  1637. insert_symbol(alloc_sym("bytes->str"), alloc_builtin(BUILTIN_BYTES_TO_STR, alloc_list(signature, 1)), &global_env);
  1638. //printf("[compiler] strings\r\n");
  1639. signature[0]=prototype_any;
  1640. signature[1]=prototype_string;
  1641. insert_symbol(alloc_sym("write"), alloc_builtin(BUILTIN_WRITE, alloc_list(signature,2)), &global_env);
  1642. insert_symbol(alloc_sym("eval"), alloc_builtin(BUILTIN_EVAL, alloc_list(signature,1)), &global_env);
  1643. signature[0]=prototype_string;
  1644. insert_symbol(alloc_sym("read"), alloc_builtin(BUILTIN_READ, alloc_list(signature,1)), &global_env);
  1645. signature[0]=prototype_string;
  1646. signature[1]=prototype_cons;
  1647. insert_symbol(alloc_sym("mount"), alloc_builtin(BUILTIN_MOUNT, alloc_list(signature,2)), &global_env);
  1648. insert_symbol(alloc_sym("open"), alloc_builtin(BUILTIN_OPEN, alloc_list(signature,1)), &global_env);
  1649. insert_symbol(alloc_sym("mmap"), alloc_builtin(BUILTIN_MMAP, alloc_list(signature,1)), &global_env);
  1650. signature[0]=prototype_stream;
  1651. signature[1]=prototype_any;
  1652. insert_symbol(alloc_sym("recv"), alloc_builtin(BUILTIN_RECV, alloc_list(signature,1)), &global_env);
  1653. insert_symbol(alloc_sym("send"), alloc_builtin(BUILTIN_SEND, alloc_list(signature,2)), &global_env);
  1654. //printf("[compiler] write/eval\r\n");
  1655. insert_symbol(alloc_sym("gc"), alloc_builtin(BUILTIN_GC, NULL), &global_env);
  1656. insert_symbol(alloc_sym("symbols"), alloc_builtin(BUILTIN_SYMBOLS, NULL), &global_env);
  1657. insert_symbol(alloc_sym("debug"), alloc_builtin(BUILTIN_DEBUG, NULL), &global_env);
  1658. printf("[compiler] interim knows %u symbols. enter (symbols) to see them.\r\n", sm_get_count(global_env));
  1659. }