📄 ctree.cc
字号:
fprintf(out, "'"); return; } case ctree_floatconst: print_float(&the_io, float_val()); return; case ctree_enumconst: fprintf(out, "%s", leafval.s); return; case ctree_strconst: fprintf(out, "\"%s\"", leafval.s); return; case ctree_symconst: case ctree_vardecl: case ctree_vardef: leafval.y->print(out); return; case ctree_typedecl: leafval.t->print_full(out); return; case ctree_typeforward: leafval.t->print_full(out); return; default: fprintf(out, "(%s", ctree_oper_attr[op].sym); fprintf(out, " "); nindent += strlen(ctree_oper_attr[op].sym)+7; for (int i=0; i<N(); i++) { if (i != 0) ctree_indent(&the_io, nindent+4); child(i)->print(out, nindent+4); if (i != N()-1) fprintf(out, "\n"); } fprintf(out, ")"); return; }}static boolean last_was_minus = FALSE;static boolean last_was_slash = FALSE;/* * Print a ctree with the proper precedence relationship. This may * mean placing ()s around the expression. */void ctree::print_with_prec(io_class *out, int nindent, int parentop, boolean is_left) { int this_prec = ctree_oper_attr[op].prec; int parent_prec = ctree_oper_attr[parentop].prec; boolean parens_needed; if ((op == ctree_neg) && last_was_minus) { /* * We don't want ``x - -y'' to be written ``x--y'' or * ``-(-x)'' to be written ``--x''; this would give a ``--'' * token. */ parens_needed = TRUE; } else if ((op == ctree_deref) && last_was_slash) { /* * We don't want ``x / *y'' to be written without spaces or * parentheses; this would be interpretted as the beginning of * a comment. */ parens_needed = TRUE; } else if (this_prec < parent_prec) { parens_needed = TRUE; } else if (this_prec > parent_prec) { parens_needed = FALSE; } else { if ((ctree_oper_attr[op].assoc == ctree_leftassoc) && is_left) parens_needed = FALSE; else if ((op == parentop) && ctree_oper_attr[op].commutes) parens_needed = FALSE; else parens_needed = TRUE; } if (parens_needed) { out->printf("("); last_was_minus = FALSE; last_was_slash = FALSE; } print_as_c(out, nindent); if (parens_needed) out->printf(")"); }/* * Print the body of a ``for'', ``while'', ``do ... while'', or * ``switch'' statement, or either the ``then'' or ``else'' body of an * ``if'' statement. */void ctree::print_as_body(io_class *out, int nindent) { int new_indent = nindent; if (op != ctree_block) { if (c_style.indent_single_statement_bodies) { out->printf("\n"); new_indent = nindent + c_style.single_statement_body_indent; ctree_indent(out, new_indent); } else { out->printf(" "); } } print_as_c(out, new_indent); }/* * Print a ctree as C. */void ctree::print_as_c(io_class *out, int nindent){ if (op == ctree_neg) assert(!last_was_minus); if (op == ctree_deref) assert(!last_was_slash); /* * If this op will print something before making a recursive call * to a print function, reset last_was_minus and last_was_slash. */ switch (op) { case ctree_strptr: case ctree_strsel: case ctree_subscr: case ctree_funcall: case ctree_postinc: case ctree_postdec: case ctree_mult: case ctree_div: case ctree_mod: case ctree_add: case ctree_sub: case ctree_lshift: case ctree_rshift: case ctree_lt: case ctree_lte: case ctree_gt: case ctree_gte: case ctree_eq: case ctree_neq: case ctree_bitand: case ctree_bitxor: case ctree_bitor: case ctree_logand: case ctree_logor: case ctree_ternary: case ctree_assign: case ctree_addassign: case ctree_subassign: case ctree_comma: case ctree_semi: break; default: last_was_minus = FALSE; last_was_slash = FALSE; } int i; switch (op) { /* Unimplemented */ default: assert_msg(FALSE, ("ctree::print_as_c - Unknown op %d", op)); /* Function declaration */ case ctree_funcdef: { char *posttype; proc_sym *the_proc_sym = (proc_sym *)leafval.y; char *pretype = make_c_proc_type(the_proc_sym, &posttype); out->printf("%s(", pretype); /* * posttype points to a scratch buffer that can be * over-written by the calls to make_c_sym_type. So we need * to save it. But the vast majority of the time it will be * an empty string, so we optimize for that case. */ if (*posttype == '0') { posttype = ""; } else { char *new_string = new char[strlen(posttype) + 1]; strcpy(new_string, posttype); posttype = new_string; } assert(N()>0); func_type *the_func_type = the_proc_sym->type(); boolean new_style = the_func_type->args_known(); for (i=0; i<N()-1; i++) { assert(child(i)->op == ctree_vardecl); if (new_style) { out->printf("%s", make_c_sym_type((var_sym *)(child(i)->leafval.y))); } else { out->printf("%s", child(i)->leafval.y->name()); } if (i != N()-2) out->printf(", "); } if (the_func_type->has_varargs()) { if (N() == 1) { static boolean warned = FALSE; mistake(&warned, the_func_type, "function with no specified arguments may not " "have varargs"); } out->printf(", ..."); } else if (new_style && (N() == 1)) { out->printf("void"); } out->printf(")%s\n", posttype); if (*posttype != '0') delete[] posttype; if (!new_style) { for (i=0; i<N()-1; i++) { ctree_indent(out, nindent + c_style.param_indent); out->printf("%s;\n", make_c_sym_type((var_sym *)child(i)->leafval.y)); } } if (comments != NULL) full_line_output_comments(out, nindent + c_style.statement_indent); ctree_indent(out, nindent + c_style.brace_indent); out->printf("{\n"); child(N()-1)->print_as_c(out, nindent + c_style.statement_indent); ctree_indent(out, nindent + c_style.brace_indent); out->printf("}\n"); return; } /* Ternary operator */ case ctree_ternary: assert(N() == 3); child(0)->print_with_prec(out, nindent, op, TRUE); out->printf(" ? "); if (comments != NULL) in_line_output_comments(out, 0, 1); child(1)->print_with_prec(out, nindent, op, FALSE); out->printf(" : "); child(2)->print_with_prec(out, nindent, op, FALSE); return; /* Binary operators */ case ctree_add: case ctree_sub: case ctree_mult: case ctree_div: case ctree_mod: case ctree_lshift: case ctree_rshift: case ctree_lt: case ctree_lte: case ctree_gt: case ctree_gte: case ctree_eq: case ctree_neq: case ctree_bitand: case ctree_bitxor: case ctree_bitor: case ctree_logand: case ctree_logor: case ctree_assign: case ctree_addassign: case ctree_subassign: for (i = 0; i < N(); i++) { child(i)->print_with_prec(out, nindent, op, (i == 0)); if (i != N()-1) { if ((op == ctree_assign) || (op == ctree_addassign) || (op == ctree_subassign)) { if (c_style.space_around_assignments) out->printf(" "); out->printf("%s", ctree_oper_attr[op].sym); if (c_style.space_around_assignments) out->printf(" "); } else { if (c_style.space_around_binops) out->printf(" "); out->printf("%s", ctree_oper_attr[op].sym); if (c_style.space_around_binops) out->printf(" "); else if (op == ctree_sub) last_was_minus = TRUE; else if (op == ctree_div) last_was_slash = TRUE; } } if ((i == 0) && (comments != NULL)) in_line_output_comments(out, 1, 1); } return; case ctree_comma: { int mod = 0; for (i = 0; i < N(); i++) { child(i)->print_with_prec(out, nindent, op, (i == 0)); if (i != N()-1) { out->printf("%s", ctree_oper_attr[op].sym); if (c_style.space_after_commas && (mod != c_style.max_comma_items_per_line - 1)) { out->printf(" "); } } if ((i == 0) && (comments != NULL)) in_line_output_comments(out, 1, 1); ++mod; if ((mod == c_style.max_comma_items_per_line) && (i + 1 < N())) { out->printf("\n"); ctree_indent(out, nindent); mod = 0; } } return; } /* Unary pre-operators */ case ctree_compl: case ctree_not: case ctree_neg: case ctree_addrof: case ctree_deref: case ctree_preinc: case ctree_predec: assert(N() == 1); out->printf("%s", ctree_oper_attr[op].sym); if (op == ctree_neg) last_was_minus = TRUE; if (comments != NULL) in_line_output_comments(out, 1, 1); child(0)->print_with_prec(out, nindent, op, TRUE); return; case ctree_conv: assert(N() == 1); out->printf("(%s)", make_c_type(type)); if (comments != NULL) in_line_output_comments(out, 1, 1); child(0)->print_with_prec(out, nindent, op, TRUE); return; /* Unary post-operators */ case ctree_postinc: case ctree_postdec: assert(N() == 1); child(0)->print_with_prec(out, nindent, op, TRUE); out->printf("%s", ctree_oper_attr[op].sym); if (comments != NULL) in_line_output_comments(out, 1, 1); return; /* Misc */ case ctree_strptr: case ctree_strsel: assert(N() == 1); child(0)->print_with_prec(out, nindent, op, TRUE); out->printf("%s%s", ctree_oper_attr[op].sym, leafval.s); if (comments != NULL) in_line_output_comments(out, 1, 1); return; case ctree_subscr: child(0)->print_with_prec(out, nindent, op, TRUE); for (i=1; i<N(); i++) { out->printf("["); child(i)->print_as_c(out, nindent); out->printf("]"); } if (comments != NULL) in_line_output_comments(out, 1, 1); return; case ctree_macro: { char *format_string = lookup_gen_op(leafval.s, N()); assert(format_string != NULL); char *follow; int num_matches = 0; for (follow = format_string; *follow != 0; ++follow) { if (*follow == '%') { ++follow; if (*follow == 'a') ++num_matches; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -