MCAHead translate_Cond(Node *n, Var lt, Var lf, SymbolTable table, MCA mca) { assert(n->nodetype == Exp); Var v1, v2, v3; Node* child = n->children->head->next; MCAHead h; MCAHead h1, h2, h3, h4, h5; char *op; switch(n->seq) { case 3: //RELOP v1 = NewVar(PLACE); v1->ttype = TEMP; v2 = NewVar(PLACE); v2->ttype = TEMP; h1 = translate_Exp(NT_getChild(n, 0), table, v1, mca); h2 = translate_Exp(NT_getChild(n, 2), table, v2, mca); h3 = NewMCAHead(mca, NewMidCode(C_IF, v1, v2, lt)); h3->ptrtoe->op = NT_getChild(n, 1)->data.s; h4 = NewMCAHead(mca, NewMidCode(C_GOTO, lf, NULL, NULL)); h = LinkMulMCAHead(mca, 4, h1, h2, h3, h4); break; case 10: //NOT h = translate_Cond(NT_getChild(n, 1), lf, lt, table, mca); break; case 1: //AND v1 = NewVar(PLACE); v1->ttype = LABEL; h1 = translate_Cond(NT_getChild(n, 0), v1, lf, table, mca); h2 = NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)); h3 = translate_Cond(NT_getChild(n, 2), lt, lf, table, mca); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; case 2: //OR v1 = NewVar(PLACE); v1->ttype = LABEL; h1 = translate_Cond(NT_getChild(n, 0), lt, v1, table, mca); h2 = NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)); h3 = translate_Cond(NT_getChild(n, 2), lt, lf, table, mca); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; default: v1 = NewVar(PLACE); v1->ttype = TEMP; h1 = translate_Exp(child, table, v1, mca); v2 = NewVar(CON); v2->value = 0; h2 = NewMCAHead(mca, NewMidCode(C_IF, v1, v2, lt)); h3 = NewMCAHead(mca, NewMidCode(C_GOTO, lf, NULL, NULL)); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; } return h; }
intercodes translate_Cond(struct Node *node,operand label_true,operand label_false) { struct Node *child = node->child; assert(child != NULL); intercodes code1,code2,code3,code4; //Exp1 RELOP Exp2 if (child->sibling != NULL && strcmp(child->sibling->type,"RELOP") == 0) { operand t1 = new_tmp(); operand t2 = new_tmp(); code1 = translate_Exp(child,t1); code2 = translate_Exp(child->sibling->sibling,t2); relop_type type = get_relop(child->sibling); code3 = gen_triop(type,t1,t2,label_true); code4 = gen_one(GOTO_K,label_false); code1 = link(code1,code2); code1 = link(code1,code3); code1 = link(code1,code4); return code1; } //NOT Exp1 if (strcmp(child->type,"NOT") == 0) return translate_Cond(child->sibling,label_true,label_false); //Exp1 AND Exp2 if (child->sibling != NULL && strcmp(child->sibling->type,"AND") == 0) { operand label1 = new_label(); code1 = translate_Cond(child,label1,label_false); code2 = translate_Cond(child->sibling->sibling,label_true,label_false); code3 = gen_one(LABEL_K,label1); code1 = link(code1,code3); code1 = link(code1,code2); return code1; } //Exp1 OR Exp2 if (child->sibling != NULL && strcmp(child->sibling->type,"OR") == 0) { operand label1 = new_label(); code1 = translate_Cond(child,label_true,label1); code2 = translate_Cond(child->sibling->sibling,label_true,label_false); code3 = gen_one(LABEL_K,label1); code1 = link(code1,code3); code1 = link(code1,code2); return code1; } //other cases operand t1 = new_tmp(); code1 = translate_Exp(node,t1); operand c1 = new_constant(0); code2 = gen_triop(NE,t1,c1,label_true); code3 = gen_one(LABEL_K,label_false); code1 = link(code1,code2); code1 = link(code1,code3); return code1; }
InterCodeNode translate_Exp(treenode *Exp_n, Operand place){ if(Exp_n == NULL){ //deprintf("Exp is NULL\n"); return NULL; } switch(Exp_n->child_num){ case 1:{ treenode *node = Exp_n->node[0]; if(node->type == NODE_INT){ //exp -> int int value = node->ival; place->kind = CONSTANT; place->u.value = value; return NULL; }else if(node->type == NODE_FLOAT){ //exp -> float //printf("******* No Float Type *******\n"); //exit(1); return NULL; }else{ //exp -> id treenode *id = Exp_n->node[0]; char *name = id->idval; struct Var_info *var = fetchVarInfo(name); if(var != NULL){ place->u.var_no = var->var_no; if(var->type == BASIC || var->type == ARRAY){ place->kind = VARIABLE; }else if(var->type == STRUCT){ place->kind = REFERENCE; } }else{ //deprintf("**** can not find var in VarInfo ****\n"); } return NULL; } break; } case 2:{ treenode *op = Exp_n->node[0]; treenode *exp = Exp_n->node[1]; if(strcmp(op->operval,"MINUS") == 0){ //MINUS exp //- exp Operand temp = new_Operand(); InterCodeNode node1 = translate_Exp(exp,temp); if(temp->kind == CONSTANT){ place->kind = CONSTANT; place->u.value = -(temp->u.value); return NULL; }else{ Operand zero = new_Operand(); zero->kind = CONSTANT; zero->u.value = 0; InterCode sub_code = new_InterCode(); sub_code->kind = SUB; sub_code->u.binop.result = place; sub_code->u.binop.op1 = zero; sub_code->u.binop.op2 = temp; InterCodeNode node2 = produceNodeByCode(sub_code); return produceNodeByNode(node1,node2); } }else if(strcmp(op->operval,"NOT") == 0){ //NOT exp //! exp Operand label1 = new_Label(); Operand label2 = new_Label(); Operand zero = new_Operand(); zero->kind = CONSTANT; zero->u.value = 0; Operand one = new_Operand(); one->kind = CONSTANT; one->u.value = 1; InterCode code0 = new_InterCode(); code0->kind = ASSIGN; code0->u.assign.left = place; code0->u.assign.right = zero; InterCodeNode node0 = produceNodeByCode(code0); InterCodeNode node1 = translate_Cond(Exp_n,label1,label2); InterCode code2 = new_InterCode(); code2->kind = LABEL; code2->u.label.label_op = label1; InterCodeNode node2 = NULL;//produceNodeByCode(code2); InterCode code3 = new_InterCode(); code3->kind = ASSIGN; code3->u.assign.left = place; code3->u.assign.right = one; InterCodeNode node3 = produceNodeByCode(code3); InterCode code4 = new_InterCode(); code4->kind = LABEL; code4->u.label.label_op = label2; InterCodeNode node4 = produceNodeByCode(code4); InterCodeNode temp1 = produceNodeByNode(node0,node1); InterCodeNode temp2 = produceNodeByNode(temp1,node2); InterCodeNode temp3 = produceNodeByNode(temp2,node3); return produceNodeByNode(temp3,node4); }else{ return NULL; } break; } case 3:{ treenode *prev = Exp_n->node[0]; treenode *midd = Exp_n->node[1]; treenode *next = Exp_n->node[2]; if(strcmp(midd->operval,"ASSIGNOP") == 0){ //exp = exp Operand left = new_Operand(); Operand right = new_Temp(); InterCodeNode node1 = translate_Exp(prev,left); InterCodeNode node2 = translate_Exp(next,right); //show(node1); //printf("**** split node ****\n"); //show(node2); InterCode assign_code = new_InterCode(); assign_code->kind = ASSIGN; assign_code->u.assign.left = left; assign_code->u.assign.right = right; place = left; InterCodeNode node3 = produceNodeByCode(assign_code); //printf("**** show node3 ****\n"); //show(node3); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"PLUS") == 0){ //exp + exp Operand temp1 = new_Temp(); Operand temp2 = new_Temp(); InterCodeNode node1 = translate_Exp(prev,temp1); InterCodeNode node2 = translate_Exp(next,temp2); if(temp1->kind == CONSTANT && temp2->kind == CONSTANT){ place->kind = CONSTANT; place->u.value = temp1->u.value + temp2->u.value; return NULL; } InterCode plus_code = new_InterCode(); plus_code->kind = ADD; plus_code->u.binop.result = place; plus_code->u.binop.op1 = temp1; plus_code->u.binop.op2 = temp2; InterCodeNode node3 = produceNodeByCode(plus_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"MINUS") == 0){ //exp - exp Operand temp1 = new_Temp(); Operand temp2 = new_Temp(); InterCodeNode node1 = translate_Exp(prev,temp1); InterCodeNode node2 = translate_Exp(next,temp2); if(temp1->kind == CONSTANT && temp2->kind == CONSTANT){ place->kind = CONSTANT; place->u.value = temp1->u.value - temp2->u.value; return NULL; } // if(temp1->kind == temp2->kind && temp1->kind == VARIABLE){ // if(temp1->u.var_no == temp2->u.var_no){ // place->kind = CONSTANT; // place->u.value = 0; // } // } InterCode minus_code = new_InterCode(); minus_code->kind = SUB; minus_code->u.binop.result = place; minus_code->u.binop.op1 = temp1; minus_code->u.binop.op2 = temp2; InterCodeNode node3 = produceNodeByCode(minus_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"STAR") == 0){ //exp * exp Operand temp1 = new_Temp(); Operand temp2 = new_Temp(); InterCodeNode node1 = translate_Exp(prev,temp1); InterCodeNode node2 = translate_Exp(next,temp2); if(temp1->kind == CONSTANT && temp2->kind == CONSTANT){ place->kind = CONSTANT; place->u.value = temp1->u.value * temp2->u.value; return NULL; } InterCode star_code = new_InterCode(); star_code->kind = MUL; star_code->u.binop.result = place; star_code->u.binop.op1 = temp1; star_code->u.binop.op2 = temp2; InterCodeNode node3 = produceNodeByCode(star_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"DIV") == 0){ //exp / exp Operand temp1 = new_Temp(); Operand temp2 = new_Temp(); InterCodeNode node1 = translate_Exp(prev,temp1); InterCodeNode node2 = translate_Exp(next,temp2); if(temp1->kind == CONSTANT && temp2->kind == CONSTANT){ place->kind = CONSTANT; place->u.value = (temp1->u.value) / (temp2->u.value); return NULL; } InterCode div_code = new_InterCode(); div_code->kind = DIV; div_code->u.binop.result = place; div_code->u.binop.op1 = temp1; div_code->u.binop.op2 = temp2; InterCodeNode node3 = produceNodeByCode(div_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"relop") == 0 || strcmp(midd->operval,"AND") == 0 || strcmp(midd->operval,"OR") == 0){ //exp relop exp //exp or exp //exp and exp Operand label1 = new_Label(); Operand label2 = new_Label(); Operand zero = new_Operand(); zero->kind = CONSTANT; zero->u.value = 0; Operand one = new_Operand(); one->kind = CONSTANT; one->u.value = 1; InterCode code0 = new_InterCode(); code0->kind = ASSIGN; code0->u.assign.left = place; code0->u.assign.right = zero; InterCodeNode node0 = produceNodeByCode(code0); InterCodeNode node1 = translate_Cond(Exp_n,label1,label2); InterCode code2 = new_InterCode(); code2->kind = LABEL; code2->u.label.label_op = label1; InterCodeNode node2 = NULL;//produceNodeByCode(code2); InterCode code3 = new_InterCode(); code3->kind = ASSIGN; code3->u.assign.left = place; code3->u.assign.right = one; InterCodeNode node3 = produceNodeByCode(code3); InterCode code4 = new_InterCode(); code4->kind = LABEL; code4->u.label.label_op = label2; InterCodeNode node4 = produceNodeByCode(code4); InterCodeNode temp1 = produceNodeByNode(node0,node1); InterCodeNode temp2 = produceNodeByNode(temp1,node2); InterCodeNode temp3 = produceNodeByNode(temp2,node3); return produceNodeByNode(temp3,node4); }else if(strcmp(prev->operval,"LP") == 0 && strcmp(next->operval,"RP") == 0){ //( exp ) return translate_Exp(midd,place); }else if(prev->type == NODE_ID && strcmp(next->operval,"RP") == 0){ //id () FieldList func = fetchFunc(prev->idval); if(func == NULL){ //deprintf("Can not find the function!\n"); return NULL; }else{ if(strcmp(func->name,"read") == 0){ InterCode read_code = new_InterCode(); read_code->kind = READ; read_code->u.read.arg = place; return produceNodeByCode(read_code); }else{ Operand func_op = new_Operand(); func_op->kind = FUNC; func_op->u.func_name = func->name; InterCode call_code = new_InterCode(); call_code->kind = CALL; call_code->u.call.result = place; call_code->u.call.function = func_op; return produceNodeByCode(call_code); } } }else if(strcmp(midd->operval,"DOT") == 0){ //Exp . id treenode *main_id = Exp_n->node[0]->node[0]; treenode *sub_id = Exp_n->node[2]; FieldList if_para = fetchPara(main_id->idval); FieldList para_field; if(if_para != NULL){ //in parameters para_field = (if_para->type->u).structure->tail; struct Var_info *var = fetchVarInfo(main_id->idval); if(var == NULL){ //printf("Can not find the Para\n"); return NULL; } int v_no = var->var_no; Operand temp_op = new_Operand(); temp_op->kind = ADDRESS; temp_op->u.var_no = v_no; if(strcmp(sub_id->idval,para_field->name) == 0){ //first field Operand temp = new_Temp(); place->kind = TEMP; place->u.temp_no = temp->u.temp_no; InterCode addr_code = new_InterCode(); addr_code->kind = ASSIGN; addr_code->u.assign.left = temp; addr_code->u.assign.right = temp_op; return produceNodeByCode(addr_code); }else{ int count = 0; while(para_field != NULL){ if(strcmp(sub_id->idval,para_field->name) == 0) break; count++; para_field = para_field->tail; } Operand res_op = new_Temp(); Operand op1 = new_Operand(); op1->kind = VARIABLE; op1->u.var_no = v_no; Operand op2 = new_Operand(); op2->kind = CONSTANT; op2->u.value = count*4; InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = res_op; add_code->u.binop.op1 = op1; add_code->u.binop.op2 = op2; InterCodeNode node1 = produceNodeByCode(add_code); Operand get_value = new_Operand(); get_value->kind = ADDRESS; get_value->u.temp_no = res_op->u.temp_no; Operand res1_op = new_Temp(); InterCode assign_code = new_InterCode(); assign_code->kind = ASSIGN; assign_code->u.assign.left = res1_op; assign_code->u.assign.right = get_value; InterCodeNode node2 = produceNodeByCode(assign_code); place->kind = TEMP; place->u.temp_no = res1_op->u.temp_no; return produceNodeByNode(node1,node2); } }else{ //not in parameters struct Var_info *var = fetchVarInfo(main_id->idval); if(var == NULL){ //printf("Can not find the Var_Info\n"); return NULL; } int v_no = var->var_no; Operand temp_op = new_Operand(); temp_op->kind = REFERENCE; temp_op->u.var_no = v_no; FieldList normal_var = fetchArg(main_id->idval); FieldList type_field = (normal_var->type->u).structure->tail; if(strcmp(sub_id->idval,type_field->name) == 0){ //first field Operand temp = new_Temp(); place->kind = ADDRESS; place->u.temp_no = temp->u.temp_no; InterCode addr_code = new_InterCode(); addr_code->kind = ASSIGN; addr_code->u.assign.left = temp; addr_code->u.assign.right = temp_op; return produceNodeByCode(addr_code); }else{ int count = 0; while(type_field != NULL){ if(strcmp(sub_id->idval,type_field->name) == 0) break; count++; type_field = type_field->tail; } Operand res_op = new_Temp(); Operand op2 = new_Operand(); op2->kind = CONSTANT; op2->u.value = count*4; InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = res_op; add_code->u.binop.op1 = temp_op; add_code->u.binop.op2 = op2; InterCodeNode node1 = produceNodeByCode(add_code); place->kind = ADDRESS; place->u.temp_no = res_op->u.temp_no; return node1; } } } break; } case 4:{ if(strcmp(Exp_n->node[2]->name,"Args") == 0){ //id (args) treenode *id = Exp_n->node[0]; FieldList func = fetchFunc(id->idval); if(func == NULL){ //printf("**** Can not find the function ****\n"); return NULL; } arg_list = NULL; InterCodeNode node1 = translate_Args(Exp_n->node[2]); if(strcmp(func->name,"write") == 0){ InterCode write_code = new_InterCode(); write_code->kind = WRITE; write_code->u.write.arg = arg_list->op; InterCodeNode node2 = produceNodeByCode(write_code); return produceNodeByNode(node1,node2); }else{ OperandNode p = arg_list; InterCodeNode link_head = new_InterCodeNode(); while(p != NULL){ InterCode arg_code = new_InterCode(); arg_code->kind = ARG; arg_code->u.arg.arg_op = p->op; InterCodeNode node2 = produceNodeByCode(arg_code); //show(node2); produceNodeByNode(link_head,node2); p = p->next; } Operand func_op = new_Operand(); func_op->kind = FUNC; func_op->u.func_name = func->name; InterCode call_code = new_InterCode(); call_code->kind = CALL; call_code->u.call.result = place; call_code->u.call.function = func_op; InterCodeNode node3 = produceNodeByCode(call_code); InterCodeNode temp = produceNodeByNode(node1,link_head->next); return produceNodeByNode(temp,node3); } } if(strcmp(Exp_n->node[2]->name,"Exp") == 0){ //exp [exp] treenode *pre_exp = Exp_n->node[0]; if(pre_exp->child_num == 3){ //exp.id [exp] treenode *inner_exp = pre_exp->node[0]; if(inner_exp->child_num == 1){ //id.id[exp] return translate_ExpDotExp(Exp_n,place); }else if(inner_exp->child_num == 4){ //id[exp].id[exp] return NULL; } } treenode *id = pre_exp->node[0]; treenode *index = Exp_n->node[2]; FieldList if_para = fetchPara(id->idval); if(pre_exp->child_num == 4 || if_para != NULL){ printf("Can not translate the code: contain multidimensional array and function parameters of array type\n"); exit(1); }else{ struct Var_info *var = fetchVarInfo(id->idval); if(var == NULL){ return NULL; } Operand array_op = new_Operand(); array_op->kind = REFERENCE; array_op->u.var_no = var->var_no; if(index->node[0]->type == NODE_INT){ // id [int] int size = index->node[0]->ival; if(size == 0){ Operand t1 = new_Temp(); InterCode assign_code = new_InterCode(); assign_code->kind = ASSIGN; assign_code->u.assign.left = t1; assign_code->u.assign.right = array_op; place->kind = ADDRESS; place->u.temp_no = t1->u.temp_no; return produceNodeByCode(assign_code); }else{ Operand res_op = new_Temp(); Operand offset_num = new_Operand(); offset_num->kind = CONSTANT; offset_num->u.value = size*4; InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = res_op; add_code->u.binop.op1 = array_op; add_code->u.binop.op2 = offset_num; place->kind = ADDRESS; place->u.temp_no = res_op->u.temp_no; return produceNodeByCode(add_code); } }else if(index->node[0]->type == NODE_ID){ //id [id] char *name = index->node[0]->idval; struct Var_info *var1 = fetchVarInfo(name); Operand res_op = new_Temp(); Operand op1 = new_Operand(); op1->kind = VARIABLE; op1->u.var_no = var1->var_no; Operand op2 = new_Operand(); op2->kind = CONSTANT; op2->u.value = 4; InterCode mul_code = new_InterCode(); mul_code->kind = MUL; mul_code->u.binop.result = res_op; mul_code->u.binop.op1 = op1; mul_code->u.binop.op2 = op2; InterCodeNode node1 = produceNodeByCode(mul_code); Operand res2_op = new_Temp(); InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = res2_op; add_code->u.binop.op1 = array_op; add_code->u.binop.op2 = res_op; InterCodeNode node2 = produceNodeByCode(add_code); place->kind = ADDRESS; place->u.temp_no = res2_op->u.temp_no; return produceNodeByNode(node1,node2); }else{ //exp Operand t1 = new_Temp(); InterCodeNode node1 = translate_Exp(index,t1); Operand t2 = new_Operand(); t2->kind = CONSTANT; t2->u.value = 4; Operand res_op = new_Temp(); InterCode mul_code = new_InterCode(); mul_code->kind = MUL; mul_code->u.binop.result = res_op; mul_code->u.binop.op1 = t1; mul_code->u.binop.op2 = t2; InterCodeNode node2 = produceNodeByCode(mul_code); Operand res2_op = new_Temp(); InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = res2_op; add_code->u.binop.op1 = res_op; add_code->u.binop.op2 = array_op; InterCodeNode node3 = produceNodeByCode(add_code); place->kind = ADDRESS; place->u.temp_no = res2_op->u.temp_no; InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); } } } break; } } }
InterCodeNode translate_Stmt(treenode *Stmt_n){ if(Stmt_n == NULL){ //deprintf("Stmt is NULL\n"); return NULL; } if(Stmt_n->child_num == 1){ //compst return translate_CompSt(Stmt_n->node[0]); }else if(Stmt_n->child_num == 2){ //exp ; Operand temp = new_Operand(); return translate_Exp(Stmt_n->node[0],temp); }else if(Stmt_n->child_num == 3){ //return exp ; Operand temp = new_Temp(); InterCodeNode node1 = translate_Exp(Stmt_n->node[1],temp); InterCode ret_code = new_InterCode(); ret_code->kind = RETURN; ret_code->u.retn.return_op = temp; InterCodeNode node2 = produceNodeByCode(ret_code); return produceNodeByNode(node1,node2); }else if(Stmt_n->child_num == 5){ treenode *head = Stmt_n->node[0]; if(strcmp(head->operval,"IF") == 0){ //if (exp) stmt Operand label1 = new_Label(); Operand label2 = new_Label(); InterCodeNode node1 = translate_Cond(Stmt_n->node[2],label1,label2); InterCodeNode node3 = translate_Stmt(Stmt_n->node[4]); InterCode code2 = new_InterCode(); code2->kind = LABEL; code2->u.label.label_op = label1; InterCodeNode node2 = NULL;//produceNodeByCode(code2); InterCode code4 = new_InterCode(); code4->kind = LABEL; code4->u.label.label_op = label2; InterCodeNode node4 = produceNodeByCode(code4); InterCodeNode temp1 = produceNodeByNode(node1,node2); InterCodeNode temp2 = produceNodeByNode(temp1,node3); return produceNodeByNode(temp2,node4); } if(strcmp(head->operval,"WHILE") == 0){ //while (exp) stmt Operand label1 = new_Label(); Operand label2 = new_Label(); Operand label3 = new_Label(); InterCode code1 = new_InterCode(); code1->kind = LABEL; code1->u.label.label_op = label1; InterCodeNode node1 = produceNodeByCode(code1); InterCodeNode node2 = translate_Cond(Stmt_n->node[2],label2,label3); InterCode code3 = new_InterCode(); code3->kind = LABEL; code3->u.label.label_op = label2; InterCodeNode node3 = NULL;//produceNodeByCode(code3); InterCodeNode node4 = translate_Stmt(Stmt_n->node[4]); InterCode code5 = new_InterCode(); code5->kind = GOTO; code5->u.label.label_op = label1; InterCodeNode node5 = produceNodeByCode(code5); InterCode code6 = new_InterCode(); code6->kind = LABEL; code6->u.label.label_op = label3; InterCodeNode node6 = produceNodeByCode(code6); InterCodeNode temp1 = produceNodeByNode(node1,node2); InterCodeNode temp2 = produceNodeByNode(temp1,node3); InterCodeNode temp3 = produceNodeByNode(temp2,node4); InterCodeNode temp4 = produceNodeByNode(temp3,node5); return produceNodeByNode(temp4,node6); } }else if(Stmt_n->child_num == 7){ //if (exp) stmt else stmt Operand label1 = new_Label(); Operand label2 = new_Label(); Operand label3 = new_Label(); InterCodeNode node1 = translate_Cond(Stmt_n->node[2],label1,label2); InterCode code2 = new_InterCode(); code2->kind = LABEL; code2->u.label.label_op = label1; InterCodeNode node2 = NULL;//produceNodeByCode(code2); InterCodeNode node3 = translate_Stmt(Stmt_n->node[4]); InterCode code4 = new_InterCode(); code4->kind = GOTO; code4->u.label.label_op = label3; InterCodeNode node4 = produceNodeByCode(code4); InterCode code5 = new_InterCode(); code5->kind = LABEL; code5->u.label.label_op = label2; InterCodeNode node5 = produceNodeByCode(code5); InterCodeNode node6 = translate_Stmt(Stmt_n->node[6]); InterCode code7 = new_InterCode(); code7->kind = LABEL; code7->u.label.label_op = label3; InterCodeNode node7 = produceNodeByCode(code7); InterCodeNode temp1 = produceNodeByNode(node1,node2); InterCodeNode temp2 = produceNodeByNode(temp1,node3); InterCodeNode temp3 = produceNodeByNode(temp2,node4); InterCodeNode temp4 = produceNodeByNode(temp3,node5); InterCodeNode temp5 = produceNodeByNode(temp4,node6); return produceNodeByNode(temp5,node7); }else{ //deprintf("**** Illegal Stmt Error ****\n"); return NULL; } }
InterCodeNode translate_Cond(treenode *cond,Operand label_t,Operand label_f){ if(cond == NULL){ //deprintf("Cond is NULL\n"); return NULL; } if(cond->child_num == 2){ treenode *op = cond->node[0]; treenode *exp = cond->node[1]; if(strcmp(op->operval,"NOT") == 0){ return translate_Cond(exp,label_f,label_t); } } if(cond->child_num == 3){ treenode *prev = cond->node[0]; treenode *midd = cond->node[1]; treenode *next = cond->node[2]; if(strcmp(midd->operval,"RELOP") == 0){ //exp relop exp Operand t1 = new_Temp(); Operand t2 = new_Temp(); InterCodeNode node1 = translate_Exp(prev,t1); InterCodeNode node2 = translate_Exp(next,t2); Operand relop = new_Operand(); relop->kind = RELOP_OP; strcpy(relop->u.relop_name,relopOpposite(midd->name)); InterCode relop_code = new_InterCode(); relop_code->kind = RELOP; relop_code->u.rel.op1 = t1; relop_code->u.rel.op2 = t2; relop_code->u.rel.relop_op = relop; relop_code->u.rel.label_op = label_f; InterCodeNode node3 = produceNodeByCode(relop_code); /*InterCode gto_code = new_InterCode(); gto_code->kind = GOTO; gto_code->u.gto.label_op = label_f; InterCodeNode node4 = produceNodeByCode(gto_code);*/ InterCodeNode temp1 = produceNodeByNode(node1,node2); InterCodeNode temp2 = produceNodeByNode(temp1,node3); return temp2; }else if(strcmp(midd->operval,"AND") == 0){ // exp and exp Operand label1 = new_Label(); InterCodeNode node1 = translate_Cond(prev,label1,label_f); InterCodeNode node3 = translate_Cond(next,label_t,label_f); InterCode label_code = new_InterCode(); label_code->kind = LABEL; label_code->u.label.label_op = label1; InterCodeNode node2 = produceNodeByCode(label_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); }else if(strcmp(midd->operval,"OR") == 0){ // exp or exp Operand label1 = new_Label(); InterCodeNode node1 = translate_Cond(prev,label_t,label1); InterCodeNode node3 = translate_Cond(next,label_t,label_f); InterCode label_code = new_InterCode(); label_code->kind = LABEL; label_code->u.label.label_op = label1; InterCodeNode node2 = produceNodeByCode(label_code); InterCodeNode temp = produceNodeByNode(node1,node2); return produceNodeByNode(temp,node3); } } //other case Operand t1 = new_Temp(); InterCodeNode node1 = translate_Exp(cond,t1); Operand zero = new_Operand(); zero->kind = CONSTANT; zero->u.value = 0; Operand unequal = new_Operand(); unequal->kind = RELOP_OP; strcpy(unequal->u.relop_name,"=="); InterCode unequal_code = new_InterCode(); unequal_code->kind = RELOP; unequal_code->u.rel.op1 = t1; unequal_code->u.rel.relop_op = unequal; unequal_code->u.rel.op2 = zero; unequal_code->u.rel.label_op = label_f; InterCodeNode node2 = produceNodeByCode(unequal_code); // InterCode gto_code = new_InterCode(); // gto_code->kind = GOTO; // gto_code->u.gto.label_op = label_f; // InterCodeNode node3 = produceNodeByCode(gto_code); InterCodeNode temp = produceNodeByNode(node1,node2); return temp; }
MCAHead translate_Stmt(Node* n, SymbolTable table, MCA mca) { assert(n->nodetype == Stmt); Var v1, v2, v3; Node* child = n->children->head->next; MCAHead h; MCAHead h1, h2, h3, h4, h5, h6, h7; switch(n->seq) { case 0: //Exp h = translate_Exp(child, table, NULL, mca); break; case 1: //Compst return translate_CompSt(child, table, mca); break; case 2: //RETURN v1 = NewVar(PLACE); v1->ttype = TEMP; h1 = translate_Exp(child->next, table, v1, mca); h2 = NewMCAHead(mca, NewMidCode(C_RETURN, v1, NULL, NULL)); h = LinkMulMCAHead(mca, 2, h1, h2); break; case 3: //IF v1 = NewVar(PLACE); v1->ttype = LABEL; v2 = NewVar(PLACE); v2->ttype = LABEL; h1 = translate_Cond(child->next->next, v1, v2, table,mca); h2 = NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)); h3 = translate_Stmt(NT_getChild(n, 4), table, mca); h4 = NewMCAHead(mca, NewMidCode(C_LAB, v2, NULL, NULL)); h = LinkMulMCAHead(mca, 4, h1, h2, h3, h4); break; case 4: //IF ELSE v1 = NewVar(PLACE); v1->ttype = LABEL; v2 = NewVar(PLACE); v2->ttype = LABEL; v3 = NewVar(PLACE); v3->ttype = LABEL; h1 = translate_Cond(child->next->next, v1, v2, table,mca); h2 = NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)); h3 = translate_Stmt(NT_getChild(n, 4), table, mca); h4 = NewMCAHead(mca, NewMidCode(C_GOTO, v3, NULL, NULL)); h5 = NewMCAHead(mca, NewMidCode(C_LAB, v2, NULL, NULL)); h6 = translate_Stmt(NT_getChild(n, 6), table, mca); h7 = NewMCAHead(mca, NewMidCode(C_LAB, v3, NULL, NULL)); assert(h6 != NULL && h2 != NULL); h = LinkMulMCAHead(mca, 7, h1, h2, h3, h4, h5, h6, h7); break; case 5: //WHILE v1 = NewVar(PLACE); v1->ttype = LABEL; v2 = NewVar(PLACE); v2->ttype = LABEL; v3 = NewVar(PLACE); v3->ttype = LABEL; h1 = NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)); h2 = translate_Cond(NT_getChild(n, 2), v2, v3, table,mca); h3 = NewMCAHead(mca, NewMidCode(C_LAB, v2, NULL, NULL)); h4 = translate_Stmt(NT_getChild(n, 4), table, mca); h5 = NewMCAHead(mca, NewMidCode(C_GOTO, v1, NULL, NULL)); h6 = NewMCAHead(mca, NewMidCode(C_LAB, v3, NULL, NULL)); h = LinkMulMCAHead(mca, 6, h1, h2, h3, h4, h5, h6); break; } return h; }
MCAHead translate_Exp(Node *n, SymbolTable table, Var place, MCA mca) { assert(n->nodetype == Exp); Var v1, v2, v3, v4, v5; Node* child = n->children->head->next; Symbol symbol; MCAHead h; MCAHead h1, h2, h3, h4, h5; char *temp; Var vlist[12]; int vlistlen = 0; int t; switch(n->seq) { case 0: //ASSIGNOP v1 = NewVar(PLACE); v1->ttype = TEMP; h1 = translate_Exp(child, table, v1, mca); v2 = NewVar(PLACE); v2->ttype = TEMP; h2 = translate_Exp(child->next->next, table, v2, mca); h3 = NewMCAHead(mca, NewMidCode(C_ASSIGN, v1, v2, NULL)); h4 = genPlaceMidCode(mca, C_ASSIGN, place, v3, NULL); h = LinkMulMCAHead(mca, 4, h1, h2, h3, h4); break; case 1: case 2: case 3: case 10: //AND OR NOT RELOP v3 = NewVar(CON); v3->value = 0; h1 = genPlaceMidCode(mca, C_ASSIGN, place, v3, NULL); v1 = NewVar(PLACE); v1->ttype = LABEL; v2 = NewVar(PLACE); v2->ttype = LABEL; h2 = translate_Cond(n, v1, v2, table, mca); v3 = NewVar(CON); v3->value = 1; h = LinkMulMCAHead(mca, 5, h1, h2, NewMCAHead(mca, NewMidCode(C_LAB, v1, NULL, NULL)), genPlaceMidCode(mca, C_ASSIGN, place, v3, NULL), NewMCAHead(mca, NewMidCode(C_LAB, v2, NULL, NULL))); break; case 4: //PLUS v2 = NewVar(PLACE); v2->ttype = TEMP; h1 = translate_Exp(child, table, v2, mca); v3 = NewVar(PLACE); v3->ttype = TEMP; h2 = translate_Exp(child->next->next, table, v3, mca); h3 = genPlaceMidCode(mca, C_ADD, place, v2, v3); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; case 5: //MINUS v2 = NewVar(PLACE); v2->ttype = TEMP; h1 = translate_Exp(child, table, v2, mca); v3 = NewVar(PLACE); v3->ttype = TEMP; h2 = translate_Exp(child->next->next, table, v3, mca); h3 = genPlaceMidCode(mca, C_SUB, place, v2, v3); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; case 6: //STAR v2 = NewVar(PLACE); v2->ttype = TEMP; h1 = translate_Exp(child, table, v2, mca); v3 = NewVar(PLACE); v3->ttype = TEMP; h2 = translate_Exp(child->next->next, table, v3, mca); h3 = genPlaceMidCode(mca, C_MUL, place, v2, v3); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; case 7: //DIV v2 = NewVar(PLACE); v2->ttype = TEMP; h1 = translate_Exp(child, table, v2, mca); v3 = NewVar(PLACE); v3->ttype = TEMP; h2 = translate_Exp(child->next->next, table, v3, mca); h3 = genPlaceMidCode(mca, C_DIV, place, v2, v3); h = LinkMulMCAHead(mca, 3, h1, h2, h3); break; case 8: //LPRP h = translate_Exp(child->next, table, place, mca); break; case 9: //MINUS v1 = NewVar(PLACE); v1->ttype = TEMP; h1 = translate_Exp(child->next, table, v1, mca); v2 = NewVar(CON); v2->value = 0; h2 = genPlaceMidCode(mca, C_SUB, place, v2, v1); h = LinkMulMCAHead(mca, 2, h1, h2); break; case 11: //CALL v1 = NewVar(VAR); v1->name = NT_getChild(n, 0)->data.s; h1 = translate_Args(NT_getChild(n, 2), table, vlist, &vlistlen, mca); #ifdef debug printf("args\n"); printMCA(mca, h1); printf("args\n"); #endif if(strcmp(v1->name, "write") == 0) { h = LinkMulMCAHead(mca, 2, h1, NewMCAHead(mca, NewMidCode(C_WRITE, vlist[0], NULL, NULL))); } else { for(t = 0; t < vlistlen; t++) h1 = LinkMulMCAHead(mca, 2, h1, NewMCAHead(mca, NewMidCode(C_ARG, vlist[t], NULL, NULL))); h = LinkMulMCAHead(mca, 2, h1, genPlaceMidCode(mca, C_CALL, place, v1, NULL)); } break; case 12: //CALL NO ARG v1 = NewVar(VAR); v1->name = NT_getChild(n, 0)->data.s; if(strcmp(v1->name, "read") == 0) h = genPlaceMidCode(mca, C_READ, place, NULL, NULL); else h = genPlaceMidCode(mca, C_CALL, place, v1, NULL); break; case 13: //ARRAY if(NT_getChild(n, 0)->seq == 15) { temp = NT_getChild(NT_getChild(n, 0), 0)->data.s; symbol = LookUpSymbol(sts, NewSymbol(temp, NULL, -1)); if(n->syn == NULL) n->syn = NewSyn(); n->syn->SType = symbol->type->tv->array->elem; n->syn->symbol = symbol; v1 = NewVar(PLACE); v1->ttype = TEMP; h1 = translate_Exp(NT_getChild(n, 2), table, v1, mca); v2 = NewVar(CON); v2->value = n->syn->SType->width; v3 = NewVar(TEMP); n->syn->addr = v3; h2 = NewMCAHead(mca, NewMidCode(C_MUL, v3, v1, v2)); h = LinkMulMCAHead(mca, 2, h1, h2); } else { if(n->syn == NULL) n->syn = NewSyn(); h1 = translate_Exp(NT_getChild(n, 0), table, NULL, mca); n->syn->SType = NT_getChild(n, 0)->syn->SType->tv->array->elem; n->syn->symbol = NT_getChild(n, 0)->syn->symbol; v1 = NewVar(PLACE); v1->ttype = TEMP; h2 = translate_Exp(NT_getChild(n, 2), table, v1, mca); v2 = NewVar(TEMP); v3 = NewVar(CON); v3->value = n->syn->SType->width; h3 = NewMCAHead(mca, NewMidCode(C_MUL, v2, v1, v3)); v4 = NewVar(TEMP); n->syn->addr = v4; h4 = NewMCAHead(mca, NewMidCode(C_ADD, v4, NT_getChild(n, 0)->syn->addr, v2)); h = LinkMulMCAHead(mca, 4, h1, h2, h3, h4); } if(n->parent->nodetype != Exp || n->parent->seq != 13) { if(n->syn->symbol->type->ispointer) v1 = NewVar(VAR); else v1 = NewVar(GetADDR); v1->name = n->syn->symbol->name; v2 = NewVar(TEMP); h5 = NewMCAHead(mca, NewMidCode(C_ADD, v2, v1, n->syn->addr)); h = LinkMulMCAHead(mca, 2, h, h5); n->syn->addr = v2; changevar(place, n->syn->addr); place->kind = ADDR; char *temp = malloc(5); sprintf(temp, "t%d", place->var_no); place->name = temp; } break; case 14: //STRUCT break; case 15: //ID symbol = LookUpSymbol(sts, NewSymbol(child->data.s, NULL, -1)); switch(symbol->type->tn) { case BASIC: v2 = NewVar(VAR); v2->name = child->data.s; changevar(place, v2); //h = genPlaceMidCode(mca, C_ASSIGN, place, v2, NULL); h = NULL; break; case ARRAY: v2 = NewVar(GetADDR); v2->name = child->data.s; changevar(place, v2); h = NULL; break; case STRUCTURE: printf("%s", "Cannot translate: Code contains variables or parameters of structure type\n."); exit(0); break; } break; case 16: //INT v2 = NewVar(CON); v2->value = child->data.i; changevar(place, v2); // place = v2; //h = genPlaceMidCode(mca, C_ASSIGN, place, v2, NULL); h = NULL; break; case 17: //FLOAT break; } return h; }
InterCodes translate_Stmt(node* Stmt){ if(strcmp(Stmt->child->name,"Exp") == 0){ Operand t = new_temp(); return translate_Exp(Stmt->child,t); } else if(strcmp(Stmt->child->name,"CompSt") == 0){ return translate_Compst(Stmt->child); } else if(strcmp(Stmt->child->name,"RETURN") == 0){ Operand t1 = new_temp(); InterCodes codes1 = translate_Exp(Stmt->child->brother,t1); InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(RET); codes2->code->onlyop.op = t1; InterCodes_link(codes1,codes2); return codes1; } else if(strcmp(Stmt->child->name,"WHILE") == 0){ Operand label1 = new_label(); Operand label2 = new_label(); Operand label3 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(LAB); codes1->code->onlyop.op = label1; InterCodes codes2 = translate_Cond(Stmt->child->brother->brother, label2, label3); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(LAB); codes3->code->onlyop.op = label2; InterCodes codes4 = translate_Stmt(Stmt->child->brother->brother->brother->brother); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(GOTO); codes5->code->onlyop.op = label1; InterCodes codes6 = InterCodes_init(); codes6->code = new_interCode(LAB); codes6->code->onlyop.op = label3; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); InterCodes_link(codes1,codes6); return codes1; } //IF LP Exp RP Stmt1 else if(Stmt->child->brother->brother->brother->brother->brother == NULL){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = translate_Cond(Stmt->child->brother->brother, label1, label2); InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(LAB); codes2->code->onlyop.op = label1; InterCodes codes3 = translate_Stmt(Stmt->child->brother->brother->brother->brother); InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(LAB); codes4->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); return codes1; } //IF LP Exp RP Stmt1 ELSE Stmt2 else{ Operand label1 = new_label(); Operand label2 = new_label(); Operand label3 = new_label(); InterCodes codes1 = translate_Cond(Stmt->child->brother->brother, label1, label2); InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(LAB); codes2->code->onlyop.op = label1; InterCodes codes3 = translate_Stmt(Stmt->child->brother->brother->brother->brother); InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(GOTO); codes4->code->onlyop.op = label3; InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes codes6 = translate_Stmt(Stmt->child->brother->brother->brother->brother->brother->brother); InterCodes codes7 = InterCodes_init(); codes7->code = new_interCode(LAB); codes7->code->onlyop.op = label3; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); InterCodes_link(codes1,codes6); InterCodes_link(codes1,codes7); return codes1; } //else if(Stmt->child->brother-) }
InterCodes translate_Cond(node* exp,Operand true_place,Operand false_place){ if(strcmp(exp->child->name,"NOT")==0){ return translate_Cond(exp->child->brother,true_place,false_place); } else if(strcmp(exp->child->brother->name,"RELOP")==0){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = translate_Exp(exp->child,t1); InterCodes codes2 = translate_Exp(exp->child->brother->brother,t2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(COND); codes3->code->cond.op1 = t1; codes3->code->cond.op2 = t2; codes3->code->cond.op = new_operand(op,0); strcpy(codes3->code->cond.op->op,exp->child->brother->node_value); InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(GOTO); codes4->code->onlyop.op = true_place; InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(GOTO); codes5->code->onlyop.op = false_place; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } else if(strcmp(exp->child->brother->name,"AND")==0){ Operand label1 = new_label(); InterCodes codes1 = translate_Cond(exp->child, label1, false_place); InterCodes codes2 = translate_Cond(exp->child->brother->brother, true_place, false_place); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(LAB); codes3->code->onlyop.op = label1; InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes2); return codes1; } else if(strcmp(exp->child->brother->name,"OR")==0){ Operand label1 = new_label(); InterCodes codes1 = translate_Cond(exp->child, true_place, label1); InterCodes codes2 = translate_Cond(exp->child->brother->brother, true_place, false_place); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(LAB); codes3->code->onlyop.op = label1; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); return codes1; } else{ /*Operand t1 = new_temp() InterCodes codes1 = translate_Exp(Exp, sym_table, t1) code2 = [IF t1 != #0 GOTO label_true] return code1 + code2 + [GOTO label_false] */ } }
InterCodes translate_Exp(node* exp,Operand place){ //-------------------------------------------------Exp ASSIGNOP Exp if(exp->exp_type == 7){ Operand t = new_temp(); InterCodes codes1 ; codes1 = translate_Exp(exp->child->brother->brother,t); if(strcmp(exp->child->child->name,"ID")==0){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(0); codes2->code->assign.left = new_operand_name(exp->child->child->node_value); codes2->code->assign.right = t; InterCodes_link(codes1,codes2); /*if(place != NULL){ InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(0); codes3->code->assign.left = place; codes3->code->assign.right = codes2->code->assign.left; InterCodes_link(codes1,codes3); }*/ } else{ Operand t2 =new_temp(); InterCodes codes2 = translate_Exp(exp->child,t2); if(place != NULL){ InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(0); codes3->code->assign.left = place; codes3->code->assign.right = t2; InterCodes_link(codes1,codes3); } } return codes1; } //-------------------------------------------------Exp AND Exp else if(exp->exp_type == 8){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp OR Exp else if(exp->exp_type == 9){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp RELOP Exp else if(exp->exp_type == 10){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp PLUS Exp else if(exp->exp_type == 11){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(1);//plus codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //-------------------------------------------------Exp MINUS Exp else if(exp->exp_type == 12){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(2);//sub codes3->code->binop.result = place; codes3->code->binop.op1 = t2; codes3->code->binop.op2 = t1; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------Exp STAR Exp else if(exp->exp_type == 13){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(3);//star codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------Exp DIV Exp else if(exp->exp_type == 14){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(4);//div codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------LP Exp RP else if(exp->exp_type == 15){ return translate_Exp(exp->child->brother,place); } //--------------------------------------------------MINUS Exp else if(exp->exp_type == 16){ Operand t1 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother,t1); codes2->code = new_interCode(SUB); codes2->code->binop.result = place; t1->is_min = 1; codes2->code->binop.op1 = new_operand(1,0); codes2->code->binop.op2 = t1; InterCodes_link(codes1,codes2); return codes1; } //---------------------------------------------------NOT Exp else if(exp->exp_type == 17){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //---------------------------------------------------ID LP Args RP else if(exp->exp_type == 18){ Operand* arg_list = (Operand*)malloc(sizeof(Operand)*8); int arg_num = 0; InterCodes codes1 = translate_Args(exp->child->brother->brother,arg_list,&arg_num); if (strcmp(exp->child->node_value,"write")==0){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(WRITE); codes2->code->onlyop.op = arg_list[0]; InterCodes_link(codes1,codes2); return codes1; } int i = 0; for(;i < arg_num;i++){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(ARG);//codes2->code->kind = REFERENCE; //////////////////////////////// codes2->code->onlyop.op = arg_list[i]; InterCodes_link(codes1,codes2); } InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(CALL); codes3->code->assign.left = place; codes3->code->assign.right = new_operand_name(exp->child->node_value); InterCodes_link(codes1,codes3); return codes1; } //---------------------------------------------------ID LP RP else if(exp->exp_type == 19){ InterCodes codes = InterCodes_init(); if(strcmp(exp->child->node_value,"read")==0){ codes->code = new_interCode(READ); codes->code->onlyop.op = place; } /*else if(strcmp(exp->child->name,"write")==0){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(READ); codes->code->onlyop.op = place; }*/ else{ codes->code = new_interCode(CALL); codes->code->assign.left = place; codes->code->assign.right = new_operand_name(exp->child->name); } return codes; } //--------------------------------------------------Exp LB Exp RB else if(exp->exp_type == 20){ return translate_Array(exp,place); } //--------------------------------------------------Exp DOT ID else if(exp->exp_type == 21){ return translate_Struct(exp,place); } //---------------------------------------------------ID else if(exp->exp_type == 22){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(0); codes->code->assign.right = new_operand_name(exp->node_value); codes->code->assign.left = place; return codes; } //--------------------------------------------------INT else if(exp->exp_type == 23){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(0); codes->code->assign.right = new_operand(1,exp->node_int); codes->code->assign.left = place; return codes; } //--------------------------------------------------FLOAT else if(exp->exp_type == 24){ } }
struct InterCodes* translate_Cond(struct TreeNode* Exp, Operand label_true, Operand label_false){ if(strcmp(Exp->children->neighbours->name, "RELOP") == 0){ printf("Exp - Exp RELOP Exp\n"); Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = IF_; code3->code.u.ifcode.op1 = t1; code3->code.u.ifcode.op2 = t2; code3->code.u.ifcode.label = label_true; strcpy(code3->code.u.ifcode.op_type, Exp->children->neighbours->value_str); struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = GOTO_; code4->code.u.gotocode.label = label_false; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = code4; code4->prev = code3; code4->next = NULL; return code1; } if(strcmp(Exp->children->neighbours->name, "NOT") == 0){ printf("Exp - NOT Exp\n"); return translate_Cond(Exp->children, label_false, label_true); } if(strcmp(Exp->children->neighbours->name, "AND") == 0){ printf("Exp - Exp AND Exp\n"); Operand label1 = new_label(); struct InterCodes* code1 = translate_Cond(Exp->children->neighbours->neighbours, label1, label_false); struct InterCodes* code2 = translate_Cond(Exp->children, label_true, label_false); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = LABEL_; code3->code.u.labelcode.label = label1; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = code2; code2->prev = code3; return code1; } if(strcmp(Exp->children->neighbours->name, "OR") == 0){ printf("Exp - Exp OR Exp\n"); Operand label1 = new_label(); struct InterCodes* code1 = translate_Cond(Exp->children->neighbours->neighbours, label_true, label1); struct InterCodes* code2 = translate_Cond(Exp->children, label_true, label_false); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = LABEL_; code3->code.u.labelcode.label = label1; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = code2; code2->prev = code3; return code1; } else{ printf("Exp - ELSE\n"); Operand t1 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = IF_; code2->code.u.ifcode.op1 = t1; code2->code.u.ifcode.op2 = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.ifcode.op2->kind = CONSTANT; code2->code.u.ifcode.op2->u.value = 0; code2->code.u.ifcode.label = label_true; char op[2] = {'!', '='}; strcpy(code2->code.u.ifcode.op_type, op); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = GOTO_; code3->code.u.gotocode.label = label_false; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = code3; code3->prev = code2; code3->next = NULL; return code1; } }
struct InterCodes* translate_Stmt(struct TreeNode* Stmt){ if (strcmp(Stmt->children->name, "SEMI") == 0){ if(Stmt->children->neighbours->neighbours == NULL){ printf("Stmt - Stmt SEMI\n"); return translate_Exp(Stmt->children->neighbours, NULL); } else{ printf("Stmt - RETURN Stmt SEMI\n"); Operand t1 = new_temp(); struct InterCodes* code1 = translate_Exp(Stmt->children->neighbours, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = RETURN_; code2->code.u.returncode.r = t1; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } if(strcmp(Stmt->children->name, "CompSt") == 0){ printf("Stmt - CompSt\n"); return translate_CompSt(Stmt->children); } if(strcmp(Stmt->children->name, "Stmt") == 0){ if(strcmp(Stmt->children->neighbours->neighbours->neighbours->neighbours->name, "IF") == 0){ printf("Stmt - IF LP Exp RP Stmt\n"); Operand label1 = new_label(); Operand label2 = new_label(); struct InterCodes* code1 = translate_Cond(Stmt->children->neighbours->neighbours, label1, label2); struct InterCodes* code2 = translate_Stmt(Stmt->children); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = LABEL_; code3->code.u.labelcode.label = label1; struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = LABEL_; code4->code.u.labelcode.label = label2; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = code2; p = code2; while(p->next != NULL) p = p->next; p->next = code4; code4->prev = p; code4->next = NULL; return code1; } if(strcmp(Stmt->children->neighbours->neighbours->neighbours->neighbours->name, "WHILE") == 0){ printf("Stmt - WHILE LP Exp RP Stmt\n"); Operand label1 = new_label(); Operand label2 = new_label(); Operand label3 = new_label(); struct InterCodes* code1 = translate_Cond(Stmt->children->neighbours->neighbours, label2, label3); struct InterCodes* code2 = translate_Stmt(Stmt->children->neighbours->neighbours); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = LABEL_; code3->code.u.labelcode.label = label1; struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = LABEL_; code4->code.u.labelcode.label = label2; struct InterCodes* code5 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code5->code.kind = LABEL_; code5->code.u.labelcode.label = label3; struct InterCodes* code6 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code6->code.kind = GOTO_; code6->code.u.gotocode.label = label3; code3->next = code1; code1->prev = code3; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code4; code4->prev = p; code4->next = code2; p = code2; while(p->next != NULL) p = p->next; p->next = code6; code6->prev = p; code6->next = code5; code5->prev = code6; code5->next = NULL; return code3; } if(strcmp(Stmt->children->neighbours->name, "ELSE") == 0){ printf("Stmt - IF LP Exp RP Stmt ELSE Stmt\n"); Operand label1 = new_label(); Operand label2 = new_label(); Operand label3 = new_label(); struct InterCodes* code1 = translate_Cond(Stmt->children->neighbours->neighbours, label1, label2); struct InterCodes* code2 = translate_Stmt(Stmt->children->neighbours->neighbours); struct InterCodes* code3 = translate_Stmt(Stmt->children); struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = LABEL_; code4->code.u.labelcode.label = label1; struct InterCodes* code5 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code5->code.kind = LABEL_; code5->code.u.labelcode.label = label2; struct InterCodes* code6 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code6->code.kind = LABEL_; code6->code.u.labelcode.label = label3; struct InterCodes* code7 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code7->code.kind = GOTO_; code7->code.u.gotocode.label = label3; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code4; code4->prev = p; code4->next = code2; p = code2; while(p->next != NULL) p = p->next; p->next = code7; code7->prev = p; code7->next = code5; code5->prev = code7; code5->next = code3; p = code3; while(p->next != NULL) p = p->next; p->next = code6; code6->prev = p; code6->next = NULL; return code1; } } }
//符号表是全局变量 struct InterCodes* translate_Exp(struct TreeNode* Exp, Operand place){ if (strcmp(Exp->children->name, "INT")){ printf("Exp - INT\n"); if(place != NULL){ FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->value_str,&item,0); place->kind = CONSTANT; place->u.value = Exp->children->value_int; struct InterCodes* temp = (struct InterCodes*)malloc(sizeof(struct InterCodes)); temp->code.kind = NONE_; return temp; } else{ struct InterCodes* temp = (struct InterCodes*)malloc(sizeof(struct InterCodes)); temp->code.kind = NONE_; return temp; } } if (strcmp(Exp->children->name, "ID")){ if(Exp->children->neighbours == NULL){ printf("Exp - ID\n"); if(place != NULL){ FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->value_str,&item,0); place->kind = VARIABLE; strcpy(place->u.ID, item->inter_name); struct InterCodes* temp = (struct InterCodes*)malloc(sizeof(struct InterCodes)); temp->code.kind = NONE_; return temp; } else{ struct InterCodes* temp = (struct InterCodes*)malloc(sizeof(struct InterCodes)); temp->code.kind = NONE_; return temp; } } if(strcmp(Exp->children->neighbours->name, "DOT")){ printf("Exp - Exp DOT ID\n"); //Operand t1 = new_temp(); //struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); int i = lookupTable(Exp->children->neighbours->neighbours->value_str,&item,0); switch(i){ case 0:{ Operand t1 = new_temp(); struct InterCodes* code1 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code1->code.kind = ADD_; code1->code.u.binop.result = t1; code1->code.u.binop.op1 = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.binop.op1->kind = VARIABLE; strcpy(code1->code.u.binop.op1->u.ID, item->inter_name); code1->code.u.binop.op2 = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.binop.op2->kind = CONSTANT; code1->code.u.binop.op2->u.value = index_size(item, Exp->children->value_str); place->kind = REFERENCE; strcpy(place->u.ID, t1->u.ID); return code1; //break; } case 1:{ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code1->code.kind = ASSIGN_; code1->code.u.assign.left = t1; code1->code.u.assign.right = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.assign.right->kind = ADDRESS; strcpy(code1->code.u.assign.right->u.ID, item->inter_name); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = ADD_; code2->code.u.binop.result = t2; code2->code.u.binop.op1 = t1; code2->code.u.binop.op2 = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.binop.op2->kind = CONSTANT; code2->code.u.binop.op2->u.value = index_size(item, Exp->children->value_str); place->kind = REFERENCE; strcpy(place->u.ID, t2->u.ID); code1->next = code2; code2->prev = code1; return code1; } } } } if (strcmp(Exp->children->name, "Exp")){ if (strcmp(Exp->children->neighbours->name, "ASSIGNOP")){ if (strcmp(Exp->children->neighbours->neighbours->children->name, "ID")){ printf("Exp - Exp ASSIGNOP Exp\n"); if(place != NULL){ Operand t1 = new_temp(); FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->neighbours->neighbours->children->value_str,&item,0); struct InterCodes* code1 = translate_Exp(Exp->children, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = ASSIGN_; code2->code.u.assign.left = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.assign.left->kind = VARIABLE; strcpy(code2->code.u.assign.left->u.ID, item->inter_name); code2->code.u.assign.right = t1; /*struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = ASSIGN; code3->code.u.assign.left = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.assign.left->kind = VARIABLE; strcpy(code3->code.u.assign.left->u.ID, place->u.ID); code3->code.u.assign.right = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.assign.right->kind = VARIABLE; strcpy(code3->code.u.assign.right->u.ID, Exp->children->neighbours->neighbours->children->inter_name);*/ place->kind = VARIABLE; strcpy(place->u.ID, item->inter_name); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } else{ Operand t1 = new_temp(); FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->neighbours->neighbours->children->value_str,&item,0); struct InterCodes* code1 = translate_Exp(Exp->children, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = ASSIGN_; code2->code.u.assign.left = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.assign.left->kind = VARIABLE; strcpy(code2->code.u.assign.left->u.ID, item->inter_name); code2->code.u.assign.right = t1; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } } if(strcmp(Exp->children->neighbours->name, "PLUS")){ printf("Exp - Exp PLUS Exp\n"); if(place != NULL){ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = ADD_; code3->code.u.binop.result = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.binop.result->kind = VARIABLE; strcpy(code3->code.u.binop.result->u.ID, place->u.ID); code3->code.u.binop.op1 = t1; code3->code.u.binop.op2 = t2; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = NULL; return code1; } else{ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } if(strcmp(Exp->children->neighbours->name, "MINUS")){ printf("Exp - Exp MINUS Exp\n"); if(place != NULL){ if(Exp->children->neighbours->neighbours != NULL){ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = SUB_; code3->code.u.binop.result = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.binop.result->kind = VARIABLE; strcpy(code3->code.u.binop.result->u.ID, place->u.ID); code3->code.u.binop.op1 = t1; code3->code.u.binop.op2 = t2; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = NULL; return code1; } else{ Operand t1 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = SUB_; code2->code.u.binop.result = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.binop.result->kind = VARIABLE; strcpy(code2->code.u.binop.result->u.ID, place->u.ID); code2->code.u.binop.op1 = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.binop.op1->kind = CONSTANT; code2->code.u.binop.op1->u.value = 0; code2->code.u.binop.op2 = t1; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } else{ if(Exp->children->neighbours->neighbours != NULL){ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } else{ Operand t1 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children, t1); return code1; } } } if(strcmp(Exp->children->neighbours->name, "STAR")){ printf("Exp - Exp STAR Exp\n"); if(place != NULL){ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = MUL_; code3->code.u.binop.result = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.binop.result->kind = VARIABLE; strcpy(code3->code.u.binop.result->u.ID, place->u.ID); code3->code.u.binop.op1 = t1; code3->code.u.binop.op2 = t2; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = NULL; return code1; } else{ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } if(strcmp(Exp->children->neighbours->name, "DIV")){ printf("Exp - Exp DIV Exp\n"); if(place != NULL){ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = DIV_; code3->code.u.binop.result = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.binop.result->kind = VARIABLE; strcpy(code3->code.u.binop.result->u.ID, place->u.ID); code3->code.u.binop.op1 = t1; code3->code.u.binop.op2 = t2; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = NULL; return code1; } else{ Operand t1 = new_temp(); Operand t2 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours->neighbours, t1); struct InterCodes* code2 = translate_Exp(Exp->children, t2); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } } if(strcmp(Exp->children->neighbours->name, "RELOP") || strcmp(Exp->children->neighbours->name, "NOT") || strcmp(Exp->children->neighbours->name, "AND") || strcmp(Exp->children->neighbours->name, "OR")){ printf("Exp - Exp Cond Exp\n"); if(place != NULL){ Operand label1 = new_label(); Operand label2 = new_label(); struct InterCodes* code1 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code1->code.kind = ASSIGN_; code1->code.u.assign.left = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.assign.left->kind = VARIABLE; strcpy(code1->code.u.assign.left->u.ID, place->u.ID); code1->code.u.assign.right = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.assign.right->kind = CONSTANT; code1->code.u.assign.right->u.value = 0; struct InterCodes* code2 = translate_Cond(Exp, label1, label2); struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = LABEL_; code3->code.u.labelcode.label = label1; struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = ASSIGN_; code4->code.u.assign.left = (Operand)malloc(sizeof(struct Operand_)); code4->code.u.assign.left->kind = VARIABLE; strcpy(code4->code.u.assign.left->u.ID, place->u.ID); code4->code.u.assign.right = (Operand)malloc(sizeof(struct Operand_)); code4->code.u.assign.right->kind = CONSTANT; code4->code.u.assign.right->u.value = 1; struct InterCodes* code5 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code5->code.kind = LABEL_; code5->code.u.labelcode.label = label2; code1->next = code2; code2->prev = code1; struct InterCodes* p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; code3->next = code4; code4->prev = code3; code4->next = code5; code5->prev = code4; code5->next = NULL; return code1; } } } if (strcmp(Exp->children->neighbours->name, "LP")){ printf("Exp - ID LP RP\n"); if(strcmp(Exp->children->neighbours->neighbours->value_str, "read") == 0){ struct InterCodes* code1 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code1->code.kind = READ_; code1->code.u.read.rd = place; return code1; } else{ FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->neighbours->neighbours->value_str,&item,1);//查函数 struct InterCodes* code1 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code1->code.kind = CALL_; code1->code.u.call.left = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.call.left->kind = VARIABLE; strcpy(code1->code.u.assign.left->u.ID, place->u.ID); code1->code.u.call.function = (Operand)malloc(sizeof(struct Operand_)); code1->code.u.call.function->kind = VARIABLE; strcpy(code1->code.u.call.function->u.ID, item->name); return code1; } } if(strcmp(Exp->children->neighbours->name, "Args")){ printf("Exp - ID LP Args RP\n"); struct ArgList* arg_list = NULL; struct InterCodes* code1 = translate_Args(Exp->children->neighbours, arg_list); if(strcpy(Exp->children->neighbours->neighbours->neighbours->value_str, "write") == 0){ struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = WRITE_; code2->code.u.write.wr = arg_list->op; struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = NULL; return code1; } else{ FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->neighbours->neighbours->neighbours->value_str,&item,0); struct ArgList* q = arg_list; struct InterCodes* code2 = NULL; while(q != NULL){ struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = ARG_; code3->code.u.arg.argument = q->op; if(code2 == NULL){ code2 = code3; } else{ struct InterCodes* p = code2; while(p->next != NULL) p = p->next; p->next = code3; code3->prev = p; } q = q->next; } struct InterCodes* code4 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code4->code.kind = CALL_; code4->code.u.call.left = (Operand)malloc(sizeof(struct Operand_)); code4->code.u.call.left->kind = VARIABLE; strcpy(code4->code.u.assign.left->u.ID, place->u.ID); code4->code.u.call.function = (Operand)malloc(sizeof(struct Operand_)); code4->code.u.call.function->kind = VARIABLE; strcpy(code4->code.u.call.function->u.ID, item->name); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; p = code2; while(p->next != NULL) p = p->next; p->next = code4; code4->prev = p; code4->next = NULL; return code1; } } if (strcmp(Exp->children->name, "RB") == 0){ printf("Exp - Exp LB Exp RB\n"); FieldList item = (FieldList)malloc(sizeof(struct FieldList_)); lookupTable(Exp->children->neighbours->neighbours->neighbours->children->value_str,&item,0); Operand t1 = new_temp(); Operand t2 = new_temp(); Operand t3 = new_temp(); struct InterCodes* code1 = translate_Exp(Exp->children->neighbours, t1); struct InterCodes* code2 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code2->code.kind = MUL_; code2->code.u.binop.result = t2; code2->code.u.binop.op1 = t1; code2->code.u.binop.op2 = (Operand)malloc(sizeof(struct Operand_)); code2->code.u.binop.result->kind = CONSTANT; code2->code.u.binop.result->u.value = 4; struct InterCodes* code3 = (struct InterCodes*)malloc(sizeof(struct InterCodes)); code3->code.kind = ADD_; code3->code.u.binop.result = t3; code3->code.u.binop.op1 = (Operand)malloc(sizeof(struct Operand_)); code3->code.u.binop.op1->kind = ADDRESS; strcpy(code3->code.u.binop.op1->u.ID, item->inter_name); code3->code.u.binop.op2 = t2; //place = t4; place->kind = REFERENCE; strcpy(place->u.ID, t3->u.ID); struct InterCodes* p = code1; while(p->next != NULL) p = p->next; p->next = code2; code2->prev = p; code2->next = code3; code3->prev = code2; code3->next = NULL; return code1; } }
intercodes translate_Stmt(struct Node *node) { struct Node *child = node->child; assert(child != NULL); intercodes code1,code2,code3,code4,code5,code6,code7; //Exp SEMI if (strcmp(child->type,"Exp") == 0) { return translate_Exp(child,NULL); } //CompSt if (strcmp(child->type,"CompSt") == 0) return translate_CompSt(child); //RETURN Exp SEMI if (strcmp(child->type,"RETURN") == 0) { operand t1 = new_tmp(); code1 = translate_Exp(child->sibling,t1); code2 = gen_one(RETURN_K,t1); // code1 = link(code1,code2); return code1; } if (strcmp(child->type,"IF") == 0) { struct Node *brother = child->sibling->sibling->sibling->sibling->sibling; //IF LP Exp RP Stmt1 if (brother == NULL) { operand label1 = new_label(); operand label2 = new_label(); code1 = translate_Cond(child->sibling->sibling,label1,label2); code2 = translate_Stmt(child->sibling->sibling->sibling->sibling); code3 = gen_one(LABEL_K,label1); code4 = gen_one(LABEL_K,label2); code1 = link(code1,code3); code1 = link(code1,code2); code1 = link(code1,code4); return code1; } //IF LP Exp RP Stmt1 ELSE Stmt2 else { operand label1 = new_label(); operand label2 = new_label(); operand label3 = new_label(); code1 = translate_Cond(child->sibling->sibling,label1,label2); code2 = translate_Stmt(child->sibling->sibling->sibling->sibling); code3 = translate_Stmt(brother->sibling); code4 = gen_one(LABEL_K,label1); code5 = gen_one(LABEL_K,label2); code6 = gen_one(LABEL_K,label3); code7 = gen_one(GOTO_K,label3); code1 = link(code1,code4); code1 = link(code1,code2); code1 = link(code1,code7); code1 = link(code1,code5); code1 = link(code1,code3); code1 = link(code1,code6); return code1; } } //WHILE LP Exp RP Stmt1 if (strcmp(child->type,"WHILE") == 0) { operand label1 = new_label(); operand label2 = new_label(); operand label3 = new_label(); code1 = translate_Cond(child->sibling->sibling,label2,label3); code2 = translate_Stmt(child->sibling->sibling->sibling->sibling); code3 = gen_one(LABEL_K,label1); code4 = gen_one(LABEL_K,label2); code5 = gen_one(LABEL_K,label3); code6 = gen_one(GOTO_K,label1); code1 = link(code3,code1); code1 = link(code1,code4); code1 = link(code1,code2); code1 = link(code1,code6); code1 = link(code1,code5); return code1; } return NULL; }
//translate intercodes translate_Exp(struct Node *node, operand place) { struct Node *child = node->child; assert(child != NULL); intercodes code1 = NULL; intercodes code2 = NULL; intercodes code3 = NULL; intercodes code4 = NULL; intercodes code5 = NULL; //INT if (strcmp(child->type,"INT") == 0) { operand c1 = new_constant(atoi(child->text)); code1 = gen_assign(ASSIGN_K,place,c1); return code1; } //ID if (strcmp(child->type,"ID") == 0 && child->sibling == NULL) { int id = getVarID(child); operand v1 = new_var(id); code1 = gen_assign(ASSIGN_K,place,v1); return code1; } //Exp1 ASSINGOP Exp2 if (strcmp(child->type,"Exp") == 0 && strcmp(child->sibling->type,"ASSIGNOP") == 0) { //Exp1 is ID (ID = Exp2) // printf("%s\n",child->child->type); if (strcmp(child->child->type,"ID") == 0) { operand t1 = new_tmp(); int id = getVarID(child->child); operand v1 = new_var(id); code1 = translate_Exp(child->sibling->sibling,t1); code2 = gen_assign(ASSIGN_K,v1,t1); // code1 = link(code1,code2); if (place != NULL) { code3 = gen_assign(ASSIGN_K,place,v1); code1 = link(code1,code3); } return code1; } //Exp[Exp] = Exp2 } //Exp1 PLUS/MINUS/STAR/DIV Exp2 if (strcmp(child->type,"Exp") == 0 && (strcmp(child->sibling->type,"PLUS") == 0 || strcmp(child->sibling->type,"MINUS") == 0 || strcmp(child->sibling->type,"STAR") == 0 || strcmp(child->sibling->type,"DIV") == 0)) { operand t1 = new_tmp(); operand t2 = new_tmp(); code1 = translate_Exp(child,t1); code2 = translate_Exp(child->sibling->sibling,t2); //printf("%d %d\n", t1->u.tmp_no, t2 -> u.tmp_no); if (strcmp(child->sibling->type,"PLUS") == 0) { code3 = gen_binop(ADD_K,place,t1,t2); } else if (strcmp(child->sibling->type,"MINUS") == 0) code3 = gen_binop(SUB_K,place,t1,t2); else if (strcmp(child->sibling->type,"STAR") == 0) code3 = gen_binop(MUL_K,place,t1,t2); else if (strcmp(child->sibling->type,"DIV") == 0) code3 = gen_binop(DIV_K,place,t1,t2); //code1 = link(code1,code2); //code1 = link(code1,code3); return code1; } //MINUS Exp1 if (strcmp(child->type,"MINUS") == 0) { operand t1 = new_tmp(); code1 = translate_Exp(child,t1); operand c1 = new_constant(0); code2 = gen_binop(SUB_K,place,c1,t1); code1 = link(code1,code2); return code1; } //Exp1 RELOP Exp2 //NOT Exp1 //Exp1 AND Exp2 //Exp1 OR Exp2 if (strcmp(child->type,"NOT") == 0 || strcmp(child->sibling->type,"RELOP") == 0 || strcmp(child->sibling->type,"AND") == 0 || strcmp(child->sibling->type,"OR") == 0) { operand label1 = new_label(); operand label2 = new_label(); operand c1 = new_constant(0); operand c2 = new_constant(1); code1 = gen_assign(ASSIGN_K,place,c1); code2 = translate_Cond(node,label1,label2); code3 = gen_one(LABEL_K,label1); code4 = gen_assign(ASSIGN_K,place,c2); code5 = gen_one(LABEL_K,label2); code1 = link(code1,code2); code1 = link(code1,code3); code1 = link(code1,code4); code1 = link(code1,code5); return code1; } //ID LP RP if (strcmp(child->sibling->sibling->type,"LP") == 0 && strcmp(child->sibling->sibling->type,"RP") == 0) { char *func_name = child->text; if (strcmp(func_name,"read") == 0) { if (place == NULL) { operand t1 = new_tmp(); code1 = gen_one(READ_K,t1); } else code1 = gen_one(READ_K,place); return code1; } struct funMes *func_node = getFunMes(child); assert(func_node != NULL); operand f1 = new_function(func_name); if (place != NULL && place->kind != ADDRESS) code1 = gen_assign(CALL_K,place,f1); else if (place != NULL && place->kind == ADDRESS) { operand t2 = new_tmp(); code1 = gen_assign(CALL_K,t2,f1); code2 = gen_assign(ASSIGN_K,place,t2); code1 = link(code1,code2); } else { operand t2 = new_tmp(); code1 = gen_assign(CALL_K,t2,f1); } return code1; } //ID LP Args RP if (strcmp(child->sibling->type,"LP") == 0 && strcmp(child->sibling->sibling->type,"Args") == 0) { char *func_name = child->text; operand *arg_list = (operand *)malloc(sizeof(operand) * 10); int arg_num = 0; code1 = translate_Args(child->sibling->sibling,arg_list,&arg_num); if (strcmp(func_name,"write") == 0) { assert(arg_num == 1); operand t1; if (arg_list[0]->kind == ADDRESS) { t1 = new_tmp(); code2 = gen_assign(ASSIGN_K,t1,arg_list[0]); code1 = link(code1,code2); } else t1 = arg_list[0]; code3 = gen_one(WRITE_K,t1); code1 = link(code1,code3); return code1; } int i; for (i = 0;i < arg_num;i++) { code2 = gen_one(ARG_K,arg_list[i]); code1 = link(code1,code2); } operand f1 = new_function(func_name); if (place != NULL && place->kind != ADDRESS) code3 = gen_assign(CALL_K,place,f1); else if (place != NULL && place->kind == ADDRESS) { operand t2 = new_tmp(); code1 = gen_assign(CALL_K,t2,f1); code2 = gen_assign(ASSIGN_K,place,t2); code1 = link(code1,code2); } else { operand t2 = new_tmp(); code3 = gen_assign(CALL_K,t2,f1); } code1 = link(code1,code3); return code1; } //LP Exp RP if (strcmp(child->type,"LP") == 0) { return translate_Exp(child->sibling,place); } //Exp1 LB Exp2 RB if (strcmp(child->type,"LB") == 0) { return translate_array(node,place,NULL,NULL); } //Exp DOT ID return NULL; }