static Value* vecCompOp(const Vector* vector1, const Vector* vector2, const Context* ctx, BINTYPE bin) { unsigned count = vector1->vals->count; if(count != vector2->vals->count && vector2->vals->count > 1) { return ValErr(mathError("Cannot %s vectors of different sizes.", binop_verb[bin])); } ArgList* newv = ArgList_new(count); unsigned i; for(i = 0; i < count; i++) { /* Perform the specified operation on each matching component */ Value* val2; if(vector2->vals->count == 1) { val2 = vector2->vals->args[0]; } else { val2 = vector2->vals->args[i]; } BinOp* op = BinOp_new(bin, Value_copy(vector1->vals->args[i]), Value_copy(val2)); Value* result = BinOp_eval(op, ctx); BinOp_free(op); /* Error checking */ if(result->type == VAL_ERR) { ArgList_free(newv); return result; } /* Store result */ newv->args[i] = result; } return ValVec(Vector_new(newv)); }
Value* Vector_parse(const char** expr) { ArgList* vals = ArgList_parse(expr, ',', '>'); if(vals == NULL) return ValErr(ignoreError()); if(vals->count < 2) { ArgList_free(vals); return ValErr(syntaxError("Vector must have at least 2 components.")); } return ValVec(Vector_new(vals)); }
Value* Vector_parse(const char** expr, parser_cb* cb) { ArgList* vals = ArgList_parse(expr, ',', '>', cb); if(vals == NULL) { /* Error occurred and has already been raised */ return ValErr(ignoreError()); } if(vals->count < 1) { ArgList_free(vals); return ValErr(syntaxError("Vector must have at least 1 component.")); } return ValVec(Vector_new(vals)); }
static Value* vecScalarOp(const Vector* vec, const Value* scalar, const Context* ctx, BINTYPE bin) { ArgList* newv = ArgList_new(vec->vals->count); unsigned i; for(i = 0; i < vec->vals->count; i++) { /* Perform operation */ BinOp* op = BinOp_new(bin, Value_copy(vec->vals->args[i]), Value_copy(scalar)); Value* result = BinOp_eval(op, ctx); BinOp_free(op); /* Error checking */ if(result->type == VAL_ERR) { ArgList_free(newv); return result; } /* Store result */ newv->args[i] = result; } return ValVec(Vector_new(newv)); }
void Vector_free(Vector* vec) { ArgList_free(vec->vals); free(vec); }