#include #include "lceb.h" int eval_node(node, depth, pvals, pops, ncalcs) NODE *node; int depth; int *pvals; char *pops; int *ncalcs; { static int *vals, *val_zero; static char *ops, *ops_zero; static int totcalc; static *node_zero; int val1, val2, op, res=-1, i, lcalcs, rcalcs; if (depth == 0) { val_zero=vals=pvals; ops_zero=ops=pops; node_zero=node; totcalc=0; } # ifdef DEBUG1 for (i=0; i<=depth; ++i) printf(" "); printf("eval : depth=%d : ncalcs=%d", depth, *ncalcs); if (node->type == TREE_NODE) { printf("node(%c)\n", *ops); print_node(node, TREE_TOP, 0, 0); } else { printf("val(%d)\n", *vals); } # endif if (node->type == TREE_LEAF) { node->val=*vals; res=*vals; vals++; *ncalcs=0; //printf("leaf=%d\n", res); } else { op=*ops; node->op=*ops; ops++; totcalc++; //printf("NEW node(%s)\n", ops); val1=eval_node(node->left, depth+1, pvals, ops, &lcalcs); //printf("val1=%d ", val1); if (val1 <= 0) return -1; val2=eval_node(node->right, depth+1, pvals, ops, &rcalcs); //printf("val2=%d\n", val2); if (val2 <= 0) return -1; switch (op) { case Add: res=val1+val2; break; case Mul: res=val1*val2; break; case Sub: if (val1 > val2) res=val1-val2; break; case Div: if (val1 > val2 && (val1 % val2 == 0)) res=val1/val2; break; case Nop: case End: fprintf(stderr, "Fatal: bad op [%d] in eval\n", op); exit(1); break; } *ncalcs=lcalcs+rcalcs+1; } if (res > 0) { if (!check_best(res, *ncalcs, node, val_zero, ops_zero)) res=-1; } # ifdef DEBUG1 for (i=0; i<=depth; ++i) printf(" "); printf("res=%d\n", res); # endif return res; }