|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.