/* Assums the dseg is the next higher seg value from the cseg */ void loadds(void) { gen_code(op_push, makesegreg(DS), 0); gen_code(op_push, makesegreg(CS), 0); gen_codes(op_add, 2, make_stack(0), make_immed(8)); gen_code(op_pop, makesegreg(DS), 0); }
static void selection_stmt() { int first_label = -1; int second_label = -1; match(TOK_IF); match(TOK_LPAREN); expression(); first_label = get_label(); gen_code("fjp %d\n", first_label); match(TOK_RPAREN); statement(); second_label = get_label(); gen_code("ujp %d\n", second_label); gen_code("lab %d:\n", first_label); if(token == TOK_ELSE){ match(TOK_ELSE); statement(); } gen_code("lab %d:\n", second_label); }
void bingen(int lower, int avg, int higher, AMODE *ap1, struct cases *cs, int size) { AMODE *ap2 = make_immed(cs->ptrs[avg].id); AMODE *ap3 = make_label(cs->ptrs[avg].label); if (cs->ptrs[avg].binlabel != - 1) gen_label(cs->ptrs[avg].binlabel); gen_coden(op_cmp, size, ap1, ap2); gen_code(op_je, ap3, 0); if (avg == lower) { if (cs->deflab < 0) cs->deflab = nextlabel++; ap3 = make_label(cs->deflab); gen_code(op_jmp, ap3, 0); } else { int avg1 = (lower + avg) / 2; int avg2 = (higher + avg + 1) / 2; if (avg + 1 < higher) ap3 = make_label(cs->ptrs[avg2].binlabel = nextlabel++); else ap3 = make_label(cs->deflab); if (size < 0) gen_code(op_jg, ap3, 0); else gen_code(op_ja, ap3, 0); bingen(lower, avg1, avg, ap1, cs, size); if (avg + 1 < higher) bingen(avg + 1, avg2, higher, ap1, cs, size); } }
static void call() { char func_name[NAME_SIZE]; Symbol *f; strcpy(func_name,save_word); match(TOK_ID); f = lookup_global_sym(FUNCTION,func_name); if(!f){ fprintf(stderr,"can not call func %s", func_name); } if(strcmp(save_word,"read") && strcmp(save_word,"write")){ gen_code("mst %d\n", f->u.f.total_offset*10000 + f->u.f.param_size); }else{ var_in_read_write = true; } match(TOK_LPAREN); args(); match(TOK_RPAREN); var_in_read_write = false; gen_code("cal %d\n",f->u.f.id); }
//略过第一个符号 'if' void grammar_parser::if_statement(set<e_word_t> follows,int& stk_index,while_context* p_while_conext) { word lmbranch=m_words.get(); if(lmbranch.m_type==ewt_key_lsbranch) { grammar_debug(lmbranch); expression(_create_syms(follows,ewt_key_rsbranch),stk_index); word rmbranch=m_words.get(); if(rmbranch.m_type==ewt_key_rsbranch) { grammar_debug(rmbranch); _instruction* p_if_jmp=gen_code(e_jpc,eab_relat_ip,0,0);//if语句应当在执行完判断后把栈顶元素弹出 stk_index--; int inst_if_body_begin=get_new_code_addr(); word lbbranch=m_words.get(); if(lbbranch.m_type==ewt_key_lbbranch) { grammar_debug(lbbranch); body(_create_syms(follows,ewt_key_else),stk_index,p_while_conext); } else { m_words.push(lbbranch); statement(_create_syms(follows,ewt_key_else),stk_index,p_while_conext); } word wd_else=m_words.get(); if(wd_else.m_type==ewt_key_else) { grammar_debug(wd_else); _instruction* p_else_jmp=gen_code(e_jmp,eab_relat_ip,0,0); int inst_else_body_begin=get_new_code_addr(); p_if_jmp->m_addr=get_new_code_addr()-inst_if_body_begin; word lbbranch=m_words.get(); if(lbbranch.m_type==ewt_key_lbbranch) { grammar_debug(lbbranch); body(follows,stk_index,p_while_conext); } else { m_words.push(lbbranch); statement(_create_syms(follows,ewt_key_else),stk_index,p_while_conext); } p_else_jmp->m_addr=get_new_code_addr()-inst_else_body_begin; } else { m_words.push(wd_else); p_if_jmp->m_addr=get_new_code_addr()-inst_if_body_begin; } } } else m_words.push(lmbranch); test_and_skip(follows,_create_syms()); }
void gencompactswitch(SNODE *stmt, int deflab) { int tablab,curlab,i, size = natural_size(stmt->exp); AMODE *ap,*ap2; long switchbottom=gswitchbottom, switchcount=gswitchcount; long switchtop=gswitchtop; int *switchlabels=0; tablab = nextlabel++; curlab = nextlabel++; initstack(); ap = gen_expr(stmt->exp,F_DREG | F_VOL,4); initstack(); if (switchbottom) gen_code(op_sub,4,ap,make_immed(switchbottom)); if (size < 0) gen_code(op_jl,0,make_label(deflab),0); else gen_code(op_jb,0,make_label(deflab),0); gen_code(op_cmp,4,ap,make_immed(switchtop-switchbottom)); if (size < 0) gen_code(op_jge,0,make_label(deflab),0); else gen_code(op_jnc,0,make_label(deflab),0); gen_code(op_shl,4,ap,make_immed(2)); ap2 = xalloc(sizeof(AMODE)); ap->mode = am_indisp; ap2->preg = ap->preg; ap->offset = makenode(en_labcon,(char *)tablab,0); gen_code(op_jmp,4,ap,0); initstack(); align(4); gen_label(tablab); switchlabels = xalloc((switchtop-switchbottom) * sizeof(int)); for (i=switchbottom; i < switchtop; i++) { switchlabels[i-switchbottom] = deflab; } stmt = stmt->s1; while (stmt) { if( stmt->s2 ) /* default case ? */ { stmt->label = (SNODE *)deflab; diddef = TRUE; } else { switchlabels[(int)stmt->label-switchbottom] = curlab; stmt->label = (SNODE *)curlab; } if(stmt->next != 0 ) curlab = nextlabel++; stmt = stmt->next; } for (i=0; i < switchtop-switchbottom; i++) gen_code(op_dd,4,make_label(switchlabels[i]),0); }
void genwhile(SNODE *stmt) /* * generate code to evaluate a while statement. */ { int lab1, lab2, lab3; initstack(); /* initialize temp registers */ lab1 = contlab; /* save old continue label */ contlab = nextlabel++; /* new continue label */ if( stmt->s1 != 0 ) /* has block */ { lab2 = breaklab; /* save old break label */ breaklab = nextlabel++; gen_code(op_jmp,0,make_label(contlab),0); lab3 = nextlabel++; gen_label(lab3); genstmt(stmt->s1); gen_label(contlab); if (stmt->lst) gen_line(stmt->lst); initstack(); truejp(stmt->exp,lab3); gen_label(breaklab); breaklab = lab2; /* restore old break label */ } else /* no loop code */ { if (stmt->lst) gen_line(stmt->lst); gen_label(contlab); initstack(); truejp(stmt->exp,contlab); } contlab = lab1; /* restore old continue label */ }
static void factor() { int next_token; if(token == TOK_LPAREN){ match(TOK_LPAREN); expression(); //does not support (x=x+3)+4 match(TOK_RPAREN); }else if(token==TOK_ID||token == TOK_AND){ next_token = virtual_get_token(true); if(next_token == TOK_LPAREN){ call(); }else{ var(); } } else if(token == TOK_NUM){ gen_code("ldc %d\n", save_num); match(TOK_NUM); }else if(token == TOK_PLUS||token == TOK_MINUS) { /* 0 + a -> +a 0 - a -> -a */ //first element is zero } else fprintf(stderr, "line %d: unexpected factor %s\n", save_line, save_word); }
void program() { int entry_flag = 0; Symbol *p, *q; /* before parse insert read && write func */ p = insert_global_sym(FUNCTION,"read"); q = insert_global_sym(FUNCTION,"write"); if(!p || !q){ fprintf(stderr, "init read write function error\n"); exit(0); } token = get_token(); while(token == TOK_INT || token == TOK_PVOID || token == TOK_VOID || token == TOK_CHAR || token == TOK_PINT || token == TOK_PCHAR) { entry_flag = 1; declaration(token); } if(entry_flag){ gen_code("stp\n"); printf("succeed!! exit()\n"); }else{ fprintf(stderr, "line %d: %s does not name a type\n", save_line, save_word ); } }
//略过第一个符号 'while' void grammar_parser::while_statement(set<e_word_t> follows,int& stk_index) { word lmbranch=m_words.get(); if(lmbranch.m_type==ewt_key_lsbranch) { grammar_debug(lmbranch); int test_begin=get_new_code_addr(false); expression(_create_syms(follows,ewt_key_rsbranch),stk_index); word rmbranch=m_words.get(); if(rmbranch.m_type==ewt_key_rsbranch) { grammar_debug(rmbranch); _instruction* p_while_jmp=gen_code(e_jpc,eab_relat_ip); stk_index--; while_context context; context.m_begin_stk_index=stk_index; word lbbranch=m_words.get(); if(lbbranch.m_type==ewt_key_lbbranch) { grammar_debug(lbbranch); body(follows,stk_index,&context); } else { m_words.push(lbbranch); statement(_create_syms(follows,ewt_key_else),stk_index,&context); } _instruction* p_loop_jmp=gen_code(e_jmp,eab_relat_ip); p_loop_jmp->m_addr=test_begin-(p_loop_jmp->m_index+1); p_while_jmp->m_addr=get_new_code_addr()-(p_while_jmp->m_index+1); for(vector<_instruction*>::iterator it=context.breaks.begin();it!=context.breaks.end();it++) { (*it)->m_addr=get_new_code_addr()-((*it)->m_index+1); } for(vector<_instruction*>::iterator it=context.continues.begin();it!=context.continues.end();it++) { (*it)->m_addr=test_begin-((*it)->m_index+1); } } } else { m_words.push(lmbranch); test_and_skip(follows,_create_syms()); } }
void gen_push(int reg, int rmode, int flag) /* * this routine generates code to push a register onto the stack */ { AMODE *ap1; ap1 = xalloc(sizeof(AMODE)); ap1->preg = reg; ap1->mode = rmode; if (rmode == am_freg) { gen_code(op_fmove,10,ap1,push); stackdepth +=8; } else { gen_code(op_move,4,ap1,push); stackdepth +=4; } }
//略过第一个符号 'return' void grammar_parser::return_statement(set<e_word_t> follows,int& stk_index) { if(!m_words.check(ewt_key_semicolon)) { expression(follows,stk_index); gen_code(e_save,eab_reg_sb,-1); gen_pop_instruction(stk_index); } gen_code(e_ret); word tmp=m_words.get(); if(tmp.m_type==ewt_key_semicolon) { grammar_debug(tmp); return; } else m_words.push(tmp); }
void gen_pop(int reg, int rmode, int flag) /* * generate code to pop the primary register in ap from the * stack. */ { AMODE *ap1; ap1 = xalloc(sizeof(AMODE)); ap1->preg = reg; ap1->mode = rmode; if (rmode == am_freg) { gen_code(op_fmove,10,pop,ap1); stackdepth -=8; } else { gen_code(op_move,4,pop,ap1); stackdepth -=4; } }
void call_library(char *lib_name) /* * generate a call to a library routine. */ { AMODE *ap; ap = set_symbol(lib_name,1); gen_code(op_call,0,ap,0); }
static void return_stmt() { match(TOK_RETURN); if(token == TOK_SEMI) { gen_code("ret\n"); match(TOK_SEMI); } else { expression(); gen_code("ret\n"); match(TOK_SEMI); has_return_value = true; } }
//略过第一个符号 'function' void grammar_parser::function(set<e_word_t> follows) { //堆栈的样子 //param1,param2,param3,param_count,ret_vaule,prev_reg_sb,prev_reg_ip,其中prev_reg_sb对应堆栈起始位置 word ident=m_words.get(); if(ident.m_type==ewt_ident) { grammar_debug(ident); _symbol* p_sym=push_symbol(_symbol(es_function,ident.m_str_value,eab_absolute_ip,get_new_code_addr(true)),true); if(get_top_gener_id()>1) report_error("语法错误:不支持函数内定义函数\n"); _instruction* p_jmp=gen_code(e_jmp,eab_absolute_ip,0,0,true); create_gener(); create_table(); word lmbrach=m_words.get(); if(lmbrach.m_type=ewt_key_lsbranch) { grammar_debug(lmbrach); p_sym->m_fun_params_count=fun_params(follows); } int stk_index=2; word lbbranch=m_words.get(); if(lbbranch.m_type==ewt_key_lbbranch) { grammar_debug(lbbranch); body(follows,stk_index,NULL); } else m_words.push(lbbranch); gen_code(e_ret);//如果没有写返回语句,加一句默认的返回语句 p_jmp->m_addr=merge_code(); pop_table(); pop_gener(); } else { report_error("语法错误:函数定义缺少函数名\n"); m_words.push(ident); } test_and_skip(follows,_create_syms()); }
static void term() { int op_token; factor(); while(token == TOK_MUL||token == TOK_DIV) { op_token = token; match(token); factor(); if(op_token == TOK_MUL){ gen_code("mpi\n"); }else if(op_token == TOK_DIV){ gen_code("dvi\n"); }else{ //common_error } } }
bool grammar_parser::complie() { error_printer::clear_error_count(); create_gener(); _instruction* p_jmp=gen_code(e_jmp,eab_absolute_ip,0,0,true); int stk_index=0; gen_load_const_instruction(stk_index,1); _symbol* p_sym=find_symbol("true"); gen_code(e_save,p_sym->m_addr_t,p_sym->m_addr); gen_pop_instruction(stk_index); block(_create_syms(ewt_end_file),stk_index,NULL); gen_code(e_exit); p_jmp->m_addr=merge_code(); pop_gener(); word end_file=m_words.get(); if(end_file.m_type!=ewt_end_file) { report_error("语法错误:未完整识别源代码\n"); return false; } return true; }
int run_compilation_passes (struct ast **ss) { int ret = 0; ret = ret || semantic (*ss); ret = ret || transform (ss); ret = ret || dealias (ss); ret = ret || collect_vars (*ss); ret = ret || optimizer (ss); ret = ret || gen_code (*ss); AST_FREE (*ss); return ret; }
static void additive_expression() { int op_token; term(); while(token == TOK_PLUS || token == TOK_MINUS) { op_token = token; match(token); term(); if(op_token == TOK_PLUS){ gen_code("adi\n"); }else if(op_token == TOK_MINUS){ gen_code("sbi\n"); } else{ //common_error } } }
static void iteration_stmt() { int first_label = -1; int second_label = -1; if(token == TOK_WHILE) { first_label = get_label(); gen_code("lab %d:\n", first_label); match(TOK_WHILE); match(TOK_LPAREN); /* ( */ expression(); second_label = get_label(); gen_code("fjp %d\n", second_label); match(TOK_RPAREN); /* ) */ statement(); gen_code("ujp %d\n", first_label); gen_code("lab %d:\n", second_label); }else if(token == TOK_FOR){ match(TOK_FOR); match(TOK_LPAREN);/* ( */ expression(); match(TOK_SEMI); first_label = get_label(); gen_code("lab %d:\n", first_label); expression(); match(TOK_SEMI); expression(); match(TOK_RPAREN);/* ) */ second_label = get_label(); gen_code("fjp %d\n", second_label); //gen_code("etu %d\n", second_label); statement(); gen_code("ujp %d\n", first_label); gen_code("lab %d:\n", second_label); } else{ } }
void gen_for(SNODE *stmt) /* * generate code to evaluate a for loop */ { int old_break, old_cont, exit_label, loop_label; old_break = breaklab; old_cont = contlab; loop_label = nextlabel++; exit_label = nextlabel++; contlab = nextlabel++; initstack(); if( stmt->label != 0 ) gen_expr(stmt->label,F_ALL | F_NOVALUE ,natural_size(stmt->label)); gen_code(op_jmp,0,make_label(contlab),0); gen_label(loop_label); if( stmt->s1 != 0 ) { breaklab = exit_label; genstmt(stmt->s1); } initstack(); if( stmt->s2 != 0 ) gen_expr(stmt->s2,F_ALL | F_NOVALUE,natural_size(stmt->s2)); gen_label(contlab); if (stmt->lst) gen_line(stmt->lst); initstack(); if( stmt->exp != 0 ) truejp(stmt->exp,loop_label); else gen_code(op_jmp,0,make_label(loop_label),0); gen_label(exit_label); breaklab = old_break; contlab = old_cont; }
//未略过第一个符号 void grammar_parser::term(set<e_word_t> follows,int& stk_index) { word tmp=m_words.get(); if(m_const_values.find(tmp.m_type)!=m_const_values.end()) { grammar_debug(tmp); inst_value value(0); if(tmp.m_type==ewt_int) value=inst_value(tmp.m_int_value); else if(tmp.m_type==ewt_float) value=inst_value(tmp.m_float_value); else if(tmp.m_type==ewt_string) value=inst_value(tmp.m_str_value); gen_load_const_instruction(stk_index,value); } else if(tmp.m_type==ewt_ident) { word lmbranch=m_words.get(); if(lmbranch.m_type==ewt_key_lsbranch) { m_words.push(lmbranch); m_words.push(tmp); funcall_expression(follows,stk_index); } else { m_words.push(lmbranch); grammar_debug(tmp); _symbol* p_sym=find_symbol(tmp.m_str_value); if(p_sym && p_sym->m_type==es_value) { gen_code(e_load,p_sym->m_addr_t,p_sym->m_addr); stk_index++; } else report_error("语法错误:未找到符号%s\n",tmp.m_str_value.c_str()); } } else if(tmp.m_type==ewt_key_lsbranch) { grammar_debug(tmp); factor_logic(_create_syms(follows,ewt_key_rsbranch),stk_index); word rmbranch=m_words.get(); if(rmbranch.m_type==ewt_key_rsbranch) { grammar_debug(rmbranch); } else m_words.push(rmbranch); } else m_words.push(tmp); test_and_skip(follows,_create_syms()); }
static void assign_stmt() { int addr; before_assign = true; var(); match(TOK_ASSIGN); before_assign = false; expression(); gen_code("sto\n"); match(TOK_SEMI); }
main (int argc, char *argv[]) { struct get_fnct get; struct param_get_file p_get_file; int status; struct pred_list *programme; struct put_fnct put; struct param_put_file p_put_file; if (argc != 3) { printf ("usage: %s source.pro output.c\n", argv[0]); exit (-1); } get.f = f_get_file; get.p = &p_get_file; p_get_file.fd = fopen (argv[1], "r"); if (p_get_file.fd == NULL) { perror (argv[1]); return errno; } status = aspl (&get, &programme); if (status) { printf ("\nProgramme correct\n"); print_program (programme); put.f = f_put_file; put.p = &p_put_file; p_put_file.fd = fopen (argv[2], "w"); if (p_put_file.fd == NULL) { perror (argv[2]); return errno; } gen_code (programme, &put); } else printf ("<- Erreur syntaxique\n"); }
//未略过第一个符号 void grammar_parser::assign_expression(set<e_word_t> follows,int& stk_index) { word ident=m_words.get(); _symbol* p_sym=find_symbol(ident.m_str_value); inst_value vaule(0); word assgin=m_words.get(); if(assgin.m_type==ewt_key_assign) { grammar_debug(assgin); expression(follows,stk_index); if(p_sym && p_sym->m_type==es_value) { gen_code(e_save,p_sym->m_addr_t,p_sym->m_addr); } else report_error("语法错误:未找到符号%s\n",ident.m_str_value.c_str()); return; } else m_words.push(assgin); test_and_skip(follows,_create_syms()); }
void genif(SNODE *stmt) /* * generate code to evaluate an if statement. */ { int lab1, lab2; lab1 = nextlabel++; /* else label */ lab2 = nextlabel++; /* exit label */ initstack(); /* clear temps */ falsejp(stmt->exp,lab1); genstmt(stmt->s1); if( stmt->s2 != 0 ) /* else part exists */ { gen_code(op_jmp,0,make_label(lab2),0); gen_label(lab1); genstmt(stmt->s2); gen_label(lab2); } else /* no else code */ gen_label(lab1); }
unsigned gen_var_decl( parse_node_t *tree, unsigned address, gen_state_t *state, FILE *fp ) { name_decl_t *new_name = calloc( 1, sizeof( name_decl_t )); name_decl_t *move; move = find_name_no_recurse( tree->down->next->data, state ); if ( move ){ fprintf( stderr, "Error: symbol \"%s\" already defined in this scope\n", tree->down->next->data ); } state->num_vars++; new_name->type = tree->down->data; new_name->name = tree->down->next->data; new_name->number = state->num_vars; new_name->state = state; if ( state->flags & STATE_IN_FUNCTION ){ fprintf( fp, " sub rsp, 8 ; %s %s\n", tree->down->data, tree->down->next->data ); new_name->placement = VAR_PLACE_LOCAL; } else { fprintf( fp, "section .bss\n" ); fprintf( fp, "global %s\n", tree->down->next->data ); fprintf( fp, "%s: resq 1 ; %s\n", tree->down->next->data, tree->down->data ); new_name->placement = VAR_PLACE_GLOBAL; } add_name( state, new_name ); address = gen_code( tree->next, address + 1, state, fp ); return address; }
static void fun_declaration(int type, char * id) { if(type != TOK_VOID) has_return_value = false; // init AutoOffset memset(&offset,0,sizeof(AutoOffset)); current_function = insert_global_sym(FUNCTION,id); if(current_function == NULL) { //insert_func failed! } current_function->u.f.return_type = type; gen_code("ent %d\n", current_function->u.f.id); /* match ( */ match(TOK_LPAREN); params(); /*match ) */ match(TOK_RPAREN); //add after insert auto_var //current_function->u.f.total_offset += current_function->u.f.param_size; compound_stmt(); if(current_function->u.f.return_type == TOK_VOID && has_return_value){ fprintf(stderr, "line %d: this fuction doesn't return value'\n", save_line); } }
//略过第一个符号 'var' void grammar_parser::declare(set<e_word_t> follows,int& stk_index) { word ident=m_words.get(); if(ident.m_type==ewt_ident) { grammar_debug(ident); _symbol* p_sym=NULL; if((get_top_gener_id()==1)&& (get_global_table()==get_top_table())) { p_sym=push_symbol(_symbol(es_value,ident.m_str_value,eab_global_data,alloc_global_data_space()),true); } else { p_sym=push_symbol(_symbol(es_value,ident.m_str_value,eab_reg_sb,stk_index)); gen_load_const_instruction(stk_index,0); } word assgin=m_words.get(); if(assgin.m_type==ewt_key_assign) { grammar_debug(assgin); expression(follows,stk_index); if(p_sym) gen_code(e_save,p_sym->m_addr_t,p_sym->m_addr); gen_pop_instruction(stk_index); } else m_words.push(assgin); word semicolon=m_words.get(); if(semicolon.m_type==ewt_key_semicolon) { grammar_debug(semicolon); return; } else m_words.push(semicolon); } else m_words.push(ident); test_and_skip(follows,_create_syms()); }