intercodes translate_VarDec(struct Node *node,operand *place) { intercodes code1,code2,code3,code4; struct Node *child = node->child; assert(child != NULL); //ID if (strcmp(child->type,"ID") == 0) { int id = getVarID(child); enum varType type; union varp vp = getVar(child,&type); operand v1 = new_var(id); if (place != NULL) { *place = v1; } if (type == varInt || type == varFloat) { return NULL; } else if (type == varArray || type == varStruct) { int size = get_structure_size(vp,type); operand c1 = new_constant(size); code1 = gen_assign(DEC_K,v1,c1); return code1; } else { printf("type is varError%d\n",type == varError); exit(-1); } } //VarDec INT LB INT RB return translate_VarDec(child,NULL); }
int new_range(TERM* min, TERM* max, TERM_RANGE** term) { TERM_RANGE* new_term = NULL; int result = ERROR_SUCCESS; new_term = (TERM_RANGE*) yr_malloc(sizeof(TERM_RANGE)); if (new_term != NULL) { new_term->type = TERM_TYPE_RANGE; new_term->first = range_first; new_term->next = range_next; new_term->min = min; new_term->max = max; result = new_constant(0, &new_term->current); } else { result = ERROR_INSUFICIENT_MEMORY; } *term = new_term; return result; }
void compile_init(void) { compile_block = new_block(); /* Note: These definitions actually depend on those in types.h and runtime.c */ component_undefined = new_component(compile_block, c_constant, new_constant(compile_block, cst_int, 42)); component_true = new_component(compile_block, c_constant, new_constant(compile_block, cst_int, TRUE)); component_false = new_component(compile_block, c_constant, new_constant(compile_block, cst_int, FALSE)); builtin_ops[b_eq] = OPmeq; builtin_ops[b_ne] = OPmne; builtin_ops[b_lt] = OPmlt; builtin_ops[b_le] = OPmle; builtin_ops[b_gt] = OPmgt; builtin_ops[b_ge] = OPmge; builtin_ops[b_bitor] = OPmbitor; builtin_ops[b_bitxor] = OPmbitxor; builtin_ops[b_bitand] = OPmbitand; builtin_ops[b_shift_left] = OPmshiftleft; builtin_ops[b_shift_right] = OPmshiftright; builtin_ops[b_add] = OPmadd; builtin_ops[b_subtract] = OPmsub; builtin_ops[b_multiply] = OPmmultiply; builtin_ops[b_divide] = OPmdivide; builtin_ops[b_remainder] = OPmremainder; builtin_ops[b_negate] = OPmnegate; builtin_ops[b_not] = OPmnot; builtin_ops[b_bitnot] = OPmbitnot; builtin_ops[b_ref] = OPmref; builtin_ops[b_set] = OPmset; builtin_functions[b_cons] = "cons"; staticpro((value *)&last_filename); last_filename = alloc_string(""); last_c_filename = xstrdup(""); }
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; }
intercodes translate_array(struct Node *node,operand place,union varp *list,enum varType *listtype) { struct Node *child = node->child; assert(child != NULL); intercodes code1 = NULL; intercodes code2,code3,code4; int size = 0; operand t1; //ID[Exp] if (strcmp(child->sibling->type,"ID") == 0) { int id = getVarID(child->child); int flag = getFlag(child->child->text); if (flag == 1) t1 = new_var(id); else t1 = new_reference(id); enum varType type; union varp vp = getVar(child->child,&type); if (vp.ap->basetype == varStruct) size = get_structure_size(vp.ap->base,vp.ap->basetype); if (vp.ap->basetype == varInt || vp.ap->basetype == varFloat) size = 4; if (list != NULL) { *list = vp.ap->base; *listtype = vp.ap->basetype; } } //Exp[Exp][Exp] // if (child->child->sibling != NULL && strcmp(child->child->sibling->type,"LB") == 0) { // } //handle Exp2 operand t2 = new_tmp(); code2 = translate_Exp(child->sibling->sibling,t2); code1 = link(code1,code2); //calculate offset operand c1 = new_constant(size); operand t3 = new_tmp(); code3 = gen_binop(MUL_K,t3,t2,c1); //Add array address operand t4 = new_tmp_id(place->u.tmp_no); code4 = gen_binop(ADD_K,t4,t1,t3); code1 = link(code1,code4); place->kind = ADDRESS; return code1; }
//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; }