/* 式を表示 */ 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); } }
/* 文を表示 */ void pr_stmt(FILE * fp, stmt_t s) { switch (s->kind) { case stmt_kind_empty: fprintf(fp, ";\n"); break; case stmt_kind_continue: fprintf(fp, "continue;\n"); break; case stmt_kind_break: fprintf(fp, "break;\n"); break; case stmt_kind_return: fprintf(fp, "return "); pr_expr(fp, s->u.e); fprintf(fp, ";\n"); break; case stmt_kind_expr: pr_expr(fp, s->u.e); fprintf(fp, ";\n"); break; case stmt_kind_compound: fprintf(fp, "{\n"); pr_var_decl_list_semicolon(fp, s->u.c.decls); pr_stmt_list(fp, s->u.c.body); fprintf(fp, "}\n"); break; case stmt_kind_if: fprintf(fp, "if ("); pr_expr(fp, s->u.i.e); fprintf(fp, ") "); pr_stmt(fp, s->u.i.th); if (s->u.i.el) { fprintf(fp, " else "); pr_stmt(fp, s->u.i.el); } break; case stmt_kind_while: fprintf(fp, "while("); pr_expr(fp, s->u.w.e); fprintf(fp, ") "); pr_stmt(fp, s->u.w.body); break; default: assert(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); } }
static void mul_expr(void) { switch(token.type) { case TOKEN_INTEGER: case TOKEN_LPARENTH: pr_expr(); if (err == SYN_ERR) { goto out; } rest_mul_expr(); goto out; default: err = SYN_ERR; goto out; } out: return ; }
static void rest_mul_expr(void) { int tmp, rv, i; number op1, op2; while(token.type == TOKEN_ASTERISK || token.type == TOKEN_SLASH) { tmp = token.type; get_next_token(); pr_expr(); if (err == SYN_ERR) { goto out; } rv = pop_item(&sp, &op2); if (rv != OK) { err = MEM_ERR; goto out; } rv = pop_item(&sp, &op1); if (rv != OK) { err = MEM_ERR; goto out; } if (tmp == TOKEN_ASTERISK) { rv = mpl_mul(&op1.value, &op1.value, &op2.value); if (rv != MPL_OK) { err = MEM_ERR; goto out; } op1.frac += op2.frac; } else if (tmp == TOKEN_SLASH) { if (op1.frac == 0 && op2.frac == 0) goto main_part; op1.frac -= op2.frac; for (i = 0; i < PRECISION; i++) { rv = mpl_mul_dig(&op1.value, &op1.value, 10); if (rv != MPL_OK) { err = MEM_ERR; goto out; } op1.frac++; } main_part: rv = mpl_div(&op1.value, NULL, &op1.value, &op2.value); if (rv != MPL_OK) { err = MEM_ERR; goto out; } } rv = push_item(&sp, &op1); if (rv != OK) { err = MEM_ERR; goto out; } mpl_clear(&op2.value); } if (token.type != TOKEN_PLUS && token.type != TOKEN_MINUS && token.type != TOKEN_RPARENTH && token.type != TOKEN_EOL) { err = SYN_ERR; goto out; } out: return ; }