void rqlParseDump(struct rqlParse *p, int depth, FILE *f) /* Dump out rqlParse tree and children. */ { spaceOut(f, 3*depth); fprintf(f, "%s ", rqlOpToString(p->op)); rqlValDump(p->val, p->type, f); fprintf(f, "\n"); struct rqlParse *child; for (child = p->children; child != NULL; child= child->next) rqlParseDump(child, depth+1, f); }
static struct rqlEval rqlLocalEval(struct rqlParse *p, void *record, RqlEvalLookup lookup, struct lm *lm) /* Evaluate self on parse tree, allocating memory if needed from lm. */ { struct rqlEval res; switch (p->op) { case rqlOpLiteral: res.val = p->val; res.type = p->type; break; case rqlOpSymbol: res.type = rqlTypeString; char *s = lookup(record, p->val.s); if (s == NULL) res.val.s = ""; else res.val.s = s; break; case rqlOpEq: res = rqlEvalEq(p, record, lookup, lm); break; case rqlOpNe: res = rqlEvalEq(p, record, lookup, lm); res.val.b = !res.val.b; break; /* Inequalities. */ case rqlOpLt: res = rqlEvalLt(p, record, lookup, lm); break; case rqlOpGt: res = rqlEvalGt(p, record, lookup, lm); break; case rqlOpLe: res = rqlEvalGt(p, record, lookup, lm); res.val.b = !res.val.b; break; case rqlOpGe: res = rqlEvalLt(p, record, lookup, lm); res.val.b = !res.val.b; break; case rqlOpLike: res = rqlEvalLike(p,record, lookup, lm); break; /* Logical ops. */ case rqlOpAnd: { res.type = rqlTypeBoolean; res.val.b = TRUE; struct rqlParse *c; for (c = p->children; c != NULL; c= c->next) { struct rqlEval e = rqlLocalEval(c, record, lookup, lm); if (!e.val.b) { res.val.b = FALSE; break; } } break; } case rqlOpOr: { res.type = rqlTypeBoolean; res.val.b = FALSE; struct rqlParse *c; for (c = p->children; c != NULL; c= c->next) { struct rqlEval e = rqlLocalEval(c, record, lookup, lm); if (e.val.b) { res.val.b = TRUE; break; } } break; } case rqlOpNot: res = rqlLocalEval(p->children, record, lookup, lm); res.val.b = !res.val.b; break; /* Type casts. */ case rqlOpStringToBoolean: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeBoolean; res.val.b = (res.val.s[0] != 0); break; case rqlOpIntToBoolean: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeBoolean; res.val.b = (res.val.i != 0); break; case rqlOpDoubleToBoolean: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeBoolean; res.val.b = (res.val.x != 0.0); break; case rqlOpStringToInt: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeInt; res.val.i = atoi(res.val.s); break; case rqlOpDoubleToInt: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeInt; res.val.i = res.val.x; break; case rqlOpStringToDouble: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeDouble; res.val.x = atof(res.val.s); break; case rqlOpBooleanToInt: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeInt; res.val.i = res.val.b; break; case rqlOpBooleanToDouble: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeDouble; res.val.x = res.val.b; break; case rqlOpIntToDouble: res = rqlLocalEval(p->children, record, lookup, lm); res.type = rqlTypeDouble; res.val.x = res.val.b; break; /* Arithmetical negation. */ case rqlOpUnaryMinusInt: res = rqlLocalEval(p->children, record, lookup, lm); res.val.i = -res.val.i; break; case rqlOpUnaryMinusDouble: res = rqlLocalEval(p->children, record, lookup, lm); res.val.x = -res.val.x; break; case rqlOpArrayIx: res = rqlEvalArrayIx(p, record, lookup, lm); break; default: errAbort("Unknown op %s\n", rqlOpToString(p->op)); res.type = rqlTypeInt; // Keep compiler from complaining. res.val.i = 0; // Keep compiler from complaining. break; } return res; }