compiler_new.c 56 KB

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