/* 式を表示 */ void pr_expr(FILE * fp, expr_t e) { switch (e->kind) { case expr_kind_int_literal: case expr_kind_id: fprintf(fp, "%s", e->u.s); break; case expr_kind_paren: fprintf(fp, "("); pr_expr(fp, e->u.p); fprintf(fp, ")"); break; case expr_kind_app: if (e->u.a.o == op_kind_fun) { fprintf(fp, "%s", e->u.a.f); fprintf(fp, "("); pr_expr_list_comma(fp, e->u.a.args); fprintf(fp, ")"); } else if (un_op_to_str(e->u.a.o)) { fprintf(fp, "%s ", un_op_to_str(e->u.a.o)); pr_expr(fp, expr_list_get(e->u.a.args, 0)); } else if (bin_op_to_str(e->u.a.o)) { pr_expr(fp, expr_list_get(e->u.a.args, 0)); fprintf(fp, " %s ", bin_op_to_str(e->u.a.o)); pr_expr(fp, expr_list_get(e->u.a.args, 1)); } else { assert(0); } break; default: assert(0); } }
char *cogen_expr_app(FILE *fp,expr_t e,env_t env) { if(e->u.a.o == op_kind_fun) { cogen_expr_call(fp,e,env); } else { char str1[16]; char str2[16]; if(e->u.a.o != op_kind_assign) { cogen_expr(fp,expr_list_get(e->u.a.args,0),env); } pos_e(str1,expr_list_get(e->u.a.args,0),env); if(judge_op_bin(e->u.a.o)) { cogen_expr(fp,expr_list_get(e->u.a.args,1),env); pos_e(str2,expr_list_get(e->u.a.args,1),env); if(judge_e(expr_list_get(e->u.a.args,0),expr_list_get(e->u.a.args,1))&&e->u.a.o != op_kind_div&&e->u.a.o != op_kind_rem) { fprintf(fp,"\tmovl\t%s,%%edx\n",str2); bin_op_cul(fp,e->u.a.o,str1,"%edx"); } else { bin_op_cul(fp,e->u.a.o,str1,str2); //ここでなんかしらの二項演算を行う感じ,種類はe->u.a.oに従う } if(e->u.a.o == op_kind_assign) { if(expr_list_get(e->u.a.args,0)->kind != expr_kind_id) { printf("左側が変数ではありません\n"); exit(1); } else { pos_v(str2,expr_list_get(e->u.a.args,0)->u.s,env); if(judge_c(str1)) { fprintf(fp,"\tmovl\t%s,%s\n",str1,str2); } else { fprintf(fp,"\tmovl\t%s,%%edx\n",str1); fprintf(fp,"\tmovl\t%%edx,%s\n",str2); } } } } else { un_op_cul(fp,e->u.a.o,str1); //ここで単行演算を行う感じ,種類はe->u.a.oに従う } } return 0; }
//関数呼び出しのcogen lgはいらないかな? int cogen_expr_call(FILE *fp, expr_t e, env_t env){ int i; int sz = expr_list_sz(e->u.a.args); char str[16]; for(i=sz-1;i>=0;i--){ cogen_expr(fp, expr_list_get(e->u.a.args,i), env); pos_e(str, expr_list_get(e->u.a.args,i) , env); fprintf(fp,"\tpushl\t%s\n",str); } fprintf(fp,"\tmovl\t%%ecx, %d(%%ebp)\n",address_env(env)-4); fprintf(fp,"\tcall\t%s\n",e->u.a.f); fprintf(fp,"\taddl\t$%d, %%esp\n",sz*4); fprintf(fp,"\tmovl\t%d(%%ebp), %%ecx\n",address_env(env)-4); pos_e(str, e, env); fprintf(fp,"\tmovl\t%%eax, %s\n",str); return 0; }
/* 式のリストを , で区切りながら表示 */ void pr_expr_list_comma(FILE * fp, expr_list_t es) { int n = expr_list_sz(es); int i; for (i = 0; i < n; i++) { if (i > 0) fprintf(fp, ", "); expr_t e = expr_list_get(es, i); pr_expr(fp, e); } }