cc_core.c 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925
  1. /* Copyright (C) 2016 Jeremiah Orians
  2. * Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  3. * Copyright (C) 2020 deesix <deesix@tuta.io>
  4. * This file is part of M2-Planet.
  5. *
  6. * M2-Planet is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * M2-Planet is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "cc.h"
  20. #include "gcc_req.h"
  21. #include <stdint.h>
  22. /* Global lists */
  23. struct token_list* global_symbol_list;
  24. struct token_list* global_function_list;
  25. struct token_list* global_constant_list;
  26. /* Core lists for this file */
  27. struct token_list* function;
  28. /* What we are currently working on */
  29. struct type* current_target;
  30. char* break_target_head;
  31. char* break_target_func;
  32. char* break_target_num;
  33. char* continue_target_head;
  34. struct token_list* break_frame;
  35. int current_count;
  36. int Address_of;
  37. /* Imported functions */
  38. char* number_to_hex(int a, int bytes);
  39. char* numerate_number(int a);
  40. char* parse_string(char* string);
  41. int escape_lookup(char* c);
  42. int numerate_string(char *a);
  43. void require(int bool, char* error);
  44. struct token_list* reverse_list(struct token_list* head);
  45. struct type* mirror_type(struct type* source, char* name);
  46. struct type* add_primitive(struct type* a);
  47. /* Host touchy function will need custom on 64bit systems*/
  48. int fixup_int32(int a);
  49. struct token_list* emit(char *s, struct token_list* head)
  50. {
  51. struct token_list* t = calloc(1, sizeof(struct token_list));
  52. require(NULL != t, "Exhusted memory while generating token to emit\n");
  53. t->next = head;
  54. t->s = s;
  55. return t;
  56. }
  57. void emit_out(char* s)
  58. {
  59. output_list = emit(s, output_list);
  60. }
  61. struct token_list* uniqueID(char* s, struct token_list* l, char* num)
  62. {
  63. l = emit("\n", emit(num, emit("_", emit(s, l))));
  64. return l;
  65. }
  66. void uniqueID_out(char* s, char* num)
  67. {
  68. output_list = uniqueID(s, output_list, num);
  69. }
  70. struct token_list* sym_declare(char *s, struct type* t, struct token_list* list)
  71. {
  72. struct token_list* a = calloc(1, sizeof(struct token_list));
  73. require(NULL != a, "Exhusted memory while attempting to declare a symbol\n");
  74. a->next = list;
  75. a->s = s;
  76. a->type = t;
  77. return a;
  78. }
  79. struct token_list* sym_lookup(char *s, struct token_list* symbol_list)
  80. {
  81. struct token_list* i;
  82. for(i = symbol_list; NULL != i; i = i->next)
  83. {
  84. if(match(i->s, s)) return i;
  85. }
  86. return NULL;
  87. }
  88. void line_error()
  89. {
  90. require(NULL != global_token, "EOF reached inside of line_error\n");
  91. file_print(global_token->filename, stderr);
  92. file_print(":", stderr);
  93. file_print(numerate_number(global_token->linenumber), stderr);
  94. file_print(":", stderr);
  95. }
  96. void require_match(char* message, char* required)
  97. {
  98. require(NULL != global_token, "EOF reached inside of require match\n");
  99. if(!match(global_token->s, required))
  100. {
  101. line_error();
  102. file_print(message, stderr);
  103. exit(EXIT_FAILURE);
  104. }
  105. global_token = global_token->next;
  106. require(NULL != global_token, "EOF after require match occurred\n");
  107. }
  108. void expression();
  109. void function_call(char* s, int bool)
  110. {
  111. require_match("ERROR in process_expression_list\nNo ( was found\n", "(");
  112. int passed = 0;
  113. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  114. {
  115. emit_out("PUSHR R13 R15\t# Prevent overwriting in recursion\n");
  116. emit_out("PUSHR R14 R15\t# Protect the old base pointer\n");
  117. emit_out("COPY R13 R15\t# Copy new base pointer\n");
  118. }
  119. else if(X86 == Architecture)
  120. {
  121. emit_out("PUSH_edi\t# Prevent overwriting in recursion\n");
  122. emit_out("PUSH_ebp\t# Protect the old base pointer\n");
  123. emit_out("COPY_esp_to_edi\t# Copy new base pointer\n");
  124. }
  125. else if(AMD64 == Architecture)
  126. {
  127. emit_out("PUSH_RDI\t# Prevent overwriting in recursion\n");
  128. emit_out("PUSH_RBP\t# Protect the old base pointer\n");
  129. emit_out("COPY_RSP_to_RDI\t# Copy new base pointer\n");
  130. }
  131. else if(ARMV7L == Architecture)
  132. {
  133. emit_out("{R11} PUSH_ALWAYS\t# Prevent overwriting in recursion\n");
  134. emit_out("{BP} PUSH_ALWAYS\t# Protect the old base pointer\n");
  135. emit_out("'0' SP R11 NO_SHIFT MOVE_ALWAYS\t# Copy new base pointer\n");
  136. }
  137. else if(AARCH64 == Architecture)
  138. {
  139. emit_out("PUSH_X16\t# Protect a tmp register we're going to use\n");
  140. emit_out("PUSH_LR\t# Protect the old return pointer (link)\n");
  141. emit_out("PUSH_BP\t# Protect the old base pointer\n");
  142. emit_out("SET_X16_FROM_SP\t# The base pointer to-be\n");
  143. }
  144. if(global_token->s[0] != ')')
  145. {
  146. expression();
  147. require(NULL != global_token, "incomplete function call, recieved EOF instead of )\n");
  148. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression1\n");
  149. else if(X86 == Architecture) emit_out("PUSH_eax\t#_process_expression1\n");
  150. else if(AMD64 == Architecture) emit_out("PUSH_RAX\t#_process_expression1\n");
  151. else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_process_expression1\n");
  152. else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_process_expression1\n");
  153. passed = 1;
  154. while(global_token->s[0] == ',')
  155. {
  156. global_token = global_token->next;
  157. require(NULL != global_token, "incomplete function call, recieved EOF instead of argument\n");
  158. expression();
  159. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression2\n");
  160. else if(X86 == Architecture) emit_out("PUSH_eax\t#_process_expression2\n");
  161. else if(AMD64 == Architecture) emit_out("PUSH_RAX\t#_process_expression2\n");
  162. else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_process_expression2\n");
  163. else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_process_expression2\n");
  164. passed = passed + 1;
  165. }
  166. }
  167. require_match("ERROR in process_expression_list\nNo ) was found\n", ")");
  168. if(TRUE == bool)
  169. {
  170. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  171. {
  172. emit_out("LOAD R0 R14 ");
  173. emit_out(s);
  174. emit_out("\nMOVE R14 R13\n");
  175. emit_out("CALL R0 R15\n");
  176. }
  177. else if(X86 == Architecture)
  178. {
  179. emit_out("LOAD_BASE_ADDRESS_eax %");
  180. emit_out(s);
  181. emit_out("\nLOAD_INTEGER\n");
  182. emit_out("COPY_edi_to_ebp\n");
  183. emit_out("CALL_eax\n");
  184. }
  185. else if(AMD64 == Architecture)
  186. {
  187. emit_out("LOAD_BASE_ADDRESS_rax %");
  188. emit_out(s);
  189. emit_out("\nLOAD_INTEGER\n");
  190. emit_out("COPY_rdi_to_rbp\n");
  191. emit_out("CALL_rax\n");
  192. }
  193. else if(ARMV7L == Architecture)
  194. {
  195. emit_out("!");
  196. emit_out(s);
  197. emit_out(" R0 SUB BP ARITH_ALWAYS\n");
  198. emit_out("!0 R0 LOAD32 R0 MEMORY\n");
  199. emit_out("{LR} PUSH_ALWAYS\t# Protect the old link register\n");
  200. emit_out("'0' R11 BP NO_SHIFT MOVE_ALWAYS\n");
  201. emit_out("'3' R0 CALL_REG_ALWAYS\n");
  202. emit_out("{LR} POP_ALWAYS\t# Prevent overwrite\n");
  203. }
  204. else if(AARCH64 == Architecture)
  205. {
  206. emit_out("SET_X0_FROM_BP\n");
  207. emit_out("LOAD_W1_AHEAD\nSKIP_32_DATA\n%");
  208. emit_out(s);
  209. emit_out("\nSUB_X0_X0_X1\n");
  210. emit_out("DEREF_X0\n");
  211. emit_out("SET_BP_FROM_X16\n");
  212. emit_out("SET_X16_FROM_X0\n");
  213. emit_out("BLR_X16\n");
  214. }
  215. }
  216. else
  217. {
  218. if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture))
  219. {
  220. emit_out("MOVE R14 R13\n");
  221. emit_out("LOADR R0 4\nJUMP 4\n&FUNCTION_");
  222. emit_out(s);
  223. emit_out("\nCALL R0 R15\n");
  224. }
  225. else if(X86 == Architecture)
  226. {
  227. emit_out("COPY_edi_to_ebp\n");
  228. emit_out("CALL_IMMEDIATE %FUNCTION_");
  229. emit_out(s);
  230. emit_out("\n");
  231. }
  232. else if(AMD64 == Architecture)
  233. {
  234. emit_out("COPY_rdi_to_rbp\n");
  235. emit_out("CALL_IMMEDIATE %FUNCTION_");
  236. emit_out(s);
  237. emit_out("\n");
  238. }
  239. else if(ARMV7L == Architecture)
  240. {
  241. emit_out("{LR} PUSH_ALWAYS\t# Protect the old link register\n");
  242. emit_out("'0' R11 BP NO_SHIFT MOVE_ALWAYS\n");
  243. emit_out("^~FUNCTION_");
  244. emit_out(s);
  245. emit_out(" CALL_ALWAYS\n");
  246. emit_out("{LR} POP_ALWAYS\t# Restore the old link register\n");
  247. }
  248. else if(AARCH64 == Architecture)
  249. {
  250. emit_out("SET_BP_FROM_X16\n");
  251. emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FUNCTION_");
  252. emit_out(s);
  253. emit_out("\n");
  254. emit_out("BLR_X16\n");
  255. }
  256. }
  257. for(; passed > 0; passed = passed - 1)
  258. {
  259. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _process_expression_locals\n");
  260. else if(X86 == Architecture) emit_out("POP_ebx\t# _process_expression_locals\n");
  261. else if(AMD64 == Architecture) emit_out("POP_RBX\t# _process_expression_locals\n");
  262. else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _process_expression_locals\n");
  263. else if(AARCH64 == Architecture) emit_out("POP_X1\t# _process_expression_locals\n");
  264. }
  265. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  266. {
  267. emit_out("POPR R14 R15\t# Restore old base pointer\n");
  268. emit_out("POPR R13 R15\t# Prevent overwrite\n");
  269. }
  270. else if(X86 == Architecture)
  271. {
  272. emit_out("POP_ebp\t# Restore old base pointer\n");
  273. emit_out("POP_edi\t# Prevent overwrite\n");
  274. }
  275. else if(AMD64 == Architecture)
  276. {
  277. emit_out("POP_RBP\t# Restore old base pointer\n");
  278. emit_out("POP_RDI\t# Prevent overwrite\n");
  279. }
  280. else if(ARMV7L == Architecture)
  281. {
  282. emit_out("{BP} POP_ALWAYS\t# Restore old base pointer\n");
  283. emit_out("{R11} POP_ALWAYS\t# Prevent overwrite\n");
  284. }
  285. else if(AARCH64 == Architecture)
  286. {
  287. emit_out("POP_BP\t# Restore the old base pointer\n");
  288. emit_out("POP_LR\t# Restore the old return pointer (link)\n");
  289. emit_out("POP_X16\t# Restore a register we used as tmp\n");
  290. }
  291. }
  292. void constant_load(struct token_list* a)
  293. {
  294. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADI R0 ");
  295. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
  296. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax %");
  297. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
  298. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
  299. emit_out(a->arguments->s);
  300. emit_out("\n");
  301. }
  302. void variable_load(struct token_list* a)
  303. {
  304. require(NULL != global_token, "incomplete variable load recieved\n");
  305. if((match("FUNCTION", a->type->name) || match("FUNCTION*", a->type->name)) && match("(", global_token->s))
  306. {
  307. function_call(numerate_number(a->depth), TRUE);
  308. return;
  309. }
  310. current_target = a->type;
  311. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("ADDI R0 R14 ");
  312. else if(X86 == Architecture) emit_out("LOAD_BASE_ADDRESS_eax %");
  313. else if(AMD64 == Architecture) emit_out("LOAD_BASE_ADDRESS_rax %");
  314. else if(ARMV7L == Architecture) emit_out("!");
  315. else if(AARCH64 == Architecture) emit_out("SET_X0_FROM_BP\nLOAD_W1_AHEAD\nSKIP_32_DATA\n%");
  316. emit_out(numerate_number(a->depth));
  317. if(ARMV7L == Architecture) emit_out(" R0 SUB BP ARITH_ALWAYS");
  318. else if(AARCH64 == Architecture) emit_out("\nSUB_X0_X0_X1\n");
  319. emit_out("\n");
  320. if(TRUE == Address_of) return;
  321. if(match("=", global_token->s)) return;
  322. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOAD R0 R0 0\n");
  323. else if(X86 == Architecture) emit_out("LOAD_INTEGER\n");
  324. else if(AMD64 == Architecture) emit_out("LOAD_INTEGER\n");
  325. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R0 MEMORY\n");
  326. else if(AARCH64 == Architecture) emit_out("DEREF_X0\n");
  327. }
  328. void function_load(struct token_list* a)
  329. {
  330. require(NULL != global_token, "incomplete function load\n");
  331. if(match("(", global_token->s))
  332. {
  333. function_call(a->s, FALSE);
  334. return;
  335. }
  336. if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&FUNCTION_");
  337. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax &FUNCTION_");
  338. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax &FUNCTION_");
  339. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&FUNCTION_");
  340. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&FUNCTION_");
  341. emit_out(a->s);
  342. emit_out("\n");
  343. }
  344. void global_load(struct token_list* a)
  345. {
  346. current_target = a->type;
  347. if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&GLOBAL_");
  348. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax &GLOBAL_");
  349. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax &GLOBAL_");
  350. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&GLOBAL_");
  351. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&GLOBAL_");
  352. emit_out(a->s);
  353. emit_out("\n");
  354. require(NULL != global_token, "unterminated global load\n");
  355. if(!match("=", global_token->s))
  356. {
  357. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOAD R0 R0 0\n");
  358. else if(X86 == Architecture) emit_out("LOAD_INTEGER\n");
  359. else if(AMD64 == Architecture) emit_out("LOAD_INTEGER\n");
  360. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R0 MEMORY\n");
  361. else if(AARCH64 == Architecture) emit_out("DEREF_X0\n");
  362. }
  363. }
  364. /*
  365. * primary-expr:
  366. * FAILURE
  367. * "String"
  368. * 'Char'
  369. * [0-9]*
  370. * [a-z,A-Z]*
  371. * ( expression )
  372. */
  373. void primary_expr_failure()
  374. {
  375. require(NULL != global_token, "hit EOF when expecting primary expression\n");
  376. line_error();
  377. file_print("Received ", stderr);
  378. file_print(global_token->s, stderr);
  379. file_print(" in primary_expr\n", stderr);
  380. exit(EXIT_FAILURE);
  381. }
  382. void primary_expr_string()
  383. {
  384. char* number_string = numerate_number(current_count);
  385. current_count = current_count + 1;
  386. if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&STRING_");
  387. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax &STRING_");
  388. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax &STRING_");
  389. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&STRING_");
  390. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&STRING_");
  391. uniqueID_out(function->s, number_string);
  392. /* The target */
  393. strings_list = emit(":STRING_", strings_list);
  394. strings_list = uniqueID(function->s, strings_list, number_string);
  395. /* catch case of just "foo" from segfaulting */
  396. require(NULL != global_token->next, "a string by itself is not valid C\n");
  397. /* Parse the string */
  398. if('"' != global_token->next->s[0])
  399. {
  400. strings_list = emit(parse_string(global_token->s), strings_list);
  401. global_token = global_token->next;
  402. }
  403. else
  404. {
  405. char* s = calloc(MAX_STRING, sizeof(char));
  406. /* prefix leading string */
  407. s[0] = '"';
  408. int i = 1;
  409. int j;
  410. while('"' == global_token->s[0])
  411. {
  412. /* Step past the leading '"' */
  413. j = 1;
  414. /* Copy the rest of the string as is */
  415. while(0 != global_token->s[j])
  416. {
  417. require(i < MAX_STRING, "concat string exceeded max string length\n");
  418. s[i] = global_token->s[j];
  419. i = i + 1;
  420. j = j + 1;
  421. }
  422. /* Move on to the next token */
  423. global_token = global_token->next;
  424. require(NULL != global_token, "multi-string null is not valid C\n");
  425. }
  426. /* Now use it */
  427. strings_list = emit(parse_string(s), strings_list);
  428. }
  429. }
  430. void primary_expr_char()
  431. {
  432. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADI R0 ");
  433. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
  434. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax %");
  435. else if(ARMV7L == Architecture) emit_out("!");
  436. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
  437. emit_out(numerate_number(escape_lookup(global_token->s + 1)));
  438. if(ARMV7L == Architecture) emit_out(" R0 LOADI8_ALWAYS");
  439. emit_out("\n");
  440. global_token = global_token->next;
  441. }
  442. void primary_expr_number()
  443. {
  444. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  445. {
  446. int size = fixup_int32(numerate_string(global_token->s));
  447. if((32767 > size) && (size > -32768))
  448. {
  449. emit_out("LOADI R0 ");
  450. emit_out(global_token->s);
  451. }
  452. else
  453. {
  454. emit_out("LOADR R0 4\nJUMP 4\n'");
  455. emit_out(number_to_hex(size, register_size));
  456. emit_out("'");
  457. }
  458. }
  459. else if(X86 == Architecture)
  460. {
  461. emit_out("LOAD_IMMEDIATE_eax %");
  462. emit_out(global_token->s);
  463. }
  464. else if(AMD64 == Architecture)
  465. {
  466. emit_out("LOAD_IMMEDIATE_rax %");
  467. emit_out(global_token->s);
  468. }
  469. else if(ARMV7L == Architecture)
  470. {
  471. emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
  472. emit_out(global_token->s);
  473. }
  474. else if(AARCH64 == Architecture)
  475. {
  476. emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
  477. emit_out(global_token->s);
  478. }
  479. emit_out("\n");
  480. global_token = global_token->next;
  481. }
  482. void primary_expr_variable()
  483. {
  484. char* s = global_token->s;
  485. global_token = global_token->next;
  486. struct token_list* a = sym_lookup(s, global_constant_list);
  487. if(NULL != a)
  488. {
  489. constant_load(a);
  490. return;
  491. }
  492. a= sym_lookup(s, function->locals);
  493. if(NULL != a)
  494. {
  495. variable_load(a);
  496. return;
  497. }
  498. a = sym_lookup(s, function->arguments);
  499. if(NULL != a)
  500. {
  501. variable_load(a);
  502. return;
  503. }
  504. a= sym_lookup(s, global_function_list);
  505. if(NULL != a)
  506. {
  507. function_load(a);
  508. return;
  509. }
  510. a = sym_lookup(s, global_symbol_list);
  511. if(NULL != a)
  512. {
  513. global_load(a);
  514. return;
  515. }
  516. line_error();
  517. file_print(s ,stderr);
  518. file_print(" is not a defined symbol\n", stderr);
  519. exit(EXIT_FAILURE);
  520. }
  521. void primary_expr();
  522. struct type* promote_type(struct type* a, struct type* b)
  523. {
  524. require(NULL != b, "impossible case 1 in promote_type\n");
  525. require(NULL != a, "impossible case 2 in promote_type\n");
  526. if(a == b) return a;
  527. struct type* i;
  528. for(i = global_types; NULL != i; i = i->next)
  529. {
  530. if(a->name == i->name) break;
  531. if(b->name == i->name) break;
  532. if(a->name == i->indirect->name) break;
  533. if(b->name == i->indirect->name) break;
  534. if(a->name == i->indirect->indirect->name) break;
  535. if(b->name == i->indirect->indirect->name) break;
  536. }
  537. require(NULL != i, "impossible case 3 in promote_type\n");
  538. return i;
  539. }
  540. void common_recursion(FUNCTION f)
  541. {
  542. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_common_recursion\n");
  543. else if(X86 == Architecture) emit_out("PUSH_eax\t#_common_recursion\n");
  544. else if(AMD64 == Architecture) emit_out("PUSH_RAX\t#_common_recursion\n");
  545. else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_common_recursion\n");
  546. else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_common_recursion\n");
  547. struct type* last_type = current_target;
  548. global_token = global_token->next;
  549. require(NULL != global_token, "Recieved EOF in common_recursion\n");
  550. f();
  551. current_target = promote_type(current_target, last_type);
  552. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _common_recursion\n");
  553. else if(X86 == Architecture) emit_out("POP_ebx\t# _common_recursion\n");
  554. else if(AMD64 == Architecture) emit_out("POP_RBX\t# _common_recursion\n");
  555. else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _common_recursion\n");
  556. else if(AARCH64 == Architecture) emit_out("POP_X1\t# _common_recursion\n");
  557. }
  558. void general_recursion(FUNCTION f, char* s, char* name, FUNCTION iterate)
  559. {
  560. require(NULL != global_token, "Recieved EOF in general_recursion\n");
  561. if(match(name, global_token->s))
  562. {
  563. common_recursion(f);
  564. emit_out(s);
  565. iterate();
  566. }
  567. }
  568. void arithmetic_recursion(FUNCTION f, char* s1, char* s2, char* name, FUNCTION iterate)
  569. {
  570. require(NULL != global_token, "Recieved EOF in arithmetic_recursion\n");
  571. if(match(name, global_token->s))
  572. {
  573. common_recursion(f);
  574. if(NULL == current_target)
  575. {
  576. emit_out(s1);
  577. }
  578. else if(current_target->is_signed)
  579. {
  580. emit_out(s1);
  581. }
  582. else
  583. {
  584. emit_out(s2);
  585. }
  586. iterate();
  587. }
  588. }
  589. int ceil_log2(int a)
  590. {
  591. int result = 0;
  592. if((a & (a - 1)) == 0)
  593. {
  594. result = -1;
  595. }
  596. while(a > 0)
  597. {
  598. result = result + 1;
  599. a = a >> 1;
  600. }
  601. if(ARMV7L == Architecture) return (result >> 1);
  602. return result;
  603. }
  604. /*
  605. * postfix-expr:
  606. * primary-expr
  607. * postfix-expr [ expression ]
  608. * postfix-expr ( expression-list-opt )
  609. * postfix-expr -> member
  610. */
  611. struct type* lookup_member(struct type* parent, char* name);
  612. void postfix_expr_arrow()
  613. {
  614. emit_out("# looking up offset\n");
  615. global_token = global_token->next;
  616. require(NULL != global_token, "naked -> not allowed\n");
  617. struct type* i = lookup_member(current_target, global_token->s);
  618. current_target = i->type;
  619. global_token = global_token->next;
  620. require(NULL != global_token, "Unterminated -> expression not allowed\n");
  621. if(0 != i->offset)
  622. {
  623. emit_out("# -> offset calculation\n");
  624. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  625. {
  626. emit_out("ADDUI R0 R0 ");
  627. emit_out(numerate_number(i->offset));
  628. emit_out("\n");
  629. }
  630. else if(X86 == Architecture)
  631. {
  632. emit_out("LOAD_IMMEDIATE_ebx %");
  633. emit_out(numerate_number(i->offset));
  634. emit_out("\nADD_ebx_to_eax\n");
  635. }
  636. else if(AMD64 == Architecture)
  637. {
  638. emit_out("LOAD_IMMEDIATE_rbx %");
  639. emit_out(numerate_number(i->offset));
  640. emit_out("\nADD_rbx_to_rax\n");
  641. }
  642. else if(ARMV7L == Architecture)
  643. {
  644. emit_out("!0 R1 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
  645. emit_out(numerate_number(i->offset));
  646. emit_out("\n'0' R0 R0 ADD R1 ARITH2_ALWAYS\n");
  647. }
  648. else if(AARCH64 == Architecture)
  649. {
  650. emit_out("LOAD_W1_AHEAD\nSKIP_32_DATA\n%");
  651. emit_out(numerate_number(i->offset));
  652. emit_out("\nADD_X0_X1_X0\n");
  653. }
  654. }
  655. if((!match("=", global_token->s) && (register_size >= i->size)))
  656. {
  657. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOAD R0 R0 0\n");
  658. else if(X86 == Architecture) emit_out("LOAD_INTEGER\n");
  659. else if(AMD64 == Architecture) emit_out("LOAD_INTEGER\n");
  660. else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R0 MEMORY\n");
  661. else if(AARCH64 == Architecture) emit_out("DEREF_X0\n");
  662. }
  663. }
  664. void postfix_expr_array()
  665. {
  666. struct type* array = current_target;
  667. common_recursion(expression);
  668. current_target = array;
  669. require(NULL != current_target, "Arrays only apply to variables\n");
  670. char* assign;
  671. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) assign = "LOAD R0 R0 0\n";
  672. else if(X86 == Architecture) assign = "LOAD_INTEGER\n";
  673. else if(AMD64 == Architecture) assign = "LOAD_INTEGER\n";
  674. else if(ARMV7L == Architecture) assign = "!0 R0 LOAD32 R0 MEMORY\n";
  675. else if(AARCH64 == Architecture) assign = "DEREF_X0\n";
  676. /* Add support for Ints */
  677. if(match("char*", current_target->name))
  678. {
  679. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) assign = "LOAD8 R0 R0 0\n";
  680. else if(X86 == Architecture) assign = "LOAD_BYTE\n";
  681. else if(AMD64 == Architecture) assign = "LOAD_BYTE\n";
  682. else if(ARMV7L == Architecture) assign = "!0 R0 LOAD8 R0 MEMORY\n";
  683. else if(AARCH64 == Architecture) assign = "DEREF_X0_BYTE\n";
  684. }
  685. else
  686. {
  687. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("SALI R0 ");
  688. else if(X86 == Architecture) emit_out("SAL_eax_Immediate8 !");
  689. else if(AMD64 == Architecture) emit_out("SAL_rax_Immediate8 !");
  690. else if(ARMV7L == Architecture) emit_out("'0' R0 R0 '");
  691. else if(AARCH64 == Architecture) emit_out("LOAD_W2_AHEAD\nSKIP_32_DATA\n%");
  692. emit_out(numerate_number(ceil_log2(current_target->indirect->size)));
  693. if(ARMV7L == Architecture) emit_out("' MOVE_ALWAYS");
  694. else if(AARCH64 == Architecture) emit_out("\nLSHIFT_X0_X0_X2");
  695. emit_out("\n");
  696. }
  697. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("ADD R0 R0 R1\n");
  698. else if(X86 == Architecture) emit_out("ADD_ebx_to_eax\n");
  699. else if(AMD64 == Architecture) emit_out("ADD_rbx_to_rax\n");
  700. else if(ARMV7L == Architecture) emit_out("'0' R0 R0 ADD R1 ARITH2_ALWAYS\n");
  701. else if(AARCH64 == Architecture) emit_out("ADD_X0_X1_X0\n");
  702. require_match("ERROR in postfix_expr\nMissing ]\n", "]");
  703. if(match("=", global_token->s))
  704. {
  705. assign = "";
  706. }
  707. emit_out(assign);
  708. }
  709. /*
  710. * unary-expr:
  711. * postfix-expr
  712. * - postfix-expr
  713. * !postfix-expr
  714. * sizeof ( type )
  715. */
  716. struct type* type_name();
  717. void unary_expr_sizeof()
  718. {
  719. global_token = global_token->next;
  720. require(NULL != global_token, "Recieved EOF when starting sizeof\n");
  721. require_match("ERROR in unary_expr\nMissing (\n", "(");
  722. struct type* a = type_name();
  723. require_match("ERROR in unary_expr\nMissing )\n", ")");
  724. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADUI R0 ");
  725. else if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax %");
  726. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax %");
  727. else if(ARMV7L == Architecture) emit_out("!");
  728. else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
  729. emit_out(numerate_number(a->size));
  730. if(ARMV7L == Architecture) emit_out(" R0 LOADI8_ALWAYS");
  731. emit_out("\n");
  732. }
  733. void postfix_expr_stub()
  734. {
  735. require(NULL != global_token, "Unexpected EOF, improperly terminated primary expression\n");
  736. if(match("[", global_token->s))
  737. {
  738. postfix_expr_array();
  739. postfix_expr_stub();
  740. }
  741. if(match("->", global_token->s))
  742. {
  743. postfix_expr_arrow();
  744. postfix_expr_stub();
  745. }
  746. }
  747. void postfix_expr()
  748. {
  749. primary_expr();
  750. postfix_expr_stub();
  751. }
  752. /*
  753. * additive-expr:
  754. * postfix-expr
  755. * additive-expr * postfix-expr
  756. * additive-expr / postfix-expr
  757. * additive-expr % postfix-expr
  758. * additive-expr + postfix-expr
  759. * additive-expr - postfix-expr
  760. * additive-expr << postfix-expr
  761. * additive-expr >> postfix-expr
  762. */
  763. void additive_expr_stub()
  764. {
  765. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  766. {
  767. arithmetic_recursion(postfix_expr, "ADD R0 R1 R0\n", "ADDU R0 R1 R0\n", "+", additive_expr_stub);
  768. arithmetic_recursion(postfix_expr, "SUB R0 R1 R0\n", "SUBU R0 R1 R0\n", "-", additive_expr_stub);
  769. arithmetic_recursion(postfix_expr, "MUL R0 R1 R0\n", "MULU R0 R1 R0\n", "*", additive_expr_stub);
  770. arithmetic_recursion(postfix_expr, "DIV R0 R1 R0\n", "DIVU R0 R1 R0\n", "/", additive_expr_stub);
  771. arithmetic_recursion(postfix_expr, "MOD R0 R1 R0\n", "MODU R0 R1 R0\n", "%", additive_expr_stub);
  772. arithmetic_recursion(postfix_expr, "SAL R0 R1 R0\n", "SL0 R0 R1 R0\n", "<<", additive_expr_stub);
  773. arithmetic_recursion(postfix_expr, "SAR R0 R1 R0\n", "SR0 R0 R1 R0\n", ">>", additive_expr_stub);
  774. }
  775. else if(X86 == Architecture)
  776. {
  777. arithmetic_recursion(postfix_expr, "ADD_ebx_to_eax\n", "ADD_ebx_to_eax\n", "+", additive_expr_stub);
  778. arithmetic_recursion(postfix_expr, "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", "-", additive_expr_stub);
  779. arithmetic_recursion(postfix_expr, "MULTIPLYS_eax_by_ebx_into_eax\n", "MULTIPLY_eax_by_ebx_into_eax\n", "*", additive_expr_stub);
  780. arithmetic_recursion(postfix_expr, "XCHG_eax_ebx\nCDTQ\nDIVIDES_eax_by_ebx_into_eax\n", "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\n", "/", additive_expr_stub);
  781. arithmetic_recursion(postfix_expr, "XCHG_eax_ebx\nCDTQ\nMODULUSS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n", "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n", "%", additive_expr_stub);
  782. arithmetic_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAL_eax_cl\n", "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSHL_eax_cl\n", "<<", additive_expr_stub);
  783. arithmetic_recursion(postfix_expr, "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAR_eax_cl\n", "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSHR_eax_cl\n", ">>", additive_expr_stub);
  784. }
  785. else if(AMD64 == Architecture)
  786. {
  787. arithmetic_recursion(postfix_expr, "ADD_rbx_to_rax\n", "ADD_rbx_to_rax\n", "+", additive_expr_stub);
  788. arithmetic_recursion(postfix_expr, "SUBTRACT_rax_from_rbx_into_rbx\nMOVE_rbx_to_rax\n", "SUBTRACT_rax_from_rbx_into_rbx\nMOVE_rbx_to_rax\n", "-", additive_expr_stub);
  789. arithmetic_recursion(postfix_expr, "MULTIPLYS_rax_by_rbx_into_rax\n", "MULTIPLY_rax_by_rbx_into_rax\n", "*", additive_expr_stub);
  790. arithmetic_recursion(postfix_expr, "XCHG_rax_rbx\nCQTO\nDIVIDES_rax_by_rbx_into_rax\n", "XCHG_rax_rbx\nLOAD_IMMEDIATE_rdx %0\nDIVIDE_rax_by_rbx_into_rax\n", "/", additive_expr_stub);
  791. arithmetic_recursion(postfix_expr, "XCHG_rax_rbx\nCQTO\nMODULUSS_rax_from_rbx_into_rbx\nMOVE_rdx_to_rax\n", "XCHG_rax_rbx\nLOAD_IMMEDIATE_rdx %0\nMODULUS_rax_from_rbx_into_rbx\nMOVE_rdx_to_rax\n", "%", additive_expr_stub);
  792. arithmetic_recursion(postfix_expr, "COPY_rax_to_rcx\nCOPY_rbx_to_rax\nSAL_rax_cl\n", "COPY_rax_to_rcx\nCOPY_rbx_to_rax\nSHL_rax_cl\n", "<<", additive_expr_stub);
  793. arithmetic_recursion(postfix_expr, "COPY_rax_to_rcx\nCOPY_rbx_to_rax\nSAR_rax_cl\n", "COPY_rax_to_rcx\nCOPY_rbx_to_rax\nSHR_rax_cl\n", ">>", additive_expr_stub);
  794. }
  795. else if(ARMV7L == Architecture)
  796. {
  797. arithmetic_recursion(postfix_expr, "'0' R0 R0 ADD R1 ARITH2_ALWAYS\n", "'0' R0 R0 ADD R1 ARITH2_ALWAYS\n", "+", additive_expr_stub);
  798. arithmetic_recursion(postfix_expr, "'0' R0 R0 SUB R1 ARITH2_ALWAYS\n", "'0' R0 R0 SUB R1 ARITH2_ALWAYS\n", "-", additive_expr_stub);
  799. arithmetic_recursion(postfix_expr, "'9' R0 '0' R1 MULS R0 ARITH2_ALWAYS\n", "'9' R0 '0' R1 MUL R0 ARITH2_ALWAYS\n", "*", additive_expr_stub);
  800. arithmetic_recursion(postfix_expr, "{LR} PUSH_ALWAYS\n^~divides CALL_ALWAYS\n{LR} POP_ALWAYS\n", "{LR} PUSH_ALWAYS\n^~divide CALL_ALWAYS\n{LR} POP_ALWAYS\n", "/", additive_expr_stub);
  801. arithmetic_recursion(postfix_expr, "{LR} PUSH_ALWAYS\n^~moduluss CALL_ALWAYS\n{LR} POP_ALWAYS\n", "{LR} PUSH_ALWAYS\n^~modulus CALL_ALWAYS\n{LR} POP_ALWAYS\n", "%", additive_expr_stub);
  802. arithmetic_recursion(postfix_expr, "LEFT R1 R0 R0 SHIFT AUX_ALWAYS\n", "LEFT R1 R0 R0 SHIFT AUX_ALWAYS\n", "<<", additive_expr_stub);
  803. arithmetic_recursion(postfix_expr, "ARITH_RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n", "RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n", ">>", additive_expr_stub);
  804. }
  805. else if(AARCH64 == Architecture)
  806. {
  807. general_recursion(postfix_expr, "ADD_X0_X1_X0\n", "+", additive_expr_stub);
  808. general_recursion(postfix_expr, "SUB_X0_X1_X0\n", "-", additive_expr_stub);
  809. general_recursion(postfix_expr, "MUL_X0_X1_X0\n", "*", additive_expr_stub);
  810. arithmetic_recursion(postfix_expr, "SDIV_X0_X1_X0\n", "UDIV_X0_X1_X0\n", "/", additive_expr_stub);
  811. arithmetic_recursion(postfix_expr, "SDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n", "UDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n", "%", additive_expr_stub);
  812. general_recursion(postfix_expr, "LSHIFT_X0_X1_X0\n", "<<", additive_expr_stub);
  813. arithmetic_recursion(postfix_expr, "ARITH_RSHIFT_X0_X1_X0\n", "LOGICAL_RSHIFT_X0_X1_X0\n", ">>", additive_expr_stub);
  814. }
  815. }
  816. void additive_expr()
  817. {
  818. postfix_expr();
  819. additive_expr_stub();
  820. }
  821. /*
  822. * relational-expr:
  823. * additive_expr
  824. * relational-expr < additive_expr
  825. * relational-expr <= additive_expr
  826. * relational-expr >= additive_expr
  827. * relational-expr > additive_expr
  828. */
  829. void relational_expr_stub()
  830. {
  831. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  832. {
  833. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.L R0 R0 1\n", "CMPU R0 R1 R0\nSET.L R0 R0 1\n", "<", relational_expr_stub);
  834. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.LE R0 R0 1\n", "CMPU R0 R1 R0\nSET.LE R0 R0 1\n", "<=", relational_expr_stub);
  835. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.GE R0 R0 1\n", "CMPU R0 R1 R0\nSET.GE R0 R0 1\n", ">=", relational_expr_stub);
  836. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.G R0 R0 1\n", "CMPU R0 R1 R0\nSET.G R0 R0 1\n", ">", relational_expr_stub);
  837. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.E R0 R0 1\n", "CMPU R0 R1 R0\nSET.E R0 R0 1\n", "==", relational_expr_stub);
  838. arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.NE R0 R0 1\n", "CMPU R0 R1 R0\nSET.NE R0 R0 1\n", "!=", relational_expr_stub);
  839. }
  840. else if(X86 == Architecture)
  841. {
  842. arithmetic_recursion(additive_expr, "CMP\nSETL\nMOVEZBL\n", "CMP\nSETB\nMOVEZBL\n", "<", relational_expr_stub);
  843. arithmetic_recursion(additive_expr, "CMP\nSETLE\nMOVEZBL\n", "CMP\nSETBE\nMOVEZBL\n", "<=", relational_expr_stub);
  844. arithmetic_recursion(additive_expr, "CMP\nSETGE\nMOVEZBL\n", "CMP\nSETAE\nMOVEZBL\n", ">=", relational_expr_stub);
  845. arithmetic_recursion(additive_expr, "CMP\nSETG\nMOVEZBL\n", "CMP\nSETA\nMOVEZBL\n", ">", relational_expr_stub);
  846. general_recursion(additive_expr, "CMP\nSETE\nMOVEZBL\n", "==", relational_expr_stub);
  847. general_recursion(additive_expr, "CMP\nSETNE\nMOVEZBL\n", "!=", relational_expr_stub);
  848. }
  849. else if(AMD64 == Architecture)
  850. {
  851. arithmetic_recursion(additive_expr, "CMP\nSETL\nMOVEZX\n", "CMP\nSETB\nMOVEZX\n", "<", relational_expr_stub);
  852. arithmetic_recursion(additive_expr, "CMP\nSETLE\nMOVEZX\n", "CMP\nSETBE\nMOVEZX\n", "<=", relational_expr_stub);
  853. arithmetic_recursion(additive_expr, "CMP\nSETGE\nMOVEZX\n", "CMP\nSETAE\nMOVEZX\n", ">=", relational_expr_stub);
  854. arithmetic_recursion(additive_expr, "CMP\nSETG\nMOVEZX\n", "CMP\nSETA\nMOVEZX\n", ">", relational_expr_stub);
  855. general_recursion(additive_expr, "CMP\nSETE\nMOVEZX\n", "==", relational_expr_stub);
  856. general_recursion(additive_expr, "CMP\nSETNE\nMOVEZX\n", "!=", relational_expr_stub);
  857. }
  858. else if(ARMV7L == Architecture)
  859. {
  860. arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_L\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LO\n", "<", relational_expr_stub);
  861. arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LE\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LS\n", "<=", relational_expr_stub);
  862. arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_GE\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_HS\n", ">=", relational_expr_stub);
  863. arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_G\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_HI\n", ">", relational_expr_stub);
  864. general_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_EQUAL\n", "==", relational_expr_stub);
  865. general_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_NE\n", "!=", relational_expr_stub);
  866. }
  867. else if(AARCH64 == Architecture)
  868. {
  869. arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LT\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LO\nSET_X0_TO_0\n", "<", relational_expr_stub);
  870. arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LE\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LS\nSET_X0_TO_0\n", "<=", relational_expr_stub);
  871. arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_GE\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_HS\nSET_X0_TO_0\n", ">=", relational_expr_stub);
  872. arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_GT\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_HI\nSET_X0_TO_0\n", ">", relational_expr_stub);
  873. general_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_EQ\nSET_X0_TO_0\n", "==", relational_expr_stub);
  874. general_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_NE\nSET_X0_TO_0\n", "!=", relational_expr_stub);
  875. }
  876. }
  877. void relational_expr()
  878. {
  879. additive_expr();
  880. relational_expr_stub();
  881. }
  882. /*
  883. * bitwise-expr:
  884. * relational-expr
  885. * bitwise-expr & bitwise-expr
  886. * bitwise-expr && bitwise-expr
  887. * bitwise-expr | bitwise-expr
  888. * bitwise-expr || bitwise-expr
  889. * bitwise-expr ^ bitwise-expr
  890. */
  891. void bitwise_expr_stub()
  892. {
  893. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
  894. {
  895. general_recursion(relational_expr, "AND R0 R0 R1\n", "&", bitwise_expr_stub);
  896. general_recursion(relational_expr, "AND R0 R0 R1\n", "&&", bitwise_expr_stub);
  897. general_recursion(relational_expr, "OR R0 R0 R1\n", "|", bitwise_expr_stub);
  898. general_recursion(relational_expr, "OR R0 R0 R1\n", "||", bitwise_expr_stub);
  899. general_recursion(relational_expr, "XOR R0 R0 R1\n", "^", bitwise_expr_stub);
  900. }
  901. else if(X86 == Architecture)
  902. {
  903. general_recursion(relational_expr, "AND_eax_ebx\n", "&", bitwise_expr_stub);
  904. general_recursion(relational_expr, "AND_eax_ebx\n", "&&", bitwise_expr_stub);
  905. general_recursion(relational_expr, "OR_eax_ebx\n", "|", bitwise_expr_stub);
  906. general_recursion(relational_expr, "OR_eax_ebx\n", "||", bitwise_expr_stub);
  907. general_recursion(relational_expr, "XOR_ebx_eax_into_eax\n", "^", bitwise_expr_stub);
  908. }
  909. else if(AMD64 == Architecture)
  910. {
  911. general_recursion(relational_expr, "AND_rax_rbx\n", "&", bitwise_expr_stub);
  912. general_recursion(relational_expr, "AND_rax_rbx\n", "&&", bitwise_expr_stub);
  913. general_recursion(relational_expr, "OR_rax_rbx\n", "|", bitwise_expr_stub);
  914. general_recursion(relational_expr, "OR_rax_rbx\n", "||", bitwise_expr_stub);
  915. general_recursion(relational_expr, "XOR_rbx_rax_into_rax\n", "^", bitwise_expr_stub);
  916. }
  917. else if(ARMV7L == Architecture)
  918. {
  919. general_recursion(relational_expr, "NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS\n", "&", bitwise_expr_stub);
  920. general_recursion(relational_expr, "NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS\n", "&&", bitwise_expr_stub);
  921. general_recursion(relational_expr, "NO_SHIFT R0 R0 OR R1 AUX_ALWAYS\n", "|", bitwise_expr_stub);
  922. general_recursion(relational_expr, "NO_SHIFT R0 R0 OR R1 AUX_ALWAYS\n", "||", bitwise_expr_stub);
  923. general_recursion(relational_expr, "'0' R0 R0 XOR R1 ARITH2_ALWAYS\n", "^", bitwise_expr_stub);
  924. }
  925. else if(AARCH64 == Architecture)
  926. {
  927. general_recursion(relational_expr, "AND_X0_X1_X0\n", "&", bitwise_expr_stub);
  928. general_recursion(relational_expr, "AND_X0_X1_X0\n", "&&", bitwise_expr_stub);
  929. general_recursion(relational_expr, "OR_X0_X1_X0\n", "|", bitwise_expr_stub);
  930. general_recursion(relational_expr, "OR_X0_X1_X0\n", "||", bitwise_expr_stub);
  931. general_recursion(relational_expr, "XOR_X0_X1_X0\n", "^", bitwise_expr_stub);
  932. }
  933. }
  934. void bitwise_expr()
  935. {
  936. relational_expr();
  937. bitwise_expr_stub();
  938. }
  939. /*
  940. * expression:
  941. * bitwise-or-expr
  942. * bitwise-or-expr = expression
  943. */
  944. void primary_expr()
  945. {
  946. require(NULL != global_token, "Recieved EOF where primary expression expected\n");
  947. if(match("&", global_token->s))
  948. {
  949. Address_of = TRUE;
  950. global_token = global_token->next;
  951. require(NULL != global_token, "Recieved EOF after & where primary expression expected\n");
  952. }
  953. else
  954. {
  955. Address_of = FALSE;
  956. }
  957. if(match("sizeof", global_token->s)) unary_expr_sizeof();
  958. else if('-' == global_token->s[0])
  959. {
  960. if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax %0\n");
  961. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax %0\n");
  962. else if(ARMV7L == Architecture) emit_out("!0 R0 LOADI8_ALWAYS\n");
  963. else if(AARCH64 == Architecture) emit_out("SET_X0_TO_0\n");
  964. common_recursion(primary_expr);
  965. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("NEG R0 R0\n");
  966. else if(X86 == Architecture) emit_out("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n");
  967. else if(AMD64 == Architecture) emit_out("SUBTRACT_rax_from_rbx_into_rbx\nMOVE_rbx_to_rax\n");
  968. else if(ARMV7L == Architecture) emit_out("'0' R0 R0 SUB R1 ARITH2_ALWAYS\n");
  969. else if(AARCH64 == Architecture) emit_out("SUB_X0_X1_X0\n");
  970. }
  971. else if('!' == global_token->s[0])
  972. {
  973. if(X86 == Architecture) emit_out("LOAD_IMMEDIATE_eax %1\n");
  974. else if(AMD64 == Architecture) emit_out("LOAD_IMMEDIATE_rax %1\n");
  975. else if(ARMV7L == Architecture) emit_out("!1 R0 LOADI8_ALWAYS\n");
  976. else if(AARCH64 == Architecture) emit_out("SET_X0_TO_1\n");
  977. common_recursion(postfix_expr);
  978. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("XORI R0 R0 1\n");
  979. else if(X86 == Architecture) emit_out("XOR_ebx_eax_into_eax\n");
  980. else if(AMD64 == Architecture) emit_out("XOR_rbx_rax_into_rax\n");
  981. else if(ARMV7L == Architecture) emit_out("'0' R0 R0 XOR R1 ARITH2_ALWAYS\n");
  982. else if(AARCH64 == Architecture) emit_out("XOR_X0_X1_X0\n");
  983. }
  984. else if('~' == global_token->s[0])
  985. {
  986. common_recursion(postfix_expr);
  987. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("NOT R0 R0\n");
  988. else if(X86 == Architecture) emit_out("NOT_eax\n");
  989. else if(AMD64 == Architecture) emit_out("NOT_rax\n");
  990. else if(ARMV7L == Architecture) emit_out("'0' R0 R0 MVN_ALWAYS\n");
  991. else if(AARCH64 == Architecture) emit_out("MVN_X0\n");
  992. }
  993. else if(global_token->s[0] == '(')
  994. {
  995. global_token = global_token->next;
  996. expression();
  997. require_match("Error in Primary expression\nDidn't get )\n", ")");
  998. }
  999. else if(global_token->s[0] == '\'') primary_expr_char();
  1000. else if(global_token->s[0] == '"') primary_expr_string();
  1001. else if(in_set(global_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")) primary_expr_variable();
  1002. else if(in_set(global_token->s[0], "0123456789")) primary_expr_number();
  1003. else primary_expr_failure();
  1004. }
  1005. void expression()
  1006. {
  1007. bitwise_expr();
  1008. if(match("=", global_token->s))
  1009. {
  1010. char* store = "";
  1011. if(!match("]", global_token->prev->s) || !match("char*", current_target->name))
  1012. {
  1013. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) store = "STORE R0 R1 0\n";
  1014. else if(X86 == Architecture) store = "STORE_INTEGER\n";
  1015. else if(AMD64 == Architecture) store = "STORE_INTEGER\n";
  1016. else if(ARMV7L == Architecture) store = "!0 R0 STORE32 R1 MEMORY\n";
  1017. else if(AARCH64 == Architecture) store = "STR_X0_[X1]\n";
  1018. }
  1019. else
  1020. {
  1021. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) store = "STORE8 R0 R1 0\n";
  1022. else if(X86 == Architecture) store = "STORE_CHAR\n";
  1023. else if(AMD64 == Architecture) store = "STORE_CHAR\n";
  1024. else if(ARMV7L == Architecture) store = "!0 R0 STORE8 R1 MEMORY\n";
  1025. else if(AARCH64 == Architecture) store = "STR_BYTE_W0_[X1]\n";
  1026. }
  1027. common_recursion(expression);
  1028. emit_out(store);
  1029. current_target = integer;
  1030. }
  1031. }
  1032. /* Process local variable */
  1033. void collect_local()
  1034. {
  1035. if(NULL != break_target_func)
  1036. {
  1037. file_print("Local variable initialized inside of loop in file: ", stderr);
  1038. line_error();
  1039. file_print("\nMove the variable outside of the loop to resolve\n", stderr);
  1040. file_print("Otherwise the binary will segfault while running\n", stderr);
  1041. exit(EXIT_FAILURE);
  1042. }
  1043. struct type* type_size = type_name();
  1044. struct token_list* a = sym_declare(global_token->s, type_size, function->locals);
  1045. if(match("main", function->s) && (NULL == function->locals))
  1046. {
  1047. if(KNIGHT_NATIVE == Architecture) a->depth = register_size;
  1048. else if(KNIGHT_POSIX == Architecture) a->depth = 20;
  1049. else if(X86 == Architecture) a->depth = -20;
  1050. else if(AMD64 == Architecture) a->depth = -40;
  1051. else if(ARMV7L == Architecture) a->depth = 16;
  1052. else if(AARCH64 == Architecture) a->depth = 32; /* argc, argv, envp and the local (8 bytes each) */
  1053. }
  1054. else if((NULL == function->arguments) && (NULL == function->locals))
  1055. {
  1056. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = register_size;
  1057. else if(X86 == Architecture) a->depth = -8;
  1058. else if(AMD64 == Architecture) a->depth = -16;
  1059. else if(ARMV7L == Architecture) a->depth = 8;
  1060. else if(AARCH64 == Architecture) a->depth = register_size;
  1061. }
  1062. else if(NULL == function->locals)
  1063. {
  1064. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->arguments->depth + 8;
  1065. else if(X86 == Architecture) a->depth = function->arguments->depth - 8;
  1066. else if(AMD64 == Architecture) a->depth = function->arguments->depth - 16;
  1067. else if(ARMV7L == Architecture) a->depth = function->arguments->depth + 8;
  1068. else if(AARCH64 == Architecture) a->depth = function->arguments->depth + register_size;
  1069. }
  1070. else
  1071. {
  1072. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->locals->depth + register_size;
  1073. else if(X86 == Architecture) a->depth = function->locals->depth - register_size;
  1074. else if(AMD64 == Architecture) a->depth = function->locals->depth - register_size;
  1075. else if(ARMV7L == Architecture) a->depth = function->locals->depth + register_size;
  1076. else if(AARCH64 == Architecture) a->depth = function->locals->depth + register_size;
  1077. }
  1078. function->locals = a;
  1079. emit_out("# Defining local ");
  1080. emit_out(global_token->s);
  1081. emit_out("\n");
  1082. global_token = global_token->next;
  1083. require(NULL != global_token, "incomplete local missing name\n");
  1084. if(match("=", global_token->s))
  1085. {
  1086. global_token = global_token->next;
  1087. require(NULL != global_token, "incomplete local assignment\n");
  1088. expression();
  1089. }
  1090. require_match("ERROR in collect_local\nMissing ;\n", ";");
  1091. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#");
  1092. else if(X86 == Architecture) emit_out("PUSH_eax\t#");
  1093. else if(AMD64 == Architecture) emit_out("PUSH_RAX\t#");
  1094. else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#");
  1095. else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#");
  1096. emit_out(a->s);
  1097. emit_out("\n");
  1098. }
  1099. void statement();
  1100. /* Evaluate if statements */
  1101. void process_if()
  1102. {
  1103. char* number_string = numerate_number(current_count);
  1104. current_count = current_count + 1;
  1105. emit_out("# IF_");
  1106. uniqueID_out(function->s, number_string);
  1107. global_token = global_token->next;
  1108. require_match("ERROR in process_if\nMISSING (\n", "(");
  1109. expression();
  1110. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @ELSE_");
  1111. else if(X86 == Architecture) emit_out("TEST\nJUMP_EQ %ELSE_");
  1112. else if(AMD64 == Architecture) emit_out("TEST\nJUMP_EQ %ELSE_");
  1113. else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~ELSE_");
  1114. else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&ELSE_");
  1115. uniqueID_out(function->s, number_string);
  1116. if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\n");
  1117. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1118. require_match("ERROR in process_if\nMISSING )\n", ")");
  1119. statement();
  1120. require(NULL != global_token, "Reached EOF inside of function\n");
  1121. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @_END_IF_");
  1122. else if(X86 == Architecture) emit_out("JUMP %_END_IF_");
  1123. else if(AMD64 == Architecture) emit_out("JUMP %_END_IF_");
  1124. else if(ARMV7L == Architecture) emit_out("^~_END_IF_");
  1125. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&_END_IF_");
  1126. uniqueID_out(function->s, number_string);
  1127. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
  1128. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1129. emit_out(":ELSE_");
  1130. uniqueID_out(function->s, number_string);
  1131. if(match("else", global_token->s))
  1132. {
  1133. global_token = global_token->next;
  1134. require(NULL != global_token, "Recieved EOF where an else statement expected\n");
  1135. statement();
  1136. require(NULL != global_token, "Reached EOF inside of function\n");
  1137. }
  1138. emit_out(":_END_IF_");
  1139. uniqueID_out(function->s, number_string);
  1140. }
  1141. void process_for()
  1142. {
  1143. struct token_list* nested_locals = break_frame;
  1144. char* nested_break_head = break_target_head;
  1145. char* nested_break_func = break_target_func;
  1146. char* nested_break_num = break_target_num;
  1147. char* nested_continue_head = continue_target_head;
  1148. char* number_string = numerate_number(current_count);
  1149. current_count = current_count + 1;
  1150. break_target_head = "FOR_END_";
  1151. continue_target_head = "FOR_ITER_";
  1152. break_target_num = number_string;
  1153. break_frame = function->locals;
  1154. break_target_func = function->s;
  1155. emit_out("# FOR_initialization_");
  1156. uniqueID_out(function->s, number_string);
  1157. global_token = global_token->next;
  1158. require_match("ERROR in process_for\nMISSING (\n", "(");
  1159. if(!match(";",global_token->s))
  1160. {
  1161. expression();
  1162. }
  1163. emit_out(":FOR_");
  1164. uniqueID_out(function->s, number_string);
  1165. require_match("ERROR in process_for\nMISSING ;1\n", ";");
  1166. expression();
  1167. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @FOR_END_");
  1168. else if(X86 == Architecture) emit_out("TEST\nJUMP_EQ %FOR_END_");
  1169. else if(AMD64 == Architecture) emit_out("TEST\nJUMP_EQ %FOR_END_");
  1170. else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~FOR_END_");
  1171. else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_END_");
  1172. uniqueID_out(function->s, number_string);
  1173. if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\n");
  1174. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1175. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_THEN_");
  1176. else if(X86 == Architecture) emit_out("JUMP %FOR_THEN_");
  1177. else if(AMD64 == Architecture) emit_out("JUMP %FOR_THEN_");
  1178. else if(ARMV7L == Architecture) emit_out("^~FOR_THEN_");
  1179. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_THEN_");
  1180. uniqueID_out(function->s, number_string);
  1181. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
  1182. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1183. emit_out(":FOR_ITER_");
  1184. uniqueID_out(function->s, number_string);
  1185. require_match("ERROR in process_for\nMISSING ;2\n", ";");
  1186. expression();
  1187. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_");
  1188. else if(X86 == Architecture) emit_out("JUMP %FOR_");
  1189. else if(AMD64 == Architecture) emit_out("JUMP %FOR_");
  1190. else if(ARMV7L == Architecture) emit_out("^~FOR_");
  1191. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_");
  1192. uniqueID_out(function->s, number_string);
  1193. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
  1194. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1195. emit_out(":FOR_THEN_");
  1196. uniqueID_out(function->s, number_string);
  1197. require_match("ERROR in process_for\nMISSING )\n", ")");
  1198. statement();
  1199. require(NULL != global_token, "Reached EOF inside of function\n");
  1200. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_ITER_");
  1201. else if(X86 == Architecture) emit_out("JUMP %FOR_ITER_");
  1202. else if(AMD64 == Architecture) emit_out("JUMP %FOR_ITER_");
  1203. else if(ARMV7L == Architecture) emit_out("^~FOR_ITER_");
  1204. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_ITER_");
  1205. uniqueID_out(function->s, number_string);
  1206. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
  1207. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1208. emit_out(":FOR_END_");
  1209. uniqueID_out(function->s, number_string);
  1210. break_target_head = nested_break_head;
  1211. break_target_func = nested_break_func;
  1212. break_target_num = nested_break_num;
  1213. continue_target_head = nested_continue_head;
  1214. break_frame = nested_locals;
  1215. }
  1216. /* Process Assembly statements */
  1217. void process_asm()
  1218. {
  1219. global_token = global_token->next;
  1220. require_match("ERROR in process_asm\nMISSING (\n", "(");
  1221. while('"' == global_token->s[0])
  1222. {
  1223. emit_out((global_token->s + 1));
  1224. emit_out("\n");
  1225. global_token = global_token->next;
  1226. require(NULL != global_token, "Recieved EOF inside asm statement\n");
  1227. }
  1228. require_match("ERROR in process_asm\nMISSING )\n", ")");
  1229. require_match("ERROR in process_asm\nMISSING ;\n", ";");
  1230. }
  1231. /* Process do while loops */
  1232. void process_do()
  1233. {
  1234. struct token_list* nested_locals = break_frame;
  1235. char* nested_break_head = break_target_head;
  1236. char* nested_break_func = break_target_func;
  1237. char* nested_break_num = break_target_num;
  1238. char* nested_continue_head = continue_target_head;
  1239. char* number_string = numerate_number(current_count);
  1240. current_count = current_count + 1;
  1241. break_target_head = "DO_END_";
  1242. continue_target_head = "DO_TEST_";
  1243. break_target_num = number_string;
  1244. break_frame = function->locals;
  1245. break_target_func = function->s;
  1246. emit_out(":DO_");
  1247. uniqueID_out(function->s, number_string);
  1248. global_token = global_token->next;
  1249. require(NULL != global_token, "Recieved EOF where do statement is expected\n");
  1250. statement();
  1251. require(NULL != global_token, "Reached EOF inside of function\n");
  1252. emit_out(":DO_TEST_");
  1253. uniqueID_out(function->s, number_string);
  1254. require_match("ERROR in process_do\nMISSING while\n", "while");
  1255. require_match("ERROR in process_do\nMISSING (\n", "(");
  1256. expression();
  1257. require_match("ERROR in process_do\nMISSING )\n", ")");
  1258. require_match("ERROR in process_do\nMISSING ;\n", ";");
  1259. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.NZ R0 @DO_");
  1260. else if(X86 == Architecture) emit_out("TEST\nJUMP_NE %DO_");
  1261. else if(AMD64 == Architecture) emit_out("TEST\nJUMP_NE %DO_");
  1262. else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~DO_");
  1263. else if(AARCH64 == Architecture) emit_out("CBZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&DO_");
  1264. uniqueID_out(function->s, number_string);
  1265. if(ARMV7L == Architecture) emit_out(" JUMP_NE\n");
  1266. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1267. emit_out(":DO_END_");
  1268. uniqueID_out(function->s, number_string);
  1269. break_frame = nested_locals;
  1270. break_target_head = nested_break_head;
  1271. break_target_func = nested_break_func;
  1272. break_target_num = nested_break_num;
  1273. continue_target_head = nested_continue_head;
  1274. }
  1275. /* Process while loops */
  1276. void process_while()
  1277. {
  1278. struct token_list* nested_locals = break_frame;
  1279. char* nested_break_head = break_target_head;
  1280. char* nested_break_func = break_target_func;
  1281. char* nested_break_num = break_target_num;
  1282. char* nested_continue_head = continue_target_head;
  1283. char* number_string = numerate_number(current_count);
  1284. current_count = current_count + 1;
  1285. break_target_head = "END_WHILE_";
  1286. continue_target_head = "WHILE_";
  1287. break_target_num = number_string;
  1288. break_frame = function->locals;
  1289. break_target_func = function->s;
  1290. emit_out(":WHILE_");
  1291. uniqueID_out(function->s, number_string);
  1292. global_token = global_token->next;
  1293. require_match("ERROR in process_while\nMISSING (\n", "(");
  1294. expression();
  1295. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @END_WHILE_");
  1296. else if(X86 == Architecture) emit_out("TEST\nJUMP_EQ %END_WHILE_");
  1297. else if(AMD64 == Architecture) emit_out("TEST\nJUMP_EQ %END_WHILE_");
  1298. else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~END_WHILE_");
  1299. else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&END_WHILE_");
  1300. uniqueID_out(function->s, number_string);
  1301. if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\t");
  1302. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1303. emit_out("# THEN_while_");
  1304. uniqueID_out(function->s, number_string);
  1305. require_match("ERROR in process_while\nMISSING )\n", ")");
  1306. statement();
  1307. require(NULL != global_token, "Reached EOF inside of function\n");
  1308. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @WHILE_");
  1309. else if(X86 == Architecture) emit_out("JUMP %WHILE_");
  1310. else if(AMD64 == Architecture) emit_out("JUMP %WHILE_");
  1311. else if(ARMV7L == Architecture) emit_out("^~WHILE_");
  1312. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&WHILE_");
  1313. uniqueID_out(function->s, number_string);
  1314. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
  1315. else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
  1316. emit_out(":END_WHILE_");
  1317. uniqueID_out(function->s, number_string);
  1318. break_target_head = nested_break_head;
  1319. break_target_func = nested_break_func;
  1320. break_target_num = nested_break_num;
  1321. continue_target_head = nested_continue_head;
  1322. break_frame = nested_locals;
  1323. }
  1324. /* Ensure that functions return */
  1325. void return_result()
  1326. {
  1327. global_token = global_token->next;
  1328. require(NULL != global_token, "Incomplete return statement recieved\n");
  1329. if(global_token->s[0] != ';') expression();
  1330. require_match("ERROR in return_result\nMISSING ;\n", ";");
  1331. struct token_list* i;
  1332. for(i = function->locals; NULL != i; i = i->next)
  1333. {
  1334. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _return_result_locals\n");
  1335. else if(X86 == Architecture) emit_out("POP_ebx\t# _return_result_locals\n");
  1336. else if(AMD64 == Architecture) emit_out("POP_RBX\t# _return_result_locals\n");
  1337. else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _return_result_locals\n");
  1338. else if(AARCH64 == Architecture) emit_out("POP_X1\t# _return_result_locals\n");
  1339. }
  1340. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("RET R15\n");
  1341. else if(X86 == Architecture) emit_out("RETURN\n");
  1342. else if(AMD64 == Architecture) emit_out("RETURN\n");
  1343. else if(ARMV7L == Architecture) emit_out("'1' LR RETURN\n");
  1344. else if(AARCH64 == Architecture) emit_out("RETURN\n");
  1345. }
  1346. void process_break()
  1347. {
  1348. if(NULL == break_target_head)
  1349. {
  1350. line_error();
  1351. file_print("Not inside of a loop or case statement\n", stderr);
  1352. exit(EXIT_FAILURE);
  1353. }
  1354. struct token_list* i = function->locals;
  1355. while(i != break_frame)
  1356. {
  1357. if(NULL == i) break;
  1358. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# break_cleanup_locals\n");
  1359. else if(X86 == Architecture) emit_out("POP_ebx\t# break_cleanup_locals\n");
  1360. else if(AMD64 == Architecture) emit_out("POP_RBX\t# break_cleanup_locals\n");
  1361. else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# break_cleanup_locals\n");
  1362. else if(AARCH64 == Architecture) emit_out("POP_X1\t# break_cleanup_locals\n");
  1363. i = i->next;
  1364. }
  1365. global_token = global_token->next;
  1366. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
  1367. else if(X86 == Architecture) emit_out("JUMP %");
  1368. else if(AMD64 == Architecture) emit_out("JUMP %");
  1369. else if(ARMV7L == Architecture) emit_out("^~");
  1370. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
  1371. emit_out(break_target_head);
  1372. emit_out(break_target_func);
  1373. emit_out("_");
  1374. emit_out(break_target_num);
  1375. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
  1376. else if(AARCH64 == Architecture) emit_out("\nBR_X16");
  1377. emit_out("\n");
  1378. require_match("ERROR in break statement\nMissing ;\n", ";");
  1379. }
  1380. void process_contine()
  1381. {
  1382. if(NULL == continue_target_head)
  1383. {
  1384. line_error();
  1385. file_print("Not inside of a loop\n", stderr);
  1386. exit(EXIT_FAILURE);
  1387. }
  1388. global_token = global_token->next;
  1389. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
  1390. else if(X86 == Architecture) emit_out("JUMP %");
  1391. else if(AMD64 == Architecture) emit_out("JUMP %");
  1392. else if(ARMV7L == Architecture) emit_out("^~");
  1393. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
  1394. emit_out(continue_target_head);
  1395. emit_out(break_target_func);
  1396. emit_out("_");
  1397. emit_out(break_target_num);
  1398. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
  1399. else if(AARCH64 == Architecture) emit_out("\nBR_X16");
  1400. emit_out("\n");
  1401. require_match("ERROR in continue statement\nMissing ;\n", ";");
  1402. }
  1403. void recursive_statement()
  1404. {
  1405. global_token = global_token->next;
  1406. require(NULL != global_token, "Recieved EOF in recursive statement\n");
  1407. struct token_list* frame = function->locals;
  1408. while(!match("}", global_token->s))
  1409. {
  1410. statement();
  1411. require(NULL != global_token, "Recieved EOF in recursive statement prior to }\n");
  1412. }
  1413. global_token = global_token->next;
  1414. /* Clean up any locals added */
  1415. if(((X86 == Architecture) && !match("RETURN\n", output_list->s)) ||
  1416. ((AMD64 == Architecture) && !match("RETURN\n", output_list->s)) ||
  1417. (((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) && !match("RET R15\n", output_list->s)) ||
  1418. ((ARMV7L == Architecture) && !match("'1' LR RETURN\n", output_list->s)) ||
  1419. ((AARCH64 == Architecture) && !match("RETURN\n", output_list->s)))
  1420. {
  1421. struct token_list* i;
  1422. for(i = function->locals; frame != i; i = i->next)
  1423. {
  1424. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _recursive_statement_locals\n");
  1425. else if(X86 == Architecture) emit_out( "POP_ebx\t# _recursive_statement_locals\n");
  1426. else if(AMD64 == Architecture) emit_out("POP_RBX\t# _recursive_statement_locals\n");
  1427. else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _recursive_statement_locals\n");
  1428. else if(AARCH64 == Architecture) emit_out("POP_X1\t# _recursive_statement_locals\n");
  1429. }
  1430. }
  1431. function->locals = frame;
  1432. }
  1433. /*
  1434. * statement:
  1435. * { statement-list-opt }
  1436. * type-name identifier ;
  1437. * type-name identifier = expression;
  1438. * if ( expression ) statement
  1439. * if ( expression ) statement else statement
  1440. * do statement while ( expression ) ;
  1441. * while ( expression ) statement
  1442. * for ( expression ; expression ; expression ) statement
  1443. * asm ( "assembly" ... "assembly" ) ;
  1444. * goto label ;
  1445. * label:
  1446. * return ;
  1447. * break ;
  1448. * expr ;
  1449. */
  1450. struct type* lookup_type(char* s, struct type* start);
  1451. void statement()
  1452. {
  1453. /* Always an integer until told otherwise */
  1454. current_target = integer;
  1455. if(global_token->s[0] == '{')
  1456. {
  1457. recursive_statement();
  1458. }
  1459. else if(':' == global_token->s[0])
  1460. {
  1461. emit_out(global_token->s);
  1462. emit_out("\t#C goto label\n");
  1463. global_token = global_token->next;
  1464. }
  1465. else if((NULL != lookup_type(global_token->s, prim_types)) ||
  1466. match("struct", global_token->s))
  1467. {
  1468. collect_local();
  1469. }
  1470. else if(match("if", global_token->s))
  1471. {
  1472. process_if();
  1473. }
  1474. else if(match("do", global_token->s))
  1475. {
  1476. process_do();
  1477. }
  1478. else if(match("while", global_token->s))
  1479. {
  1480. process_while();
  1481. }
  1482. else if(match("for", global_token->s))
  1483. {
  1484. process_for();
  1485. }
  1486. else if(match("asm", global_token->s))
  1487. {
  1488. process_asm();
  1489. }
  1490. else if(match("goto", global_token->s))
  1491. {
  1492. global_token = global_token->next;
  1493. require(NULL != global_token, "naked goto is not supported\n");
  1494. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
  1495. else if(X86 == Architecture) emit_out("JUMP %");
  1496. else if(AMD64 == Architecture) emit_out("JUMP %");
  1497. else if(ARMV7L == Architecture) emit_out("^~");
  1498. else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
  1499. emit_out(global_token->s);
  1500. if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
  1501. else if(AARCH64 == Architecture) emit_out("\nBR_X16");
  1502. emit_out("\n");
  1503. global_token = global_token->next;
  1504. require_match("ERROR in statement\nMissing ;\n", ";");
  1505. }
  1506. else if(match("return", global_token->s))
  1507. {
  1508. return_result();
  1509. }
  1510. else if(match("break", global_token->s))
  1511. {
  1512. process_break();
  1513. }
  1514. else if(match("continue", global_token->s))
  1515. {
  1516. process_contine();
  1517. }
  1518. else
  1519. {
  1520. expression();
  1521. require_match("ERROR in statement\nMISSING ;\n", ";");
  1522. }
  1523. }
  1524. /* Collect function arguments */
  1525. void collect_arguments()
  1526. {
  1527. global_token = global_token->next;
  1528. require(NULL != global_token, "Recieved EOF when attempting to collect arguments\n");
  1529. struct type* type_size;
  1530. struct token_list* a;
  1531. while(!match(")", global_token->s))
  1532. {
  1533. type_size = type_name();
  1534. if(global_token->s[0] == ')')
  1535. {
  1536. /* foo(int,char,void) doesn't need anything done */
  1537. continue;
  1538. }
  1539. else if(global_token->s[0] != ',')
  1540. {
  1541. /* deal with foo(int a, char b) */
  1542. a = sym_declare(global_token->s, type_size, function->arguments);
  1543. if(NULL == function->arguments)
  1544. {
  1545. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = 0;
  1546. else if(X86 == Architecture) a->depth = -4;
  1547. else if(AMD64 == Architecture) a->depth = -8;
  1548. else if(ARMV7L == Architecture) a->depth = 4;
  1549. else if(AARCH64 == Architecture) a->depth = register_size;
  1550. }
  1551. else
  1552. {
  1553. if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->arguments->depth + register_size;
  1554. else if(X86 == Architecture) a->depth = function->arguments->depth - register_size;
  1555. else if(AMD64 == Architecture) a->depth = function->arguments->depth - register_size;
  1556. else if(ARMV7L == Architecture) a->depth = function->arguments->depth + register_size;
  1557. else if(AARCH64 == Architecture) a->depth = function->arguments->depth + register_size;
  1558. }
  1559. global_token = global_token->next;
  1560. require(NULL != global_token, "Incomplete argument list\n");
  1561. function->arguments = a;
  1562. }
  1563. /* ignore trailing comma (needed for foo(bar(), 1); expressions*/
  1564. if(global_token->s[0] == ',')
  1565. {
  1566. global_token = global_token->next;
  1567. require(NULL != global_token, "naked comma in collect arguments\n");
  1568. }
  1569. require(NULL != global_token, "Argument list never completed\n");
  1570. }
  1571. global_token = global_token->next;
  1572. }
  1573. void declare_function()
  1574. {
  1575. current_count = 0;
  1576. function = sym_declare(global_token->prev->s, NULL, global_function_list);
  1577. /* allow previously defined functions to be looked up */
  1578. global_function_list = function;
  1579. if((KNIGHT_NATIVE == Architecture) && match("main", function->s))
  1580. {
  1581. require_match("Impossible error ( vanished\n", "(");
  1582. require_match("Reality ERROR (USING KNIGHT-NATIVE)\nHardware does not support arguments\nthus neither can main on this architecture\ntry tape_01 and tape_02 instead\n", ")");
  1583. }
  1584. else collect_arguments();
  1585. require(NULL != global_token, "Function definitions either need to be prototypes or full\n");
  1586. /* If just a prototype don't waste time */
  1587. if(global_token->s[0] == ';') global_token = global_token->next;
  1588. else
  1589. {
  1590. emit_out("# Defining function ");
  1591. emit_out(function->s);
  1592. emit_out("\n");
  1593. emit_out(":FUNCTION_");
  1594. emit_out(function->s);
  1595. emit_out("\n");
  1596. statement();
  1597. /* Prevent duplicate RETURNS */
  1598. if(((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) && !match("RET R15\n", output_list->s)) emit_out("RET R15\n");
  1599. else if((X86 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
  1600. else if((AMD64 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
  1601. else if((ARMV7L == Architecture) && !match("'1' LR RETURN\n", output_list->s)) emit_out("'1' LR RETURN\n");
  1602. else if((AARCH64 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
  1603. }
  1604. }
  1605. /*
  1606. * program:
  1607. * declaration
  1608. * declaration program
  1609. *
  1610. * declaration:
  1611. * CONSTANT identifer value
  1612. * type-name identifier ;
  1613. * type-name identifier ( parameter-list ) ;
  1614. * type-name identifier ( parameter-list ) statement
  1615. *
  1616. * parameter-list:
  1617. * parameter-declaration
  1618. * parameter-list, parameter-declaration
  1619. *
  1620. * parameter-declaration:
  1621. * type-name identifier-opt
  1622. */
  1623. void program()
  1624. {
  1625. function = NULL;
  1626. Address_of = FALSE;
  1627. struct type* type_size;
  1628. new_type:
  1629. if (NULL == global_token) return;
  1630. if(match("CONSTANT", global_token->s))
  1631. {
  1632. global_token = global_token->next;
  1633. require(NULL != global_token, "CONSTANT lacks a name\n");
  1634. global_constant_list = sym_declare(global_token->s, NULL, global_constant_list);
  1635. require(NULL != global_token->next, "CONSTANT lacks a value\n");
  1636. if(match("sizeof", global_token->next->s))
  1637. {
  1638. global_token = global_token->next->next;
  1639. require_match("ERROR in CONSTANT with sizeof\nMissing (\n", "(");
  1640. struct type* a = type_name();
  1641. require_match("ERROR in CONSTANT with sizeof\nMissing )\n", ")");
  1642. global_token->prev->s = numerate_number(a->size);
  1643. global_constant_list->arguments = global_token->prev;
  1644. }
  1645. else
  1646. {
  1647. global_constant_list->arguments = global_token->next;
  1648. global_token = global_token->next->next;
  1649. }
  1650. }
  1651. else if(match("typedef", global_token->s))
  1652. {
  1653. /* typedef $TYPE $NAME; */
  1654. global_token = global_token->next;
  1655. type_size = type_name();
  1656. type_size = mirror_type(type_size, global_token->s);
  1657. add_primitive(type_size);
  1658. global_token = global_token->next;
  1659. require_match("ERROR in typedef statement\nMissing ;\n", ";");
  1660. }
  1661. else
  1662. {
  1663. type_size = type_name();
  1664. if(NULL == type_size)
  1665. {
  1666. goto new_type;
  1667. }
  1668. /* Add to global symbol table */
  1669. global_symbol_list = sym_declare(global_token->s, type_size, global_symbol_list);
  1670. global_token = global_token->next;
  1671. require(NULL != global_token, "Unterminated global\n");
  1672. if(match(";", global_token->s))
  1673. {
  1674. /* Ensure 4 bytes are allocated for the global */
  1675. globals_list = emit(":GLOBAL_", globals_list);
  1676. globals_list = emit(global_token->prev->s, globals_list);
  1677. globals_list = emit("\nNULL\n", globals_list);
  1678. global_token = global_token->next;
  1679. }
  1680. else if(match("(", global_token->s)) declare_function();
  1681. else if(match("=",global_token->s))
  1682. {
  1683. /* Store the global's value*/
  1684. globals_list = emit(":GLOBAL_", globals_list);
  1685. globals_list = emit(global_token->prev->s, globals_list);
  1686. globals_list = emit("\n", globals_list);
  1687. global_token = global_token->next;
  1688. require(NULL != global_token, "Global locals value in assignment\n");
  1689. if(in_set(global_token->s[0], "0123456789"))
  1690. { /* Assume Int */
  1691. globals_list = emit("%", globals_list);
  1692. globals_list = emit(global_token->s, globals_list);
  1693. globals_list = emit("\n", globals_list);
  1694. }
  1695. else if(('"' == global_token->s[0]))
  1696. { /* Assume a string*/
  1697. globals_list = emit("&GLOBAL_", globals_list);
  1698. globals_list = emit(global_token->prev->prev->s, globals_list);
  1699. globals_list = emit("_contents\n", globals_list);
  1700. globals_list = emit(":GLOBAL_", globals_list);
  1701. globals_list = emit(global_token->prev->prev->s, globals_list);
  1702. globals_list = emit("_contents\n", globals_list);
  1703. globals_list = emit(parse_string(global_token->s), globals_list);
  1704. }
  1705. else
  1706. {
  1707. line_error();
  1708. file_print("Received ", stderr);
  1709. file_print(global_token->s, stderr);
  1710. file_print(" in program\n", stderr);
  1711. exit(EXIT_FAILURE);
  1712. }
  1713. global_token = global_token->next;
  1714. require_match("ERROR in Program\nMissing ;\n", ";");
  1715. }
  1716. else
  1717. {
  1718. line_error();
  1719. file_print("Received ", stderr);
  1720. file_print(global_token->s, stderr);
  1721. file_print(" in program\n", stderr);
  1722. exit(EXIT_FAILURE);
  1723. }
  1724. }
  1725. goto new_type;
  1726. }
  1727. void recursive_output(struct token_list* head, FILE* out)
  1728. {
  1729. struct token_list* i = reverse_list(head);
  1730. while(NULL != i)
  1731. {
  1732. file_print(i->s, out);
  1733. i = i->next;
  1734. }
  1735. }