Year 2 compilers coureswork

main.c 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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. if (op == 280) printf("closure: %s\n", stok(elem->dst));
  129. }
  130. void print_tac(TLIST* tac_list) {
  131. TLIST *ptr = tac_list;
  132. while (ptr != NULL) {
  133. print_tac_el(ptr->elem);
  134. ptr = ptr->next;
  135. }
  136. }
  137. int invert_op(int op) {
  138. if (op == LE_OP) {
  139. return '>';
  140. } else if (op == GE_OP) {
  141. return '<';
  142. } else if (op == '>') {
  143. return LE_OP;
  144. } else if (op == '<') {
  145. return GE_OP;
  146. } else if (op == EQ_OP) {
  147. return NE_OP;
  148. } else if (op == NE_OP) {
  149. return EQ_OP;
  150. } else {
  151. printf("Unknown operator: %c", op);
  152. exit(1);
  153. }
  154. }
  155. int count_args(NODE *tree) {
  156. NODE *tmp = tree;
  157. int a = 1;
  158. while (tmp != NULL) {
  159. if (tmp->type != ',') {
  160. break;
  161. }
  162. tmp = tmp->left;
  163. a++;
  164. }
  165. return a;
  166. }
  167. void populate_arg_list(NODE *tree, TOKEN** arr, int arr_len) {
  168. if (tree->type == '~') {
  169. for (int i = 0; i < arr_len; i++) {
  170. if (arr[i] == NULL) {
  171. TOKEN* name = (TOKEN*)tree->right->left;
  172. arr[i] = name;
  173. break;
  174. }
  175. }
  176. } else {
  177. populate_arg_list(tree->left, arr, arr_len);
  178. populate_arg_list(tree->right, arr, arr_len);
  179. }
  180. }
  181. TOKEN** get_argument_list(NODE *tree) {
  182. int num_args = count_args(tree->left->right->right);
  183. TOKEN** arr = (TOKEN**) malloc(sizeof(TOKEN*) * num_args);
  184. populate_arg_list(tree->left->right->right, arr, num_args);
  185. return arr;
  186. }
  187. void populate_val_list(NODE* tree, NODE** arr, int num_args) {
  188. if (tree->type == ',') {
  189. populate_val_list(tree->left, arr, num_args);
  190. populate_val_list(tree->right, arr, num_args);
  191. } else {
  192. for (int i = 0; i < num_args; i++) {
  193. if (arr[i] == NULL) {
  194. arr[i] = tree;
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. NODE** get_val_list(NODE *tree) {
  201. int num_args = count_args(tree);
  202. NODE** arr = (NODE**) malloc(sizeof(NODE*) * num_args);
  203. populate_val_list(tree, arr, num_args);
  204. return arr;
  205. }
  206. TOKEN* build_tac(NODE *tree, TACS* tac, TACS* after_tac) {
  207. if (tree == NULL) return NULL;
  208. int type = tree->type;
  209. if (type == LEAF) {
  210. return (TOKEN *) tree->left;
  211. } else if (type == '=') {
  212. TOKEN* dst = (TOKEN*) tree->left->left;
  213. TOKEN* result = build_tac(tree->right, tac, after_tac);
  214. new_tac(tac, dst, result, NULL, tree->type);
  215. } else if (type=='+' || type=='-' || type=='*' || type=='/' || type =='%') {
  216. TOKEN* dst = gen_tmp();
  217. TOKEN* src = build_tac(tree->left, tac, after_tac);
  218. TOKEN* tgt = build_tac(tree->right, tac, after_tac);
  219. new_tac(tac, dst, src, tgt, tree->type);
  220. return dst;
  221. } else if (type == IF) {
  222. int op = invert_op(tree->left->type);
  223. TOKEN* lhs = build_tac(tree->left->left, tac, after_tac);
  224. TOKEN* rhs = build_tac(tree->left->right, tac, after_tac);
  225. TOKEN* label = gen_label();
  226. new_tac(tac, label, lhs, rhs, op);
  227. if (tree->right->type == ELSE) {
  228. TOKEN* cont = gen_label();
  229. build_tac(tree->right->left, tac, after_tac);
  230. new_tac(tac, cont, NULL, NULL, VOID);
  231. new_tac(tac, label, NULL, NULL, IDENTIFIER);
  232. build_tac(tree->right->right, tac, after_tac);
  233. new_tac(tac, cont, NULL, NULL, IDENTIFIER);
  234. } else {
  235. build_tac(tree->right, tac, after_tac);
  236. new_tac(tac, label, NULL, NULL, IDENTIFIER);
  237. }
  238. } else if (type == RETURN) {
  239. TOKEN* src = build_tac(tree->left, tac, after_tac);
  240. new_tac(tac, NULL, src, NULL, RETURN);
  241. } else if (type == 'D') {
  242. TACS* gen_tac = (TACS*) malloc(sizeof(TACS));
  243. new_tac(after_tac, (TOKEN*) tree->left->right->left->left, NULL, NULL, 'D');
  244. if (tree->left->right->right != NULL) {
  245. TOKEN** arg_list = get_argument_list(tree);
  246. int arg_count = count_args(tree->left->right->right);
  247. for (int i = 0; i < arg_count; i++) {
  248. new_tac(after_tac, arg_list[i], NULL, NULL, AUTO);
  249. }
  250. }
  251. build_tac(tree->right, after_tac, gen_tac);
  252. new_tac(after_tac, (TOKEN*) tree->left->right->left->left, NULL, NULL, 279);
  253. if (tac != after_tac) {
  254. new_tac(tac, (TOKEN*) tree->left->right->left->left, NULL, NULL, 280);
  255. }
  256. append_tac(tac->list, gen_tac->list);
  257. } else if (type == APPLY) {
  258. TOKEN* ret_val = gen_tmp();
  259. if (tree->right != NULL) {
  260. int num_args;
  261. NODE **val_list;
  262. num_args = count_args(tree->right);
  263. val_list = get_val_list(tree->right);
  264. TOKEN* arg_tokens[num_args];
  265. for (int i = 0; i < num_args; i++) {
  266. arg_tokens[i] = build_tac(val_list[i], tac, after_tac);
  267. }
  268. for (int i = 0; i < num_args; i++) {
  269. new_tac(tac, arg_tokens[i], NULL, NULL, 278);
  270. }
  271. }
  272. new_tac(tac, (TOKEN*) tree->left->left, NULL, ret_val, APPLY);
  273. return ret_val;
  274. } else {
  275. build_tac(tree->left, tac, after_tac);
  276. build_tac(tree->right, tac, after_tac);
  277. return NULL;
  278. }
  279. return NULL;
  280. }
  281. int tmp_regs[10] = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25};
  282. int svd_regs[8] = {16, 17, 18, 19, 20, 21, 22, 23};
  283. int arg_regs[3] = {5, 6, 7};
  284. int tmp_cntr = 0;
  285. int register_me(TOKEN* name, ENV* env) {
  286. if (tmp_cntr == 10) tmp_cntr = 0;
  287. if (name->type == CONSTANT) {
  288. if (name->value == 0) {
  289. return 0;
  290. } else {
  291. printf("li $%d, %d\n", tmp_regs[tmp_cntr], name->value);
  292. return tmp_regs[tmp_cntr++];
  293. }
  294. } else {
  295. BIND* binding = find_name_in_list(name, env->bindings);
  296. if (binding == NULL) {
  297. BIND* new_bind;
  298. if (name->lexeme[0] != '$') {
  299. new_bind = create_binding(name, env->counter++, NULL);
  300. if (env->bindings == NULL) env->bindings = create_list(new_bind, NULL);
  301. else append_list(env->bindings, new_bind);
  302. new_bind->is_saved = 1;
  303. return svd_regs[new_bind->env_offset];
  304. } else {
  305. new_bind = create_binding(name, tmp_cntr++, NULL);
  306. if (env->bindings == NULL) env->bindings = create_list(new_bind, NULL);
  307. else append_list(env->bindings, new_bind);
  308. return tmp_regs[new_bind->env_offset];
  309. }
  310. } else {
  311. return binding->is_saved ? svd_regs[binding->env_offset] : tmp_regs[binding->env_offset];
  312. }
  313. }
  314. }
  315. void alloc_function_env() {
  316. printf("li $a0, 68\n");
  317. printf("li $v0, 9\n");
  318. printf("syscall\n");
  319. }
  320. void compile_tac(TLIST* tacs) {
  321. ENV* env = create_new_function_env(NULL, NULL);
  322. printf("=====\n");
  323. alloc_function_env();
  324. printf("or $fp, $0, $v0\n");
  325. printf("la $t0, main\n");
  326. printf("sw $t0, 0($fp)\n");
  327. printf("sw $0, 4($fp)\n");
  328. printf("jal main\n");
  329. printf("j done\n");
  330. while(tacs != NULL) {
  331. TAC_T* t = tacs->elem;
  332. if (debug) {
  333. printf("#");
  334. print_tac_el(t);
  335. }
  336. if (t->op == '=') {
  337. int src = register_me(t->src, env);
  338. int dst = register_me(t->dst, env);
  339. printf("or $%d, $0, $%d\n", dst, src);
  340. }
  341. if (t->op == 'D') {
  342. env = create_new_function_env(NULL, env);
  343. printf("%s:\n", t->dst->lexeme);
  344. alloc_function_env();
  345. printf("sw $fp, 4($v0)\n");
  346. if (env->previous->bindings != NULL) {
  347. int i = 2;
  348. BLIST* ptr = env->previous->bindings;
  349. while (ptr != NULL) {
  350. if (ptr->binding->name->lexeme[0] != '$') {
  351. printf("sw $%d, %d($fp)\n", svd_regs[ptr->binding->env_offset], i*4);
  352. i++;
  353. }
  354. ptr = ptr->next;
  355. }
  356. }
  357. printf("or $fp, $0, $v0\n");
  358. printf("la $t0, %s\n", stok(t->dst));
  359. printf("sw $t0, 0($fp)\n");
  360. printf("sw $ra, 64($fp)\n");
  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("add $%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("sub $%d, $%d, $%d\n", dst, src, tgt);
  373. }
  374. if (t->op == '*') {
  375. int src = register_me(t->src, env);
  376. int dst = register_me(t->dst, env);
  377. int tgt = register_me(t->tgt, env);
  378. printf("mult $%d, $%d\n", src, tgt);
  379. printf("mflo $%d\n", dst);
  380. }
  381. if (t->op == '/') {
  382. int src = register_me(t->src, env);
  383. int dst = register_me(t->dst, env);
  384. int tgt = register_me(t->tgt, env);
  385. printf("div $%d, $%d\n", src, tgt);
  386. printf("mflo $%d\n", dst);
  387. }
  388. if (t->op == '%') {
  389. int src = register_me(t->src, env);
  390. int dst = register_me(t->dst, env);
  391. int tgt = register_me(t->tgt, env);
  392. printf("div $%d, $%d\n", src, tgt);
  393. printf("mfhi $%d\n", dst);
  394. }
  395. if (t->op == LE_OP) {
  396. int src = register_me(t->src, env);
  397. int tgt = register_me(t->tgt, env);
  398. printf("ble $%d, $%d, %s\n", src, tgt, stok(t->dst));
  399. }
  400. if (t->op == GE_OP) {
  401. int src = register_me(t->src, env);
  402. int tgt = register_me(t->tgt, env);
  403. printf("bge $%d, $%d, %s\n", src, tgt, stok(t->dst));
  404. }
  405. if (t->op == EQ_OP) {
  406. int src = register_me(t->src, env);
  407. int tgt = register_me(t->tgt, env);
  408. printf("beq $%d, $%d, %s\n", src, tgt, stok(t->dst));
  409. }
  410. if (t->op == NE_OP) {
  411. int src = register_me(t->src, env);
  412. int tgt = register_me(t->tgt, env);
  413. printf("bne $%d, $%d, %s\n", src, tgt, stok(t->dst));
  414. }
  415. if (t->op == '>') {
  416. int src = register_me(t->src, env);
  417. int tgt = register_me(t->tgt, env);
  418. printf("bgt $%d, $%d, %s\n", src, tgt, stok(t->dst));
  419. }
  420. if (t->op == '<') {
  421. int src = register_me(t->src, env);
  422. int tgt = register_me(t->tgt, env);
  423. printf("blt $%d, $%d, %s\n", src, tgt, stok(t->dst));
  424. }
  425. if (t->op == APPLY) {
  426. int tgt_idx = register_me(t->tgt, env);
  427. env->arg_counter = 0;
  428. printf("jal %s\n", stok(t->dst));
  429. printf("lw $fp, 4($fp)\n");
  430. printf("lw $ra, 64($fp)\n");
  431. if (env->bindings != NULL) {
  432. int i = 2;
  433. BLIST* ptr = env->bindings;
  434. while (ptr != NULL) {
  435. if (ptr->binding->name->lexeme[0] != '$') {
  436. printf("lw $%d, %d($fp)\n", svd_regs[ptr->binding->env_offset], i*4);
  437. i++;
  438. }
  439. ptr = ptr->next;
  440. }
  441. }
  442. printf("or $%d, $0, $v1\n", tgt_idx);
  443. }
  444. if (t->op == IDENTIFIER) {
  445. printf("%s:\n", stok(t->dst));
  446. }
  447. if (t->op == VOID) {
  448. printf("j %s\n", stok(t->dst));
  449. }
  450. if (t->op == RETURN) {
  451. int src_idx = register_me(t->src, env);
  452. printf("or $v1, $0, $%d\n", src_idx);
  453. printf("jr $31\n");
  454. }
  455. if (t->op == 279) {
  456. env = env->previous;
  457. }
  458. if (t->op == 278) {
  459. int dst_idx = register_me(t->dst, env);
  460. printf("or $%d, $0, $%d\n", arg_regs[env->arg_counter], dst_idx);
  461. env->arg_counter++;
  462. }
  463. if (t->op == AUTO) {
  464. int dst_idx = register_me(t->dst, env);
  465. printf("or $%d, $0, $%d\n", dst_idx, arg_regs[env->param_counter]);
  466. env->param_counter++;
  467. }
  468. tacs = tacs->next;
  469. }
  470. printf("done:\n");
  471. printf("ori $v0, $0, 10\n");
  472. printf("syscall\n");
  473. }
  474. void interpret_tree(NODE *tree) {
  475. TACS* gen_tac = (TACS*) malloc(sizeof(TACS));
  476. build_tac(tree, gen_tac, gen_tac);
  477. print_tac(gen_tac->list);
  478. compile_tac(gen_tac->list);
  479. }
  480. extern int yydebug;
  481. #ifdef __APPLE__
  482. extern NODE* yyparse(void);
  483. #endif
  484. extern NODE* ans;
  485. extern void init_symbtable(void);
  486. int main(int argc, char** argv)
  487. {
  488. NODE* tree;
  489. if (argc>1 && strcmp(argv[1],"-d")==0) debug = 1;
  490. init_symbtable();
  491. printf("--C COMPILER\n");
  492. yyparse();
  493. tree = ans;
  494. printf("parse finished\n");
  495. print_tree(tree);
  496. interpret_tree(tree);
  497. return 0;
  498. }