int valueEquals(Value *v1, Value *v2) { if (v1 == v2) return 1; if (v1->type != v2->type) return 0; switch (v1->type) { case INT_VALUE_TYPE: case ENV_VALUE_TYPE: case BUILTIN_FUN_VALUE_TYPE: case CLOSURE_VALUE_TYPE: return v1->data == v2->data; case LIST_VALUE_TYPE: { List *l1 = v1->data; List *l2 = v2->data; int len = listSize(l1); int i; if (len != listSize(l2)) return 0; for (i = 0; i < len; i++) if (!valueEquals(listGet(l1, i), listGet(l2, i))) return 0; return 1; } case STRING_VALUE_TYPE: return strcmp((char *)v1->data, (char *)v2->data) == 0; case NONE_VALUE_TYPE: return 1; // singleton, same type means equal default: error("unknown value type passed to valueEquals: %d\n", v1->type); } }
RC evalExpr(Record *record, Schema *schema, Expr *expr, Value **result) { Value *lIn; Value *rIn; MAKE_VALUE(*result, DT_INT, -1); switch (expr->type) { case EXPR_OP: { Operator *op = expr->expr.op; bool twoArgs = (op->type != OP_BOOL_NOT); // lIn = (Value *) malloc(sizeof(Value)); // rIn = (Value *) malloc(sizeof(Value)); CHECK(evalExpr(record, schema, op->args[0], &lIn)); if (twoArgs) CHECK(evalExpr(record, schema, op->args[1], &rIn)); switch (op->type) { case OP_BOOL_NOT: CHECK(boolNot(lIn, *result)) ; break; case OP_BOOL_AND: CHECK(boolAnd(lIn, rIn, *result)) ; break; case OP_BOOL_OR: CHECK(boolOr(lIn, rIn, *result)) ; break; case OP_COMP_EQUAL: CHECK(valueEquals(lIn, rIn, *result)) ; break; case OP_COMP_SMALLER: CHECK(valueSmaller(lIn, rIn, *result)) ; break; default: break; } // cleanup freeVal(lIn); if (twoArgs) freeVal(rIn); } break; case EXPR_CONST: CPVAL(*result, expr->expr.cons); break; case EXPR_ATTRREF: free(*result); CHECK(getAttr(record, schema, expr->expr.attrRef, result)) ; break; } return RC_OK; }