home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Atari / Gnu / gdb36p4s.zoo / expprint.c < prev    next >
C/C++ Source or Header  |  1993-08-13  |  10KB  |  325 lines

  1. /* Print in infix form a struct expression.
  2.    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. GDB is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GDB is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GDB; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "defs.h"
  22. #include "param.h"
  23. #include "symtab.h"
  24. #include "expression.h"
  25. #include "value.h"
  26.  
  27.  
  28. /* These codes indicate operator precedences, least tightly binding first.  */
  29. /* Adding 1 to a precedence value is done for binary operators,
  30.    on the operand which is more tightly bound, so that operators
  31.    of equal precedence within that operand will get parentheses.  */
  32. /* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
  33.    they are used as the "surrounding precedence" to force
  34.    various kinds of things to be parenthesized.  */
  35. enum precedence
  36. { PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_OR, PREC_AND,
  37.   PREC_LOGIOR, PREC_LOGAND, PREC_LOGXOR, PREC_EQUAL, PREC_ORDER,
  38.   PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
  39.   PREC_HYPER, PREC_PREFIX, PREC_SUFFIX };
  40.  
  41. /* Table mapping opcodes into strings for printing operators
  42.    and precedences of the operators.  */
  43.  
  44. struct op_print
  45. {
  46.   char *string;
  47.   enum exp_opcode opcode;
  48.   /* Precedence of operator.  These values are used only by comparisons.  */
  49.   enum precedence precedence;
  50.   int right_assoc;
  51. };
  52.  
  53. static struct op_print op_print_tab[] =
  54.   {
  55.     {",", BINOP_COMMA, PREC_COMMA, 0},
  56.     {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
  57.     {"||", BINOP_OR, PREC_OR, 0},
  58.     {"&&", BINOP_AND, PREC_AND, 0},
  59.     {"|", BINOP_LOGIOR, PREC_LOGIOR, 0},
  60.     {"&", BINOP_LOGAND, PREC_LOGAND, 0},
  61.     {"^", BINOP_LOGXOR, PREC_LOGXOR, 0},
  62.     {"==", BINOP_EQUAL, PREC_EQUAL, 0},
  63.     {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
  64.     {"<=", BINOP_LEQ, PREC_ORDER, 0},
  65.     {">=", BINOP_GEQ, PREC_ORDER, 0},
  66.     {">", BINOP_GTR, PREC_ORDER, 0},
  67.     {"<", BINOP_LESS, PREC_ORDER, 0},
  68.     {">>", BINOP_RSH, PREC_SHIFT, 0},
  69.     {"<<", BINOP_LSH, PREC_SHIFT, 0},
  70.     {"+", BINOP_ADD, PREC_ADD, 0},
  71.     {"-", BINOP_SUB, PREC_ADD, 0},
  72.     {"*", BINOP_MUL, PREC_MUL, 0},
  73.     {"/", BINOP_DIV, PREC_MUL, 0},
  74.     {"%", BINOP_REM, PREC_MUL, 0},
  75.     {"@", BINOP_REPEAT, PREC_REPEAT, 0},
  76.     {"-", UNOP_NEG, PREC_PREFIX, 0},
  77.     {"!", UNOP_ZEROP, PREC_PREFIX, 0},
  78.     {"~", UNOP_LOGNOT, PREC_PREFIX, 0},
  79.     {"*", UNOP_IND, PREC_PREFIX, 0},
  80.     {"&", UNOP_ADDR, PREC_PREFIX, 0},
  81.     {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
  82.     {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
  83.     {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
  84.     /* C++  */
  85.     {"::", BINOP_SCOPE, PREC_PREFIX, 0},
  86.   };
  87.  
  88. static void print_subexp ();
  89.  
  90. void
  91. print_expression (exp, stream)
  92.      struct expression *exp;
  93.      FILE *stream;
  94. {
  95.   int pc = 0;
  96.   print_subexp (exp, &pc, stream, PREC_NULL);
  97. }
  98.  
  99. /* Print the subexpression of EXP that starts in position POS, on STREAM.
  100.    PREC is the precedence of the surrounding operator;
  101.    if the precedence of the main operator of this subexpression is less,
  102.    parentheses are needed here.  */
  103.  
  104. static void
  105. print_subexp (exp, pos, stream, prec)
  106.      register struct expression *exp;
  107.      register int *pos;
  108.      FILE *stream;
  109.      enum precedence prec;
  110. {
  111.   register int tem;
  112.   register int pc;
  113.   int nargs;
  114.   register char *op_str;
  115.   int assign_modify = 0;
  116.   enum exp_opcode opcode;
  117.   enum precedence myprec;
  118.   /* Set to 1 for a right-associative operator.  */
  119.   int assoc;
  120.  
  121.   pc = (*pos)++;
  122.   opcode = exp->elts[pc].opcode;
  123.   switch (opcode)
  124.     {
  125.     case OP_SCOPE:
  126.       myprec = PREC_PREFIX;
  127.       assoc = 0;
  128.       (*pos) += 2;
  129.       print_subexp (exp, pos, stream, (int) myprec + assoc);
  130.       fprintf (stream, " :: ");
  131.       nargs = strlen (&exp->elts[pc + 2].string);
  132.       (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  133.  
  134.       fprintf (stream, &exp->elts[pc + 2].string);
  135.       return;
  136.  
  137.     case OP_LONG:
  138.       (*pos) += 3;
  139.       value_print (value_from_long (exp->elts[pc + 1].type,
  140.                     exp->elts[pc + 2].longconst),
  141.            stream, 0, Val_no_prettyprint);
  142.       return;
  143.  
  144.     case OP_DOUBLE:
  145.       (*pos) += 3;
  146.       value_print (value_from_double (exp->elts[pc + 1].type,
  147.                       exp->elts[pc + 2].doubleconst),
  148.            stream, 0, Val_no_prettyprint);
  149.       return;
  150.  
  151.     case OP_VAR_VALUE:
  152.       (*pos) += 2;
  153.       print_demangled (SYMBOL_NAME (exp->elts[pc + 1].symbol), stream);
  154.       return;
  155.  
  156.     case OP_LAST:
  157.       (*pos) += 2;
  158.       fprintf (stream, "$%d", (int) exp->elts[pc + 1].longconst);
  159.       return;
  160.  
  161.     case OP_REGISTER:
  162.       (*pos) += 2;
  163.       fprintf (stream, "$%s", reg_names[exp->elts[pc + 1].longconst]);
  164.       return;
  165.  
  166.     case OP_INTERNALVAR:
  167.       (*pos) += 2;
  168.       fprintf (stream, "$%s",
  169.            internalvar_name (exp->elts[pc + 1].internalvar));
  170.       return;
  171.  
  172.     case OP_FUNCALL:
  173.       (*pos) += 2;
  174.       nargs = exp->elts[pc + 1].longconst;
  175.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  176.       fprintf (stream, " (");
  177.       for (tem = 0; tem < nargs; tem++)
  178.     {
  179.       if (tem > 0)
  180.         fprintf (stream, ", ");
  181.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  182.     }
  183.       fprintf (stream, ")");
  184.       return;
  185.  
  186.     case OP_STRING:
  187.       nargs = strlen (&exp->elts[pc + 1].string);
  188.       (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  189.       fprintf (stream, "\"");
  190.       for (tem = 0; tem < nargs; tem++)
  191.     printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
  192.       fprintf (stream, "\"");
  193.       return;
  194.  
  195.     case TERNOP_COND:
  196.       if ((int) prec > (int) PREC_COMMA)
  197.     fprintf (stream, "(");
  198.       /* Print the subexpressions, forcing parentheses
  199.      around any binary operations within them.
  200.      This is more parentheses than are strictly necessary,
  201.      but it looks clearer.  */
  202.       print_subexp (exp, pos, stream, PREC_HYPER);
  203.       fprintf (stream, " ? ");
  204.       print_subexp (exp, pos, stream, PREC_HYPER);
  205.       fprintf (stream, " : ");
  206.       print_subexp (exp, pos, stream, PREC_HYPER);
  207.       if ((int) prec > (int) PREC_COMMA)
  208.     fprintf (stream, ")");
  209.       return;
  210.  
  211.     case STRUCTOP_STRUCT:
  212.       tem = strlen (&exp->elts[pc + 1].string);
  213.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  214.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  215.       fprintf (stream, ".%s", &exp->elts[pc + 1].string);
  216.       return;
  217.  
  218.     case STRUCTOP_PTR:
  219.       tem = strlen (&exp->elts[pc + 1].string);
  220.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  221.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  222.       fprintf (stream, "->%s", &exp->elts[pc + 1].string);
  223.       return;
  224.  
  225.     case BINOP_SUBSCRIPT:
  226.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  227.       fprintf (stream, "[");
  228.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  229.       fprintf (stream, "]");
  230.       return;
  231.  
  232.     case UNOP_POSTINCREMENT:
  233.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  234.       fprintf (stream, "++");
  235.       return;
  236.  
  237.     case UNOP_POSTDECREMENT:
  238.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  239.       fprintf (stream, "--");
  240.       return;
  241.  
  242.     case UNOP_CAST:
  243.       (*pos) += 2;
  244.       if ((int) prec > (int) PREC_PREFIX)
  245.     fprintf (stream, "(");
  246.       fprintf (stream, "(");
  247.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  248.       fprintf (stream, ") ");
  249.       print_subexp (exp, pos, stream, PREC_PREFIX);
  250.       if ((int) prec > (int) PREC_PREFIX)
  251.     fprintf (stream, ")");
  252.       return;
  253.  
  254.     case UNOP_MEMVAL:
  255.       (*pos) += 2;
  256.       if ((int) prec > (int) PREC_PREFIX)
  257.     fprintf (stream, "(");
  258.       fprintf (stream, "{");
  259.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  260.       fprintf (stream, "} ");
  261.       print_subexp (exp, pos, stream, PREC_PREFIX);
  262.       if ((int) prec > (int) PREC_PREFIX)
  263.     fprintf (stream, ")");
  264.       return;
  265.  
  266.     case BINOP_ASSIGN_MODIFY:
  267.       opcode = exp->elts[pc + 1].opcode;
  268.       (*pos) += 2;
  269.       myprec = PREC_ASSIGN;
  270.       assoc = 1;
  271.       assign_modify = 1;
  272.       for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
  273.     if (op_print_tab[tem].opcode == opcode)
  274.       {
  275.         op_str = op_print_tab[tem].string;
  276.         break;
  277.       }
  278.  
  279.     case OP_THIS:
  280.       ++(*pos);
  281.       fprintf (stream, "this");
  282.       return;
  283.  
  284.     default:
  285.       for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
  286.     if (op_print_tab[tem].opcode == opcode)
  287.       {
  288.         op_str = op_print_tab[tem].string;
  289.         myprec = op_print_tab[tem].precedence;
  290.         assoc = op_print_tab[tem].right_assoc;
  291.         break;
  292.       }
  293.     }
  294.  
  295.   if ((int) myprec < (int) prec)
  296.     fprintf (stream, "(");
  297.   if ((int) opcode > (int) BINOP_END)
  298.     {
  299.       /* Unary prefix operator.  */
  300.       fprintf (stream, "%s", op_str);
  301.       print_subexp (exp, pos, stream, PREC_PREFIX);
  302.     }
  303.   else
  304.     {
  305.       /* Binary operator.  */
  306.       /* Print left operand.
  307.      If operator is right-associative,
  308.      increment precedence for this operand.  */
  309.       print_subexp (exp, pos, stream, (int) myprec + assoc);
  310.       /* Print the operator itself.  */
  311.       if (assign_modify)
  312.     fprintf (stream, " %s= ", op_str);
  313.       else if (op_str[0] == ',')
  314.     fprintf (stream, "%s ", op_str);
  315.       else
  316.     fprintf (stream, " %s ", op_str);
  317.       /* Print right operand.
  318.      If operator is left-associative,
  319.      increment precedence for this operand.  */
  320.       print_subexp (exp, pos, stream, (int) myprec + !assoc);
  321.     }
  322.   if ((int) myprec < (int) prec)
  323.     fprintf (stream, ")");
  324. }
  325.