Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kcc/cceval.c
There are 8 other files named cceval.c in the archive. Click here to see a list.
/*
** cceval - partially evaluate parse trees
** David Eppstein / Stanford University / 28-Jul-84
**
** This is used mostly by gfor(), to see whether the loop test
** can be omitted the first time through, and thus moved to the
** end of the loop.
*/
#include "cc.h" /* include standard decls (not cc.g) */
static unset; /* whether an unbound var was found */
/* ----------------------------------------------- */
/* partially evaluate boolean expression */
/* ----------------------------------------------- */
istrue(test,bindings)
node test, bindings;
{
unset = 0;
return optimize && value(test, bindings) && !unset;
}
/* ---------------------------------------- */
/* recursive expression evaluator */
/* ---------------------------------------- */
static value(test, bindings)
node test, bindings;
{
node lookup();
if (test == NULL) return 1;
switch (test->nop) {
case ICONST:
return test->niconst;
case IDENT:
test = lookup(test->nid, bindings); /* find variable assignment */
if (test == NULL) break; /* none found, give up */
return value(test, NULL); /* otherwise re-eval hoping no vars */
case LAND:
return value(test->left, bindings) && value(test->right, bindings);
case LOR:
return value(test->left, bindings) || value(test->right, bindings);
case NOT:
return !value(test->left, bindings);
case EQUAL:
return value(test->left, bindings) == value(test->right, bindings);
case LESS:
return value(test->left, bindings) < value(test->right, bindings);
case GREAT:
return value(test->left, bindings) > value(test->right, bindings);
case NEQ:
return value(test->left, bindings) != value(test->right, bindings);
case LEQ:
return value(test->left, bindings) <= value(test->right, bindings);
case GEQ:
return value(test->left, bindings) >= value(test->right, bindings);
case PLUS:
return value(test->left, bindings) + value(test->right, bindings);
case MINUS:
return value(test->left, bindings) - value(test->right, bindings);
case MPLY:
return value(test->left, bindings) * value(test->right, bindings);
case DIV:
return value(test->left, bindings) / value(test->right, bindings);
case MOD:
return value(test->left, bindings) % value(test->right, bindings);
}
/* here when unrecognized node or unbound var, remember bad expr */
unset = 1; /* tell caller we lost */
return 0; /* and pick arbitrary val to return */
}
/* ------------------------------------------------ */
/* find an assignment to a given variable */
/* ------------------------------------------------ */
static node lookup(var, bindings)
struct SYMBOL *var;
node bindings;
{
node result;
if (bindings == NULL) return NULL;
switch (bindings->nop) {
case EXPRESS:
result = lookup(var, bindings->right);
if (result != NULL) return result;
else return lookup(var, bindings->left);
case ASGN:
if (bindings->left->nop == IDENT && bindings->left->nid == var)
return bindings->right;
else return NULL;
default:
return NULL;
}
}