Year 2 compilers coureswork

main.c 17KB

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