1 /* Print in infix form a struct expression.
2 Copyright (C) 1986 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
23 #include "expression.h"
27 /* These codes indicate operator precedences, least tightly binding first. */
28 /* Adding 1 to a precedence value is done for binary operators,
29 on the operand which is more tightly bound, so that operators
30 of equal precedence within that operand will get parentheses. */
31 /* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
32 they are used as the "surrounding precedence" to force
33 various kinds of things to be parenthesized. */
35 { PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_OR, PREC_AND,
36 PREC_LOGIOR, PREC_LOGAND, PREC_LOGXOR, PREC_EQUAL, PREC_ORDER,
37 PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
38 PREC_HYPER, PREC_PREFIX, PREC_SUFFIX };
40 /* Table mapping opcodes into strings for printing operators
41 and precedences of the operators. */
46 enum exp_opcode opcode;
47 /* Precedence of operator. These values are used only by comparisons. */
48 enum precedence precedence;
52 static struct op_print op_print_tab[] =
54 {",", BINOP_COMMA, PREC_COMMA, 0},
55 {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
56 {"||", BINOP_OR, PREC_OR, 0},
57 {"&&", BINOP_AND, PREC_AND, 0},
58 {"|", BINOP_LOGIOR, PREC_LOGIOR, 0},
59 {"&", BINOP_LOGAND, PREC_LOGAND, 0},
60 {"^", BINOP_LOGXOR, PREC_LOGXOR, 0},
61 {"==", BINOP_EQUAL, PREC_EQUAL, 0},
62 {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
63 {"<=", BINOP_LEQ, PREC_ORDER, 0},
64 {">=", BINOP_GEQ, PREC_ORDER, 0},
65 {">", BINOP_GTR, PREC_ORDER, 0},
66 {"<", BINOP_LESS, PREC_ORDER, 0},
67 {">>", BINOP_RSH, PREC_SHIFT, 0},
68 {"<<", BINOP_LSH, PREC_SHIFT, 0},
69 {"+", BINOP_ADD, PREC_ADD, 0},
70 {"-", BINOP_SUB, PREC_ADD, 0},
71 {"*", BINOP_MUL, PREC_MUL, 0},
72 {"/", BINOP_DIV, PREC_MUL, 0},
73 {"%", BINOP_REM, PREC_MUL, 0},
74 {"@", BINOP_REPEAT, PREC_REPEAT, 0},
75 {"-", UNOP_NEG, PREC_PREFIX, 0},
76 {"!", UNOP_ZEROP, PREC_PREFIX, 0},
77 {"~", UNOP_LOGNOT, PREC_PREFIX, 0},
78 {"*", UNOP_IND, PREC_PREFIX, 0},
79 {"&", UNOP_ADDR, PREC_PREFIX, 0},
80 {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
81 {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
82 {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}
85 static void print_subexp ();
88 print_expression (exp, stream)
89 struct expression *exp;
93 print_subexp (exp, &pc, stream, PREC_NULL);
96 /* Print the subexpression of EXP that starts in position POS, on STREAM.
97 PREC is the precedence of the surrounding operator;
98 if the precedence of the main operator of this subexpression is less,
99 parentheses are needed here. */
102 print_subexp (exp, pos, stream, prec)
103 register struct expression *exp;
106 enum precedence prec;
111 register char *op_str;
112 int assign_modify = 0;
113 enum exp_opcode opcode;
114 enum precedence myprec;
115 /* Set to 1 for a right-associative operator. */
119 opcode = exp->elts[pc].opcode;
124 value_print (value_from_long (exp->elts[pc + 1].type,
125 exp->elts[pc + 2].longconst),
131 value_print (value_from_double (exp->elts[pc + 1].type,
132 exp->elts[pc + 2].doubleconst),
138 fprintf (stream, "%s", SYMBOL_NAME (exp->elts[pc + 1].symbol));
143 fprintf (stream, "$%d", exp->elts[pc + 1].longconst);
148 fprintf (stream, "$%s", reg_names[exp->elts[pc + 1].longconst]);
153 fprintf (stream, "$%s",
154 internalvar_name (exp->elts[pc + 1].internalvar));
159 nargs = exp->elts[pc + 1].longconst;
160 print_subexp (exp, pos, stream, PREC_SUFFIX);
161 fprintf (stream, " (");
162 for (tem = 0; tem < nargs; tem++)
165 fprintf (stream, ", ");
166 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
168 fprintf (stream, ")");
172 nargs = strlen (&exp->elts[pc + 1].string);
173 (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
174 fprintf (stream, "\"");
175 for (tem = 0; tem < nargs; tem++)
176 printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
177 fprintf (stream, "\"");
181 if ((int) prec > (int) PREC_COMMA)
182 fprintf (stream, "(");
183 /* Print the subexpressions, forcing parentheses
184 around any binary operations within them.
185 This is more parentheses than are strictly necessary,
186 but it looks clearer. */
187 print_subexp (exp, pos, stream, PREC_HYPER);
188 fprintf (stream, " ? ");
189 print_subexp (exp, pos, stream, PREC_HYPER);
190 fprintf (stream, " : ");
191 print_subexp (exp, pos, stream, PREC_HYPER);
192 if ((int) prec > (int) PREC_COMMA)
193 fprintf (stream, ")");
196 case STRUCTOP_STRUCT:
197 tem = strlen (&exp->elts[pc + 1].string);
198 (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
199 print_subexp (exp, pos, stream, PREC_SUFFIX);
200 fprintf (stream, ".%s", &exp->elts[pc + 1].string);
204 tem = strlen (&exp->elts[pc + 1].string);
205 (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
206 print_subexp (exp, pos, stream, PREC_SUFFIX);
207 fprintf (stream, "->%s", &exp->elts[pc + 1].string);
210 case BINOP_SUBSCRIPT:
211 print_subexp (exp, pos, stream, PREC_SUFFIX);
212 fprintf (stream, "[");
213 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
214 fprintf (stream, "]");
217 case UNOP_POSTINCREMENT:
218 print_subexp (exp, pos, stream, PREC_SUFFIX);
219 fprintf (stream, "++");
222 case UNOP_POSTDECREMENT:
223 print_subexp (exp, pos, stream, PREC_SUFFIX);
224 fprintf (stream, "--");
229 if ((int) prec > (int) PREC_PREFIX)
230 fprintf (stream, "(");
231 fprintf (stream, "(");
232 type_print (exp->elts[pc + 1].type, "", stream, 0);
233 fprintf (stream, ") ");
234 print_subexp (exp, pos, stream, PREC_PREFIX);
235 if ((int) prec > (int) PREC_PREFIX)
236 fprintf (stream, ")");
241 if ((int) prec > (int) PREC_PREFIX)
242 fprintf (stream, "(");
243 fprintf (stream, "{");
244 type_print (exp->elts[pc + 1].type, "", stream, 0);
245 fprintf (stream, "} ");
246 print_subexp (exp, pos, stream, PREC_PREFIX);
247 if ((int) prec > (int) PREC_PREFIX)
248 fprintf (stream, ")");
251 case BINOP_ASSIGN_MODIFY:
252 opcode = exp->elts[pc + 1].opcode;
254 myprec = PREC_ASSIGN;
257 for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
258 if (op_print_tab[tem].opcode == opcode)
260 op_str = op_print_tab[tem].string;
265 for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
266 if (op_print_tab[tem].opcode == opcode)
268 op_str = op_print_tab[tem].string;
269 myprec = op_print_tab[tem].precedence;
270 assoc = op_print_tab[tem].right_assoc;
275 if ((int) myprec < (int) prec)
276 fprintf (stream, "(");
277 if ((int) opcode > (int) BINOP_END)
279 /* Unary prefix operator. */
280 fprintf (stream, "%s", op_str);
281 print_subexp (exp, pos, stream, PREC_PREFIX);
285 /* Binary operator. */
286 /* Print left operand.
287 If operator is right-associative,
288 increment precedence for this operand. */
289 print_subexp (exp, pos, stream, (int) myprec + assoc);
290 /* Print the operator itself. */
292 fprintf (stream, " %s= ", op_str);
293 else if (op_str[0] == ',')
294 fprintf (stream, "%s ", op_str);
296 fprintf (stream, " %s ", op_str);
297 /* Print right operand.
298 If operator is left-associative,
299 increment precedence for this operand. */
300 print_subexp (exp, pos, stream, (int) myprec + !assoc);
302 if ((int) myprec < (int) prec)
303 fprintf (stream, ")");