Year 2 compilers coureswork

main.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include "nodes.h"
  6. #include "C.tab.h"
  7. #include "types.h"
  8. #include "list.h"
  9. int debug = 0;
  10. extern TOKEN* lookup_token(char*);
  11. TOKEN* gen_tmp(void) {
  12. char tmp[10];
  13. static char num = 0;
  14. snprintf(tmp, 10, "$t%d", num++);
  15. return lookup_token(tmp);
  16. }
  17. TOKEN* gen_label(void) {
  18. char tmp[10];
  19. static char label = 0;
  20. snprintf(tmp, 10, "L%d", label++);
  21. return lookup_token(tmp);
  22. }
  23. char *named(int t)
  24. {
  25. static char b[100];
  26. if (isgraph(t) || t==' ') {
  27. sprintf(b, "%c", t);
  28. return b;
  29. }
  30. switch (t) {
  31. default: return "???";
  32. case IDENTIFIER:
  33. return "id";
  34. case CONSTANT:
  35. return "constant";
  36. case STRING_LITERAL:
  37. return "string";
  38. case LE_OP:
  39. return "<=";
  40. case GE_OP:
  41. return ">=";
  42. case EQ_OP:
  43. return "==";
  44. case NE_OP:
  45. return "!=";
  46. case EXTERN:
  47. return "extern";
  48. case AUTO:
  49. return "auto";
  50. case INT:
  51. return "int";
  52. case VOID:
  53. return "void";
  54. case APPLY:
  55. return "apply";
  56. case LEAF:
  57. return "leaf";
  58. case IF:
  59. return "if";
  60. case ELSE:
  61. return "else";
  62. case WHILE:
  63. return "while";
  64. case CONTINUE:
  65. return "continue";
  66. case BREAK:
  67. return "break";
  68. case RETURN:
  69. return "return";
  70. }
  71. }
  72. void print_leaf(NODE *tree, int level)
  73. {
  74. TOKEN *t = (TOKEN *)tree;
  75. int i;
  76. for (i=0; i<level; i++) putchar(' ');
  77. if (t->type == CONSTANT) printf("%d\n", t->value);
  78. else if (t->type == STRING_LITERAL) printf("\"%s\"\n", t->lexeme);
  79. else if (t) puts(t->lexeme);
  80. }
  81. void print_tree0(NODE *tree, int level)
  82. {
  83. int i;
  84. if (tree==NULL) return;
  85. if (tree->type==LEAF) {
  86. print_leaf(tree->left, level);
  87. }
  88. else {
  89. for(i=0; i<level; i++) putchar(' ');
  90. printf("%s\n", named(tree->type));
  91. print_tree0(tree->left, level+2);
  92. print_tree0(tree->right, level+2);
  93. }
  94. }
  95. void print_tree(NODE *tree)
  96. {
  97. print_tree0(tree, 0);
  98. }
  99. void new_tac(TACS* tacs, TOKEN* dst, TOKEN* src, TOKEN* tgt, int op) {
  100. if (tacs->list == NULL) {
  101. TAC_T* tac;
  102. tac = create_tac(op, src, tgt, dst);
  103. tacs->list = new_tac_list(tac, NULL);
  104. } else {
  105. add_tac(tacs->list, op, src, tgt, dst);
  106. }
  107. }
  108. char* stok(TOKEN* tok) {
  109. return tok->lexeme;
  110. }
  111. void print_tac_el(TAC_T* elem) {
  112. int op = elem->op;
  113. if (op == '=') printf("%s := %s\n", stok(elem->dst), stok(elem->src));
  114. if (op=='+' || op=='-' || op=='*' || op=='/' || op =='%') printf("%s := %s %c %s\n", stok(elem->dst), stok(elem->src), op, stok(elem->tgt));
  115. if (op == RETURN) printf("ret %s\n", stok(elem->src));
  116. if (op == 'D') printf("func %s\n", stok(elem->dst));
  117. if (op == '>' || op == '<') printf("if %s %c %s then %s\n", stok(elem->src), op, stok(elem->tgt), stok(elem->dst));
  118. if (op == GE_OP) printf("if %s >= %s then %s\n", stok(elem->src), stok(elem->tgt), stok(elem->dst));
  119. if (op == LE_OP) printf("if %s <= %s then %s\n", stok(elem->src), stok(elem->tgt), stok(elem->dst));
  120. if (op == EQ_OP) printf("if %s == %s then %s\n", stok(elem->src), stok(elem->tgt), stok(elem->dst));
  121. if (op == NE_OP) printf("if %s != %s then %s\n", stok(elem->src), stok(elem->tgt), stok(elem->dst));
  122. if (op == IDENTIFIER) printf("%s\n", stok(elem->dst));
  123. if (op == VOID) printf("goto %s\n", stok(elem->dst));
  124. if (op == AUTO) printf("param %s\n", stok(elem->dst));
  125. if (op == APPLY) printf("call %s, %s\n", stok(elem->dst), stok(elem->tgt));
  126. if (op == 278) printf("arg %s\n", stok(elem->dst));
  127. if (op == 279) printf("end %s\n\n", stok(elem->dst));
  128. }
  129. void print_tac(TLIST* tac_list) {
  130. TLIST *ptr = tac_list;
  131. while (ptr != NULL) {
  132. print_tac_el(ptr->elem);
  133. ptr = ptr->next;
  134. }
  135. }
  136. int invert_op(int op) {
  137. if (op == LE_OP) {
  138. return '>';
  139. } else if (op == GE_OP) {
  140. return '<';
  141. } else if (op == '>') {
  142. return LE_OP;
  143. } else if (op == '<') {
  144. return GE_OP;
  145. } else if (op == EQ_OP) {
  146. return NE_OP;
  147. } else if (op == NE_OP) {
  148. return EQ_OP;
  149. } else {
  150. printf("Unknown operator: %c", op);
  151. exit(1);
  152. }
  153. }
  154. int count_args(NODE *tree) {
  155. NODE *tmp = tree;
  156. int a = 1;
  157. while (tmp != NULL) {
  158. if (tmp->type != ',') {
  159. break;
  160. }
  161. tmp = tmp->left;
  162. a++;
  163. }
  164. return a;
  165. }
  166. void populate_arg_list(NODE *tree, TOKEN** arr, int arr_len) {
  167. if (tree->type == '~') {
  168. for (int i = 0; i < arr_len; i++) {
  169. if (arr[i] == NULL) {
  170. TOKEN* name = (TOKEN*)tree->right->left;
  171. arr[i] = name;
  172. break;
  173. }
  174. }
  175. } else {
  176. populate_arg_list(tree->left, arr, arr_len);
  177. populate_arg_list(tree->right, arr, arr_len);
  178. }
  179. }
  180. TOKEN** get_argument_list(NODE *tree) {
  181. int num_args = count_args(tree->left->right->right);
  182. TOKEN** arr = (TOKEN**) malloc(sizeof(TOKEN*) * num_args);
  183. populate_arg_list(tree->left->right->right, arr, num_args);
  184. return arr;
  185. }
  186. void populate_val_list(NODE* tree, NODE** arr, int num_args) {
  187. if (tree->type == ',') {
  188. populate_val_list(tree->left, arr, num_args);
  189. populate_val_list(tree->right, arr, num_args);
  190. } else {
  191. for (int i = 0; i < num_args; i++) {
  192. if (arr[i] == NULL) {
  193. arr[i] = tree;
  194. break;
  195. }
  196. }
  197. }
  198. }
  199. NODE** get_val_list(NODE *tree) {
  200. int num_args = count_args(tree);
  201. NODE** arr = (NODE**) malloc(sizeof(NODE*) * num_args);
  202. populate_val_list(tree, arr, num_args);
  203. return arr;
  204. }
  205. TOKEN* build_tac(NODE *tree, TACS* tac) {
  206. if (tree == NULL) return NULL;
  207. int type = tree->type;
  208. if (type == LEAF) {
  209. return (TOKEN *) tree->left;
  210. } else if (type == '=') {
  211. TOKEN* dst = (TOKEN*) tree->left->left;
  212. TOKEN* result = build_tac(tree->right, tac);
  213. new_tac(tac, dst, result, NULL, tree->type);
  214. } else if (type=='+' || type=='-' || type=='*' || type=='/' || type =='%') {
  215. TOKEN* dst = gen_tmp();
  216. TOKEN* src = build_tac(tree->left, tac);
  217. TOKEN* tgt = build_tac(tree->right, tac);
  218. new_tac(tac, dst, src, tgt, tree->type);
  219. return dst;
  220. } else if (type == IF) {
  221. int op = invert_op(tree->left->type);
  222. TOKEN* lhs = build_tac(tree->left->left, tac);
  223. TOKEN* rhs = build_tac(tree->left->right, tac);
  224. TOKEN* label = gen_label();
  225. new_tac(tac, label, lhs, rhs, op);
  226. if (tree->right->type == ELSE) {
  227. TOKEN* cont = gen_label();
  228. build_tac(tree->right->left, tac);
  229. new_tac(tac, cont, NULL, NULL, VOID);
  230. new_tac(tac, label, NULL, NULL, IDENTIFIER);
  231. build_tac(tree->right->right, tac);
  232. new_tac(tac, cont, NULL, NULL, IDENTIFIER);
  233. } else {
  234. build_tac(tree->right, tac);
  235. new_tac(tac, label, NULL, NULL, IDENTIFIER);
  236. }
  237. } else if (type == RETURN) {
  238. TOKEN* src = build_tac(tree->left, tac);
  239. new_tac(tac, NULL, src, NULL, RETURN);
  240. } else if (type == 'D') {
  241. new_tac(tac, (TOKEN*) tree->left->right->left->left, NULL, NULL, 'D');
  242. if (tree->left->right->right != NULL) {
  243. TOKEN** arg_list = get_argument_list(tree);
  244. int arg_count = count_args(tree->left->right->right);
  245. for (int i = 0; i < arg_count; i++) {
  246. new_tac(tac, arg_list[i], NULL, NULL, AUTO);
  247. }
  248. }
  249. build_tac(tree->right, tac);
  250. new_tac(tac, (TOKEN*) tree->left->right->left->left, NULL, NULL, 279);
  251. } else if (type == APPLY) {
  252. TOKEN* ret_val = gen_tmp();
  253. if (tree->right != NULL) {
  254. int num_args;
  255. NODE **val_list;
  256. num_args = count_args(tree->right);
  257. val_list = get_val_list(tree->right);
  258. TOKEN* arg_tokens[num_args];
  259. for (int i = 0; i < num_args; i++) {
  260. arg_tokens[i] = build_tac(val_list[i], tac);
  261. }
  262. for (int i = 0; i < num_args; i++) {
  263. new_tac(tac, arg_tokens[i], NULL, NULL, 278);
  264. }
  265. }
  266. new_tac(tac, (TOKEN*) tree->left->left, NULL, ret_val, APPLY);
  267. return ret_val;
  268. } else {
  269. build_tac(tree->left, tac);
  270. build_tac(tree->right, tac);
  271. return NULL;
  272. }
  273. return NULL;
  274. }
  275. int tmp_regs[10] = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25};
  276. int svd_regs[8] = {16, 17, 18, 19, 20, 21, 22, 23};
  277. int arg_regs[3] = {5, 6, 7};
  278. int tmp_cntr = 0;
  279. int register_me(TOKEN* name, ENV* env) {
  280. if (tmp_cntr == 10) tmp_cntr = 0;
  281. if (name->type == CONSTANT) {
  282. if (name->value == 0) {
  283. return 0;
  284. } else {
  285. printf("li $%d, %d\n", tmp_regs[tmp_cntr], name->value);
  286. return tmp_regs[tmp_cntr++];
  287. }
  288. } else {
  289. BIND* binding = find_name_in_list(name, env->bindings);
  290. if (binding == NULL) {
  291. BIND* new_bind;
  292. if (name->lexeme[0] != '$') {
  293. new_bind = create_binding(name, env->counter++, NULL);
  294. if (env->bindings == NULL) env->bindings = create_list(new_bind, NULL);
  295. else append_list(env->bindings, new_bind);
  296. new_bind->is_saved = 1;
  297. return svd_regs[new_bind->env_offset];
  298. } else {
  299. new_bind = create_binding(name, tmp_cntr++, NULL);
  300. if (env->bindings == NULL) env->bindings = create_list(new_bind, NULL);
  301. else append_list(env->bindings, new_bind);
  302. return tmp_regs[new_bind->env_offset];
  303. }
  304. } else {
  305. return binding->is_saved ? svd_regs[binding->env_offset] : tmp_regs[binding->env_offset];
  306. }
  307. }
  308. }
  309. void alloc_function_env() {
  310. printf("li $a0, 68\n");
  311. printf("li $v0, 9\n");
  312. printf("syscall\n");
  313. }
  314. void compile_tac(TLIST* tacs) {
  315. ENV* env = create_new_function_env(NULL, NULL);
  316. printf("=====\n");
  317. alloc_function_env();
  318. printf("or $fp, $0, $v0\n");
  319. printf("la $t0, main\n");
  320. printf("sw $t0, 0($fp)\n");
  321. printf("sw $0, 4($fp)\n");
  322. printf("jal main\n");
  323. printf("j done\n");
  324. while(tacs != NULL) {
  325. TAC_T* t = tacs->elem;
  326. if (debug) {
  327. printf("#");
  328. print_tac_el(t);
  329. }
  330. if (t->op == '=') {
  331. int src = register_me(t->src, env);
  332. int dst = register_me(t->dst, env);
  333. printf("or $%d, $0, $%d\n", dst, src);
  334. }
  335. if (t->op == 'D') {
  336. env = create_new_function_env(NULL, env);
  337. printf("%s:\n", t->dst->lexeme);
  338. alloc_function_env();
  339. printf("sw $fp, 4($v0)\n");
  340. if (env->previous->bindings != NULL) {
  341. int i = 2;
  342. BLIST* ptr = env->previous->bindings;
  343. while (ptr != NULL) {
  344. if (ptr->binding->name->lexeme[0] != '$') {
  345. printf("sw $%d, %d($fp)\n", svd_regs[ptr->binding->env_offset], i*4);
  346. i++;
  347. }
  348. ptr = ptr->next;
  349. }
  350. }
  351. printf("or $fp, $0, $v0\n");
  352. printf("la $t0, %s\n", stok(t->dst));
  353. printf("sw $t0, 0($fp)\n");
  354. printf("sw $ra, 64($fp)\n");
  355. }
  356. if (t->op == '+') {
  357. int src = register_me(t->src, env);
  358. int dst = register_me(t->dst, env);
  359. int tgt = register_me(t->tgt, env);
  360. printf("add $%d, $%d, $%d\n", dst, src, tgt);
  361. }
  362. if (t->op == '-') {
  363. int src = register_me(t->src, env);
  364. int dst = register_me(t->dst, env);
  365. int tgt = register_me(t->tgt, env);
  366. printf("sub $%d, $%d, $%d\n", dst, src, tgt);
  367. }
  368. if (t->op == '*') {
  369. int src = register_me(t->src, env);
  370. int dst = register_me(t->dst, env);
  371. int tgt = register_me(t->tgt, env);
  372. printf("mult $%d, $%d\n", src, tgt);
  373. printf("mflo $%d\n", dst);
  374. }
  375. if (t->op == '/') {
  376. int src = register_me(t->src, env);
  377. int dst = register_me(t->dst, env);
  378. int tgt = register_me(t->tgt, env);
  379. printf("div $%d, $%d\n", src, tgt);
  380. printf("mflo $%d\n", dst);
  381. }
  382. if (t->op == '%') {
  383. int src = register_me(t->src, env);
  384. int dst = register_me(t->dst, env);
  385. int tgt = register_me(t->tgt, env);
  386. printf("div $%d, $%d\n", src, tgt);
  387. printf("mfhi $%d\n", dst);
  388. }
  389. if (t->op == LE_OP) {
  390. int src = register_me(t->src, env);
  391. int tgt = register_me(t->tgt, env);
  392. printf("ble $%d, $%d, %s\n", src, tgt, stok(t->dst));
  393. }
  394. if (t->op == GE_OP) {
  395. int src = register_me(t->src, env);
  396. int tgt = register_me(t->tgt, env);
  397. printf("bge $%d, $%d, %s\n", src, tgt, stok(t->dst));
  398. }
  399. if (t->op == EQ_OP) {
  400. int src = register_me(t->src, env);
  401. int tgt = register_me(t->tgt, env);
  402. printf("beq $%d, $%d, %s\n", src, tgt, stok(t->dst));
  403. }
  404. if (t->op == NE_OP) {
  405. int src = register_me(t->src, env);
  406. int tgt = register_me(t->tgt, env);
  407. printf("bne $%d, $%d, %s\n", src, tgt, stok(t->dst));
  408. }
  409. if (t->op == '>') {
  410. int src = register_me(t->src, env);
  411. int tgt = register_me(t->tgt, env);
  412. printf("bgt $%d, $%d, %s\n", src, tgt, stok(t->dst));
  413. }
  414. if (t->op == '<') {
  415. int src = register_me(t->src, env);
  416. int tgt = register_me(t->tgt, env);
  417. printf("blt $%d, $%d, %s\n", src, tgt, stok(t->dst));
  418. }
  419. if (t->op == APPLY) {
  420. int tgt_idx = register_me(t->tgt, env);
  421. env->arg_counter = 0;
  422. printf("jal %s\n", stok(t->dst));
  423. printf("lw $fp, 4($fp)\n");
  424. printf("lw $ra, 64($fp)\n");
  425. if (env->bindings != NULL) {
  426. int i = 2;
  427. BLIST* ptr = env->bindings;
  428. while (ptr != NULL) {
  429. if (ptr->binding->name->lexeme[0] != '$') {
  430. printf("lw $%d, %d($fp)\n", svd_regs[ptr->binding->env_offset], i*4);
  431. i++;
  432. }
  433. ptr = ptr->next;
  434. }
  435. }
  436. printf("or $%d, $0, $v1\n", tgt_idx);
  437. }
  438. if (t->op == IDENTIFIER) {
  439. printf("%s:\n", stok(t->dst));
  440. }
  441. if (t->op == VOID) {
  442. printf("j %s\n", stok(t->dst));
  443. }
  444. if (t->op == RETURN) {
  445. int src_idx = register_me(t->src, env);
  446. printf("or $v1, $0, $%d\n", src_idx);
  447. printf("jr $31\n");
  448. }
  449. if (t->op == 279) {
  450. env = env->previous;
  451. }
  452. if (t->op == 278) {
  453. int dst_idx = register_me(t->dst, env);
  454. printf("or $%d, $0, $%d\n", arg_regs[env->arg_counter], dst_idx);
  455. env->arg_counter++;
  456. }
  457. if (t->op == AUTO) {
  458. int dst_idx = register_me(t->dst, env);
  459. printf("or $%d, $0, $%d\n", dst_idx, arg_regs[env->param_counter]);
  460. env->param_counter++;
  461. }
  462. tacs = tacs->next;
  463. }
  464. printf("done:\n");
  465. printf("ori $v0, $0, 10\n");
  466. printf("syscall\n");
  467. }
  468. void interpret_tree(NODE *tree) {
  469. TACS* gen_tac = (TACS*) malloc(sizeof(TACS));
  470. build_tac(tree, gen_tac);
  471. print_tac(gen_tac->list);
  472. compile_tac(gen_tac->list);
  473. }
  474. extern int yydebug;
  475. #ifdef __APPLE__
  476. extern NODE* yyparse(void);
  477. #endif
  478. extern NODE* ans;
  479. extern void init_symbtable(void);
  480. int main(int argc, char** argv)
  481. {
  482. NODE* tree;
  483. if (argc>1 && strcmp(argv[1],"-d")==0) debug = 1;
  484. init_symbtable();
  485. printf("--C COMPILER\n");
  486. yyparse();
  487. tree = ans;
  488. printf("parse finished\n");
  489. print_tree(tree);
  490. interpret_tree(tree);
  491. return 0;
  492. }