1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)rval.c	5.1 (Berkeley) 6/5/85";
   9: #endif not lint
  10: 
  11: /*
  12:  * pxp - Pascal execution profiler
  13:  *
  14:  * Bill Joy UCB
  15:  * Version 1.2 January 1979
  16:  */
  17: 
  18: #include "0.h"
  19: #include "tree.h"
  20: 
  21: extern  char *opnames[];
  22: 
  23: #define alph(c)     ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
  24: /*
  25:  * Rvalue reformats an expression.
  26:  * Par is a flag indicating that the expression
  27:  * should be parenthesized if it is non-atomic.
  28:  */
  29: rvalue(r, par)
  30:     register int *r;
  31:     int par;
  32: {
  33:     register int *al;
  34:     register char *opname;
  35: 
  36:     if (r == NIL) {
  37:         ppid("{expr}");
  38:         return;
  39:     }
  40:     if (r[0] <= T_IN)
  41:         opname = opnames[r[0]];
  42:     switch (r[0]) {
  43:         case T_BINT:
  44:         case T_INT:
  45:         case T_FINT:
  46:             ppnumb(r[2]);
  47:             if (r[0] == T_BINT)
  48:                 ppsep("b");
  49:             return;
  50:         case T_NIL:
  51:             ppkw("nil");
  52:             return;
  53:         case T_FCALL:
  54:             funccod(r);
  55:             return;
  56:         case T_VAR:
  57:             lvalue(r);
  58:             return;
  59:         case T_CSET:
  60:             cset(r);
  61:             return;
  62:         case T_STRNG:
  63:             ppstr(r[2]);
  64:             return;
  65:     }
  66:     if (par)
  67:         ppbra("(");
  68:     switch (r[0]) {
  69:         default:
  70:             panic("rval");
  71:         case T_PLUS:
  72:         case T_MINUS:
  73:             /*
  74: 			 * if child is relational (bogus) or adding operator,
  75: 			 * parenthesize child.
  76: 			 * this has the unaesthetic property that
  77: 			 * --i prints as -(-i), but is needed to catch
  78: 			 * -(a+b) which must print as -(a+b), not as -a+b.
  79: 			 * otherwise child has higher precedence
  80: 			 * and need not be parenthesized.
  81: 			 */
  82:             ppop(r[0] == T_PLUS ? "+" : "-");
  83:             al = r[2];
  84:             rvalue(r[2], prec(al) <= prec(r) || full);
  85:             break;
  86:         case T_NOT:
  87:             /*
  88: 			 * if child is of lesser precedence
  89: 			 * (i.e. not another not operator)
  90: 			 * parenthesize it.
  91: 			 * nested not operators need not be parenthesized
  92: 			 * because it's a prefix operator.
  93: 			 */
  94:             ppkw(opname);
  95:             ppspac();
  96:             al = r[2];
  97:             rvalue(r[2], prec(al) < prec(r) || full);
  98:             break;
  99:         case T_EQ:
 100:         case T_NE:
 101:         case T_GE:
 102:         case T_LE:
 103:         case T_GT:
 104:         case T_LT:
 105:             /*
 106: 			 * make the aesthetic choice to
 107: 			 * fully parenthesize relational expressions,
 108: 			 * in spite of left to right associativity.
 109: 			 * note: there are no operators with lower precedence.
 110: 			 */
 111:             al = r[2];
 112:             rvalue(al, prec(al) <= prec(r) || full);
 113:             goto rest;
 114:         case T_AND:
 115:         case T_OR:
 116:         case T_MULT:
 117:         case T_ADD:
 118:         case T_SUB:
 119:         case T_DIVD:
 120:         case T_MOD:
 121:         case T_DIV:
 122:         case T_IN:
 123:             /*
 124: 			 * need not parenthesize left child
 125: 			 * if it has equal precedence,
 126: 			 * due to left to right associativity.
 127: 			 * right child needs to be parenthesized
 128: 			 * if it has equal (or lesser) precedence.
 129: 			 */
 130:             al = r[2];
 131:             rvalue(al, prec(al) < prec(r) || full);
 132: rest:
 133:             ppspac();
 134:             if (alph(opname[0]))
 135:                 ppkw(opname);
 136:             else
 137:                 ppop(opname);
 138:             ppspac();
 139:             al = r[3];
 140:             rvalue(al, prec(al) <= prec(r) || full);
 141:             break;
 142:     }
 143:     if (par)
 144:         ppket(")");
 145: }
 146: 
 147: /*
 148:  * Prec returns the precedence of an operator,
 149:  * with larger numbers indicating stronger binding.
 150:  * This is used to determine when parenthesization
 151:  * is needed on subexpressions.
 152:  */
 153: prec(r)
 154:     register int *r;
 155: {
 156: 
 157:     if (r == NIL)
 158:         return;
 159:     switch (r[0]) {
 160:         case T_NOT:
 161:             return (3);
 162:         case T_MULT:
 163:         case T_DIVD:
 164:         case T_DIV:
 165:         case T_MOD:
 166:         case T_AND:
 167:             return (2);
 168:         case T_ADD:
 169:         case T_SUB:
 170:         case T_OR:
 171:         case T_PLUS:
 172:         case T_MINUS:
 173:             return (1);
 174:         default:
 175:             return (0);
 176:     }
 177: }

Defined functions

prec defined in line 153; used 10 times

Defined variables

sccsid defined in line 8; never used

Defined macros

alph defined in line 23; used 1 times
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1028
Valid CSS Valid XHTML 1.0 Strict