t_quad_arg quadruple_call(t_quad_arg arg1) { t_quad_arg rt; quadruple[quadruple_top].op = QUAD_CALL; quadruple[quadruple_top].arg1 = arg1; rt.arg_code = ARG_TEMP_IDX; rt.val.int_val = push_temp(); quadruple[quadruple_top].arg2 = rt; quadruple[quadruple_top].result.arg_code = 0; quadruple_top++; return rt; }
t_quad_arg quadruple_add(t_quad_arg arg1, t_quad_arg arg2) { t_quad_arg rt; quadruple[quadruple_top].op = QUAD_ADD; quadruple[quadruple_top].arg1 = arg1; quadruple[quadruple_top].arg2 = arg2; rt.arg_code = ARG_TEMP_IDX; rt.val.int_val = push_temp(); quadruple[quadruple_top].result = rt; quadruple_top++; return rt; }
void gencode (tree * n) { // custion : only value that are not used after calling another gencode // cuz these values are not re-entrent static int param_count = 0; // ok struct SymbolTable *st; char *t1, *t2, new_tmp[MAX_VAR_NAME]; if (n == NULL) return; if (isleaf (n)) { checktype(n); if(istemp(name(n))) push_temp(name(n)); else push(name(n)); return; } switch(n->type) { case t_assign: if(isleaf(n->right)) { fprintf(out, "%s\t:=\t%s\n", name(n->left), name(n->right)); break; } gencode(n->right->left); gencode(n->right->right); fprintf(out, "%s\t:=\t%s\t%s\t%s\n", name(n->left), pop(), operation(n->right), pop()); break; case t_op: gencode(n->right); gencode(n->left); if(top()->temp) { t1 = pop(); t2 = pop(); fprintf(out, "%s\t:=\t%s\t%s\t%s\n", t1, t1, operation(n), t2); push_temp(t1); break; } t1 = pop(); t2 = pop(); sprintf(new_tmp, "_t%d", last_temp++); fprintf(out, "%s\t:=\t%s\t%s\t%s\n", new_tmp, t1, operation(n), t2); push_temp(new_tmp); break; case t_goto: st = lookup(name(n->left)); if(st && (gettype(name(n->left)) == LABEL)) fprintf(out, "%s\t%s\n", operation(n), name(n->left)); else { add(name(n->left), LABEL); st = lookup(name(n->left)); st->ok = 0; // waitting to see label defination fprintf(stderr, "Warning: waitting to see label(%s)\n", name(n->left)); } break; case t_while: { int Lbegin = newlabel(); int Lend = newlabel(); fprintf(out, "_l%d\t:\n", Lbegin); if(isleaf(n->left)) { fprintf(out, "if\t%s\t=\t0\tgoto\t_l%d\n", name(n->left), Lend); } else { /* TODO : it SHLULD be relop but we dont check */ gencode(n->left->left); gencode(n->left->right); fprintf(out, "if\t%s\t%s\t%s\tgoto\t_l%d\n", pop(), neg_operation(n->left), pop(), Lend); } gencode(n->right); fprintf(out, "goto\t_l%d\n", Lbegin); fprintf(out, "_l%d\t:\n", Lend); break; } case t_for: fprintf(stderr, "No impl for FOR yet!\n"); break; case t_sub: gencode(n->right); fprintf(out, "call\t%s\t%d\n", n->left->value.idval, param_count); param_count = 0; break; case t_param: gencode(n->left); fprintf(out, "param\t%s\n", pop()); param_count++; if(n->right) gencode(n->right); break; case t_if: { int L = newlabel(); if(isleaf(n->left)) { fprintf(out, "if\t%s\t=\t0\tgoto\t_l%d\n", name(n->left), L); } else { /* TODO : it SHLULD be relop but we dont check */ gencode(n->left->left); gencode(n->left->right); fprintf(out, "if\t%s\t%s\t%s\tgoto\t_l%d\n", pop(), operation(n->left), pop(), L); } gencode(n->right->left); // else if(n->right->right != NULL) { int L2 = newlabel(); fprintf(out, "goto\t_l%d\n", L2); fprintf(out, "_l%d\t:\n", L); gencode(n->right->right); fprintf(out, "_l%d\t:\n", L2); } else { fprintf(out, "_l%d\t:\n", L); } break; } case t_join: if(n->op == LABEL_JOIN) { add(n->left->value.idval, LABEL); fprintf(out, "%s\t:\n", n->left->value.idval); } else gencode(n->left); gencode(n->right); break; case t_block: gencode(n->left); break; } // switch }