📄 rval.c
字号:
/*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)rval.c 8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * pxp - Pascal execution profiler * * Bill Joy UCB * Version 1.2 January 1979 */#include "0.h"#include "tree.h"extern char *opnames[];#define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))/* * Rvalue reformats an expression. * Par is a flag indicating that the expression * should be parenthesized if it is non-atomic. */rvalue(r, par) register int *r; int par;{ register int *al; register char *opname; if (r == NIL) { ppid("{expr}"); return; } if (r[0] <= T_IN) opname = opnames[r[0]]; switch (r[0]) { case T_BINT: case T_INT: case T_FINT: ppnumb(r[2]); if (r[0] == T_BINT) ppsep("b"); return; case T_NIL: ppkw("nil"); return; case T_FCALL: funccod(r); return; case T_VAR: lvalue(r); return; case T_CSET: cset(r); return; case T_STRNG: ppstr(r[2]); return; } if (par) ppbra("("); switch (r[0]) { default: panic("rval"); case T_PLUS: case T_MINUS: /* * if child is relational (bogus) or adding operator, * parenthesize child. * this has the unaesthetic property that * --i prints as -(-i), but is needed to catch * -(a+b) which must print as -(a+b), not as -a+b. * otherwise child has higher precedence * and need not be parenthesized. */ ppop(r[0] == T_PLUS ? "+" : "-"); al = r[2]; rvalue(r[2], prec(al) <= prec(r) || full); break; case T_NOT: /* * if child is of lesser precedence * (i.e. not another not operator) * parenthesize it. * nested not operators need not be parenthesized * because it's a prefix operator. */ ppkw(opname); ppspac(); al = r[2]; rvalue(r[2], prec(al) < prec(r) || full); break; case T_EQ: case T_NE: case T_GE: case T_LE: case T_GT: case T_LT: /* * make the aesthetic choice to * fully parenthesize relational expressions, * in spite of left to right associativity. * note: there are no operators with lower precedence. */ al = r[2]; rvalue(al, prec(al) <= prec(r) || full); goto rest; case T_AND: case T_OR: case T_MULT: case T_ADD: case T_SUB: case T_DIVD: case T_MOD: case T_DIV: case T_IN: /* * need not parenthesize left child * if it has equal precedence, * due to left to right associativity. * right child needs to be parenthesized * if it has equal (or lesser) precedence. */ al = r[2]; rvalue(al, prec(al) < prec(r) || full);rest: ppspac(); if (alph(opname[0])) ppkw(opname); else ppop(opname); ppspac(); al = r[3]; rvalue(al, prec(al) <= prec(r) || full); break; } if (par) ppket(")");}/* * Prec returns the precedence of an operator, * with larger numbers indicating stronger binding. * This is used to determine when parenthesization * is needed on subexpressions. */prec(r) register int *r;{ if (r == NIL) return; switch (r[0]) { case T_NOT: return (3); case T_MULT: case T_DIVD: case T_DIV: case T_MOD: case T_AND: return (2); case T_ADD: case T_SUB: case T_OR: case T_PLUS: case T_MINUS: return (1); default: return (0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -