home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pxp / rval.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  2KB  |  140 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3. /*
  4.  * pxp - Pascal execution profiler
  5.  *
  6.  * Bill Joy UCB
  7.  * Version 1.2 January 1979
  8.  */
  9.  
  10. #include "0.h"
  11. #include "tree.h"
  12.  
  13. extern    char *opnames[];
  14.  
  15. #define alph(c)        ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
  16. /*
  17.  * Rvalue reformats an expression.
  18.  * Par is a flag indicating that the expression
  19.  * should be parenthesized if it is non-atomic.
  20.  */
  21. rvalue(r, par)
  22.     register int *r;
  23.     int par;
  24. {
  25.     register int *al;
  26.     register char *opname;
  27.  
  28.     if (r == NIL) {
  29.         ppid("{expr}");
  30.         return;
  31.     }
  32.     if (r[0] <= T_IN)
  33.         opname = opnames[r[0]];
  34.     switch (r[0]) {
  35.         case T_BINT:
  36.         case T_INT:
  37.         case T_FINT:
  38.             ppnumb(r[2]);
  39.             if (r[0] == T_BINT)
  40.                 ppsep("b");
  41.             return;
  42.         case T_NIL:
  43.             ppkw("nil");
  44.             return;
  45.         case T_FCALL:
  46.             funccod(r);
  47.             return;
  48.         case T_VAR:
  49.             lvalue(r);
  50.             return;
  51.         case T_CSET:
  52.             cset(r);
  53.             return;
  54.         case T_STRNG:
  55.             ppstr(r[2]);
  56.             return;
  57.     }
  58.     if (par)
  59.         ppbra("(");
  60.     switch (r[0]) {
  61.         default:
  62.             panic("rval");
  63.         case T_PLUS:
  64.         case T_MINUS:
  65.             ppop(r[0] == T_PLUS ? "+" : "-");
  66.             al = r[2];
  67.             rvalue(r[2], prec(al) > prec(r) || full);
  68.             break;
  69.         case T_NOT:
  70.             ppkw(opname);
  71.             ppspac();
  72.             rvalue(r[2], 1);
  73.             break;
  74.         case T_EQ:
  75.         case T_NE:
  76.         case T_GE:
  77.         case T_LE:
  78.         case T_GT:
  79.         case T_LT:
  80.             al = r[2];
  81.             rvalue(al, prec(al) <= prec(r) || full);
  82.             goto rest;
  83.         case T_AND:
  84.         case T_OR:
  85.         case T_MULT:
  86.         case T_ADD:
  87.         case T_SUB:
  88.         case T_DIVD:
  89.         case T_MOD:
  90.         case T_DIV:
  91.         case T_IN:
  92.             al = r[2];
  93.             rvalue(al, prec(al) < prec(r) || full);
  94. rest:
  95.             ppspac();
  96.             if (alph(opname[0]))
  97.                 ppkw(opname);
  98.             else
  99.                 ppop(opname);
  100.             ppspac();
  101.             al = r[3];
  102.             rvalue(al, prec(al) <= prec(r) || full);
  103.             break;
  104.     }
  105.     if (par)
  106.         ppket(")");
  107. }
  108.  
  109. /*
  110.  * Prec returns the precedence of an operator,
  111.  * with larger numbers indicating stronger binding.
  112.  * This is used to determine when parenthesization
  113.  * is needed on subexpressions.
  114.  */
  115. prec(r)
  116.     register int *r;
  117. {
  118.  
  119.     if (r == NIL)
  120.         return;
  121.     switch (r[0]) {
  122.         case T_NOT:
  123.             return (3);
  124.         case T_MULT:
  125.         case T_DIVD:
  126.         case T_DIV:
  127.         case T_MOD:
  128.         case T_AND:
  129.             return (2);
  130.         case T_ADD:
  131.         case T_SUB:
  132.         case T_OR:
  133.         case T_PLUS:
  134.         case T_MINUS:
  135.             return (1);
  136.         default:
  137.             return (0);
  138.     }
  139. }
  140.