static int32_t qb_validate_operands_array_pad(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *input = &operands[0], *size = &operands[1], *value = &operands[2]; if(IS_SCALAR(input->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array"); return FALSE; } if(!IS_SCALAR(size->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "scalar"); return FALSE; } if(input->address->dimension_count > 1) { qb_address *element_size_address = input->address->array_size_addresses[1]; qb_address *value_size_address = value->address->array_size_address; if(IS_IMMUTABLE(element_size_address) && IS_IMMUTABLE(value_size_address)) { uint32_t element_size = VALUE(U32, element_size_address); uint32_t value_size = VALUE(U32, value_size_address); if(element_size != value_size) { qb_report_unmet_intrinsic_condition_exception(cxt->line_id, cxt->intrinsic_function, "the third parameter to have the same size as the elements in the input array"); return FALSE; } } else { qb_operand guard_operands[2] = { { QB_OPERAND_ADDRESS, { value_size_address } }, { QB_OPERAND_ADDRESS, { element_size_address } } }; qb_operand guard_result = { QB_OPERAND_EMPTY, { NULL } }; qb_produce_op(cxt, &factory_guard_array_size_exact, guard_operands, 2, &guard_result, NULL, 0, NULL); } } else { if(!IS_SCALAR(value->address)) { qb_report_unmet_intrinsic_condition_exception(cxt->line_id, cxt->intrinsic_function, "the third parameter to be a scalar when the input array is not multidimensional"); return FALSE; } } return TRUE; }
static int32_t qb_validate_operands_array_element(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *container = &operands[0]; qb_operand *index = &operands[1]; if(container->type != QB_OPERAND_ADDRESS || IS_SCALAR(container->address)) { qb_report_not_an_array_exception(cxt->line_id); return FALSE; } if((index->type == QB_OPERAND_ADDRESS && !IS_SCALAR(index->address)) || (index->type == QB_OPERAND_ARRAY_INITIALIZER)) { qb_report_illegal_array_index_exception(cxt->line_id); return FALSE; } else if(index->type == QB_OPERAND_ZVAL) { if(index->constant->type == IS_STRING) { qb_report_associative_array_exception(cxt->line_id); return FALSE; } else if(index->constant->type != IS_BOOL && index->constant->type != IS_LONG && index->constant->type != IS_DOUBLE) { qb_report_illegal_array_index_exception(cxt->line_id); return FALSE; } } else if(index->type == QB_OPERAND_NONE) { // an append operation if(!IS_RESIZABLE(container->address)) { qb_report_fixed_length_array_exception(cxt->line_id); return FALSE; } } return TRUE; }
SvecType * op_svec_by_svec_internal(int operation, SvecType *svec1, SvecType *svec2) { SparseData left = sdata_from_svec(svec1); SparseData right = sdata_from_svec(svec2); int scalar_args=check_scalar(IS_SCALAR(svec1),IS_SCALAR(svec2)); return(svec_operate_on_sdata_pair(scalar_args,operation,left,right)); }
static int32_t qb_validate_operands_array_fill(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *start_index = &operands[0], *number = &operands[1]; if(!IS_SCALAR(start_index->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "scalar"); return FALSE; } if(!IS_SCALAR(number->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "scalar"); return FALSE; } return TRUE; }
static int32_t qb_validate_operands_two_arrays(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *operand1 = &operands[0], *operand2 = &operands[1]; if(IS_SCALAR(operand1->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array"); return FALSE; } if(IS_SCALAR(operand2->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "array"); return FALSE; } return TRUE; }
void check_dimension(SvecType *svec1, SvecType *svec2, char *msg) { /* If the array dimensions aren't the same, operation has no meaning unless one of * the inputs is a constant */ if ((!IS_SCALAR(svec1)) && (!IS_SCALAR(svec2)) && (svec1->dimension != svec2->dimension)) { // elog(NOTICE,"svec1: %s",svec_out_internal(svec1)); // elog(NOTICE,"svec2: %s",svec_out_internal(svec2)); ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("%s: array dimension of inputs are not the same: dim1=%d, dim2=%d\n", msg, svec1->dimension, svec2->dimension))); } }
static int32_t qb_validate_operands_array_rand(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *container = &operands[0], *count = &operands[1]; if(IS_SCALAR(container->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array"); return FALSE; } if(count->type == QB_OPERAND_ADDRESS) { if(!IS_SCALAR(count->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "scalar"); return FALSE; } } return TRUE; }
static int32_t qb_transfer_operands_unset_object_property(qb_compiler_context *cxt, qb_op_factory *f, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_operand *result, qb_operand *dest, uint32_t dest_count) { qb_operand *container = &operands[0], *name = &operands[1]; qb_address *address = qb_obtain_object_property(cxt, container, name, QB_ARRAY_BOUND_CHECK_ISSET); if(IS_SCALAR(address)) { dest[0].address = address; dest[0].type = QB_OPERAND_ADDRESS; } else { if(IS_RESIZABLE(address)) { if(IS_MULTIDIMENSIONAL(address)) { dest[0].address = address->dimension_addresses[0]; dest[0].type = QB_OPERAND_ADDRESS; dest[1].address = address; dest[1].type = QB_OPERAND_SEGMENT_SELECTOR; dest[2].address = address; dest[2].type = QB_OPERAND_ADDRESS; } else { dest[0].address = address; dest[0].type = QB_OPERAND_SEGMENT_SELECTOR; dest[1].address = address; dest[1].type = QB_OPERAND_ADDRESS; } } else { qb_address *predicate_address = qb_obtain_predicate_address(cxt, container->address, FALSE); dest[0].address = predicate_address; dest[0].type = QB_OPERAND_ADDRESS; dest[1].address = address; dest[1].type = QB_OPERAND_ADDRESS; } } return TRUE; }
/* & | ! */ SEXP attribute_hidden do_logic(SEXP call, SEXP op, SEXP args, SEXP env) { SEXP ans, arg1, arg2; int argc; if (args == R_NilValue) argc = 0; else if (CDR(args) == R_NilValue) argc = 1; else if (CDDR(args) == R_NilValue) argc = 2; else argc = length(args); arg1 = CAR(args); arg2 = CADR(args); if (ATTRIB(arg1) != R_NilValue || ATTRIB(arg2) != R_NilValue) { if (DispatchGroup("Ops",call, op, args, env, &ans)) return ans; } else if (argc == 1 && IS_SCALAR(arg1, LGLSXP)) { /* directly handle '!' operator for simple logical scalars. */ int v = LOGICAL(arg1)[0]; return ScalarLogical(v == NA_LOGICAL ? v : ! v); } if (argc == 1) return lunary(call, op, arg1); else if (argc == 2) return lbinary(call, op, args); else error(_("binary operations require two arguments")); return R_NilValue; /* for -Wall */ }
/* & | ! */ SEXP attribute_hidden do_logic(SEXP call, SEXP op, SEXP args, SEXP env) { SEXP arg1 = CAR(args); //, arg2 = CADR(args) Rboolean attr1 = ATTRIB(arg1) != R_NilValue; if (attr1 || ATTRIB(CADR(args)) != R_NilValue) { SEXP ans; if (DispatchGroup("Ops", call, op, args, env, &ans)) return ans; } /* The above did dispatch to valid S3/S4 methods, including those with * "wrong" number of arguments. * Now require binary calls to `&` and `|` or unary calls to `!` : */ checkArity(op, args); if (CDR(args) == R_NilValue) { // one argument <==> !(arg1) if (!attr1 && IS_SCALAR(arg1, LGLSXP)) { /* directly handle '!' operator for simple logical scalars. */ int v = LOGICAL(arg1)[0]; return ScalarLogical(v == NA_LOGICAL ? v : ! v); } return lunary(call, op, arg1); } // else : two arguments return lbinary(call, op, args); }
static int32_t qb_transfer_operands_unset(qb_compiler_context *cxt, qb_op_factory *f, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_operand *result, qb_operand *dest, uint32_t dest_count) { qb_operand *variable = &operands[0]; if(IS_SCALAR(variable->address)) { dest[0] = *variable; } else { if(IS_RESIZABLE(variable->address)) { if(IS_MULTIDIMENSIONAL(variable->address)) { // need to set the first dimension to zero as well dest[0].address = variable->address->dimension_addresses[0]; dest[0].type = QB_OPERAND_ADDRESS; dest[1].address = variable->address; dest[1].type = QB_OPERAND_SEGMENT_SELECTOR; dest[2] = *variable; } else { dest[0].address = variable->address; dest[0].type = QB_OPERAND_SEGMENT_SELECTOR; dest[1] = *variable; } } else { // the predicate is always use, since we're unsetting an array accessible through a variable dest[0].address = cxt->true_address; dest[0].type = QB_OPERAND_ADDRESS; dest[1] = *variable; } } return TRUE; }
static int32_t qb_validate_operands_cross_product(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { uint32_t i; for(i = 0; i < operand_count; i++) { qb_operand *operand = &operands[0]; if(IS_SCALAR(operand->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, i, "array"); return FALSE; } } if(operand_count == 3) { qb_operand *operand1 = &operands[0], *operand2 = &operands[1], *operand3 = &operands[2]; qb_address *v1_width_address = DIMENSION_ADDRESS(operand1->address, -1); qb_address *v2_width_address = DIMENSION_ADDRESS(operand2->address, -1); qb_address *v3_width_address = DIMENSION_ADDRESS(operand3->address, -1); if(IS_IMMUTABLE(v1_width_address) && IS_IMMUTABLE(v2_width_address) && IS_IMMUTABLE(v3_width_address)) { uint32_t v1_width = VALUE(U32, v1_width_address); uint32_t v2_width = VALUE(U32, v2_width_address); uint32_t v3_width = VALUE(U32, v3_width_address); if(!(v1_width == v2_width && v2_width == v3_width && v1_width == 4)) { qb_report_invalid_4d_cross_product_exception(cxt->line_id, v1_width, v2_width, v3_width); return FALSE; } } else { qb_operand operands[3] = { { QB_OPERAND_ADDRESS, { v1_width_address } }, { QB_OPERAND_ADDRESS, { v2_width_address } }, { QB_OPERAND_ADDRESS, { v3_width_address } } }; qb_produce_op(cxt, &factory_validate_cross_product_4d, operands, 3, NULL, NULL, 0, NULL); } } else { qb_operand *operand1 = &operands[0], *operand2 = &operands[1]; qb_address *v1_width_address = DIMENSION_ADDRESS(operand1->address, -1); qb_address *v2_width_address = DIMENSION_ADDRESS(operand2->address, -1); if(IS_IMMUTABLE(v1_width_address) && IS_IMMUTABLE(v2_width_address)) { uint32_t v1_width = VALUE(U32, v1_width_address); uint32_t v2_width = VALUE(U32, v2_width_address); if(!(v1_width == v2_width && 2 <= v1_width && v2_width <= 3)) { qb_report_invalid_cross_product_exception(cxt->line_id, v1_width, v2_width); return FALSE; } } else { qb_operand operands[2] = { { QB_OPERAND_ADDRESS, { v1_width_address } }, { QB_OPERAND_ADDRESS, { v2_width_address } } }; uint32_t width = 3; if(IS_IMMUTABLE(v1_width_address)) { width = VALUE(U32, v1_width_address); } if(IS_IMMUTABLE(v2_width_address)) { width = VALUE(U32, v2_width_address); } if(width == 2) { qb_produce_op(cxt, &factory_validate_cross_product_2d, operands, 2, NULL, NULL, 0, NULL); } else { qb_produce_op(cxt, &factory_validate_cross_product_3d, operands, 2, NULL, NULL, 0, NULL); } } } return TRUE; }
static int32_t qb_validate_operands_range(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *start = &operands[0], *end = &operands[1], *interval = &operands[2]; if(!IS_SCALAR(start->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "scalar"); return FALSE; } if(!IS_SCALAR(end->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "scalar"); return FALSE; } if(interval->type == QB_OPERAND_ADDRESS && !IS_SCALAR(interval->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 2, "scalar"); return FALSE; } return TRUE; }
static int32_t qb_choose_set_or_scalar_op(qb_compiler_context *cxt, void *factory, qb_operand *operands, uint32_t operand_count, qb_operand *result, uint32_t *jump_target_indices, uint32_t jump_target_count, qb_result_prototype *result_prototype) { qb_set_op_chooser *c = factory; if(IS_SCALAR(operands[0].address)) { factory = c->scalar_factory; } else { factory = c->set_factory; } return qb_produce_op(cxt, factory, operands, operand_count, result, jump_target_indices, jump_target_count, result_prototype); }
static int32_t qb_validate_operands_array_diff(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *value = &operands[0]; if(cxt->argument_offset == 0) { if(IS_SCALAR(value->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array"); return FALSE; } } return TRUE; }
static int32_t qb_validate_operands_sample_convolution(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *matrix = &operands[3], *divider = &operands[4], *offset = &operands[5]; if(!qb_validate_operands_sampling(cxt, f, expr_type, flags, operands, operand_count, result_destination)) { return FALSE; } if(matrix->address->dimension_count != 2) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 3, "2x2 matrix"); return FALSE; } if(divider->type == QB_OPERAND_ADDRESS && !IS_SCALAR(divider->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 4, "scalar"); return FALSE; } if(offset->type == QB_OPERAND_ADDRESS && !IS_SCALAR(offset->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 5, "scalar"); return FALSE; } return TRUE; }
static int32_t qb_transfer_operands_boolean_cast(qb_compiler_context *cxt, qb_op_factory *f, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_operand *result, qb_operand *dest, uint32_t dest_count) { qb_operand *variable = &operands[0]; if(IS_SCALAR(variable->address)) { dest[0] = *variable; } else { dest[0].address = variable->address->array_size_address; dest[0].type = QB_OPERAND_ADDRESS; } dest[1] = *result; return TRUE; }
static int32_t qb_validate_operands_minmax_array(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *container = &operands[0]; if(operand_count == 1) { if(IS_SCALAR(container->address)) { qb_report_unmet_intrinsic_condition_exception(cxt->line_id, cxt->intrinsic_function, "an array as parameter when only one parameter is given"); return FALSE; } } return TRUE; }
static int32_t qb_validate_operands_refract(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *operand3 = &operands[2]; qb_validate_operands_matching_vector_width(cxt, f, expr_type, flags, operands, operand_count, result_destination); if(!IS_SCALAR(operand3->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 2, "scalar"); return FALSE; } return TRUE; }
static int32_t qb_transfer_operands_object_property_isset(qb_compiler_context *cxt, qb_op_factory *f, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_operand *result, qb_operand *dest, uint32_t dest_count) { qb_operand *container = &operands[0], *name = &operands[1]; qb_address *address = qb_obtain_object_property(cxt, container, name, QB_ARRAY_BOUND_CHECK_ISSET); qb_address *predicate_address = qb_obtain_predicate_address(cxt, address, FALSE); dest[0].address = IS_SCALAR(address) ? address : address->array_size_address; dest[0].type = QB_OPERAND_ADDRESS; dest[1].address = predicate_address; dest[1].type = QB_OPERAND_ADDRESS; dest[2] = *result; return TRUE; }
/* * Do exponentiation, only makes sense if the left is a vector and the right * is a scalar or if both are scalar */ static SvecType * pow_svec_by_scalar_internal(SvecType *svec1, SvecType *svec2) { SparseData left = sdata_from_svec(svec1); SparseData right = sdata_from_svec(svec2); SparseData sdata=NULL; double *left_vals=(double *)(left->vals->data); double *right_vals=(double *)(right->vals->data); double data_result; int scalar_args=check_scalar(IS_SCALAR(svec1),IS_SCALAR(svec2)); switch(scalar_args) { case 0: //neither arg is scalar case 1: //left arg is scalar ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Svec exponentiation is undefined when the right argument is a vector"))); break; case 2: //right arg is scalar if (right_vals[0] == 2.) //recognize the squared case as special { sdata = square_sdata(left); } else if (right_vals[0] == 3.) //recognize the cubed case as special { sdata = cube_sdata(left); } else if (right_vals[0] == 4.) //recognize the quad case as special { sdata = quad_sdata(left); } else { sdata = pow_sdata_by_scalar(left,(char *)right_vals); } break; case 3: //both args are scalar data_result = pow(left_vals[0],right_vals[0]); return(svec_make_scalar(data_result,1)); break; } return(svec_from_sparsedata(sdata,true)); }
static int32_t qb_validate_operands_unpack(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *value = &operands[0], *index = &operands[1], *type = &operands[2]; if(IS_SCALAR(value->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array of bytes"); return FALSE; } if(index->type == QB_OPERAND_ADDRESS) { if(!IS_SCALAR(index->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "index value"); return FALSE; } } if(expr_type == QB_TYPE_UNKNOWN || expr_type == QB_TYPE_ANY) { if(type->type != QB_OPERAND_NONE) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "constant indicating the type"); return FALSE; } else { qb_report_missing_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 2, "the type cannot be determined from context"); return FALSE; } } return TRUE; }
static int32_t qb_validate_operands_pack(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *value = &operands[0], *index = &operands[1]; if(value->type != QB_OPERAND_ADDRESS) { // type coercion had failed earlier if(index->type != QB_OPERAND_NONE) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "constant indicating the type"); } else { qb_report_missing_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 1, "the type cannot be determined from context"); } return FALSE; } if(!IS_SCALAR(value->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "scalar"); return FALSE; } return TRUE; }
static int32_t qb_validate_operands_object_property(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *container = &operands[0]; qb_operand *name = &operands[1]; if(name->type != QB_OPERAND_ZVAL) { qb_report_variable_variable_exception(cxt->line_id); return FALSE; } if(container->type == QB_OPERAND_NONE) { if(!qb_get_instance_variable(cxt, name->constant)) { zend_class_entry *scope = cxt->zend_op_array->scope; qb_report_missing_property_exception(cxt->line_id, scope, Z_STRVAL_P(name->constant)); return FALSE; } } else if(container->type == QB_OPERAND_ADDRESS) { uint32_t index, swizzle_mask; if(IS_SCALAR(container->address)) { qb_report_not_an_array_exception(cxt->line_id); return FALSE; } if(container->address->dimension_count == 1 && ((container->address->flags & QB_ADDRESS_VECTOR) || (container->address->flags & QB_ADDRESS_COMPLEX))) { index = qb_find_vector_index_alias(cxt, container->address, name->constant); if(index == INVALID_INDEX) { swizzle_mask = qb_get_vector_swizzle_mask(cxt, container->address, name->constant); if(swizzle_mask == INVALID_INDEX) { qb_report_missing_named_element_exception(cxt->line_id, Z_STRVAL_P(name->constant)); return FALSE; } } } else { if(!container->address->index_alias_schemes || !container->address->index_alias_schemes[0]) { qb_report_elements_not_named_exception(cxt->line_id); return FALSE; } index = qb_find_index_alias(cxt, container->address->index_alias_schemes[0], name->constant); if(index == INVALID_INDEX) { swizzle_mask = (container->address->dimension_count == 1) ? qb_get_swizzle_mask(cxt, container->address->index_alias_schemes[0], name->constant) : INVALID_INDEX; if(swizzle_mask == INVALID_INDEX) { qb_report_missing_named_element_exception(cxt->line_id, Z_STRVAL_P(name->constant)); return FALSE; } } } } return TRUE; }
static int32_t qb_validate_operands_array_push(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *container = &operands[0]; qb_address *container_element_size_address; uint32_t i; if(IS_TEMPORARY(container->address)) { qb_report_unexpected_value_as_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0); return FALSE; } if(IS_SCALAR(container->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "array"); return FALSE; } if(IS_FIXED_LENGTH(container->address)) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "variable-length array"); return FALSE; } if(container->address->dimension_count > 1) { container_element_size_address = container->address->array_size_addresses[1]; } else { container_element_size_address = cxt->one_address; } // make sure the elements being pushed in match the size of the elements in the container for(i = 1; i < operand_count; i++) { qb_address *address = operands[i].address; qb_address *element_size_address = address->array_size_address; if(container_element_size_address != element_size_address) { if(IS_IMMUTABLE(container_element_size_address) && IS_IMMUTABLE(element_size_address)) { uint32_t container_element_size = VALUE(U32, container_element_size_address); uint32_t element_size = VALUE(U32, element_size_address); if(container_element_size != element_size) { qb_report_unmet_intrinsic_condition_exception(cxt->line_id, cxt->intrinsic_function, "values of the same size as the elements in the container"); return FALSE; } } else { qb_operand guard_operands[2] = { { QB_OPERAND_ADDRESS, { element_size_address } }, { QB_OPERAND_ADDRESS, { container_element_size_address } } }; qb_operand guard_result = { QB_OPERAND_EMPTY, { NULL } }; qb_produce_op(cxt, &factory_guard_array_size_exact, guard_operands, 2, &guard_result, NULL, 0, NULL); } } } return TRUE; }
static uint32_t qb_get_address_length(qb_address *address) { uint32_t i, j; uint32_t length = sizeof(qb_address); // the address itself if(!IS_SCALAR(address)) { if(address->dimension_count > 1) { length += sizeof(qb_address *) * address->dimension_count * 2; length += sizeof(qb_address) * (address->dimension_count * 2 - 1); } else { length += sizeof(qb_address); } if(address->array_index_address) { if(address->array_index_address->segment_selector != QB_SELECTOR_CONSTANT_SCALAR || address->array_index_address->segment_offset != 0) { // it's not zero length += sizeof(qb_address); } } if(address->index_alias_schemes) { // need a pointer per dimension length += sizeof(qb_index_alias_scheme *) * address->dimension_count; for(i = 0; i < address->dimension_count; i++) { qb_index_alias_scheme *scheme = address->index_alias_schemes[i]; if(scheme) { length += sizeof(qb_index_alias_scheme); // a string pointer and an uint32 per alias length += (sizeof(const char *) + sizeof(uint32_t)) * scheme->dimension; for(j = 0; j < scheme->dimension; j++) { length += scheme->alias_lengths[j] + 1; } if(scheme->class_name) { length += scheme->class_name_length + 1; } } } } } return length; }
double comp_func( Data_Obj *dp, index_t index ) { double d; mach_prec mp; if( dp==NO_OBJ ) return(0.0); #ifdef FOOBAR #ifdef HAVE_CUDA if( ! object_is_in_ram(DEFAULT_QSP_ARG dp, "use value functions on CUDA object") ){ return(0.0); } #endif /* HAVE_CUDA */ #endif // FOOBAR if( !IS_SCALAR(dp) ){ sprintf(DEFAULT_ERROR_STRING,"comp_func: %s is not a scalar", OBJ_NAME(dp)); NWARN(DEFAULT_ERROR_STRING); return(0.0); } if( OBJ_MACH_DIM(dp,0) <= (dimension_t)index ){ sprintf(DEFAULT_ERROR_STRING, "Component index %d out of range for object %s", index,OBJ_NAME(dp)); NWARN(DEFAULT_ERROR_STRING); } mp = OBJ_MACH_PREC(dp); switch( mp ){ case PREC_SP: d = (* (((float *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_DP: d = (* (((double *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_IN: d = (* (((short *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_DI: d = (* (((int32_t *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_LI: d = (* (((int64_t *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_BY: d = (* (((char *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_UIN: d = (* (((u_short *)OBJ_DATA_PTR(dp))+index) ); break; case PREC_UDI: if( IS_BITMAP(dp) ){ FETCH_BIT } else { d = (* (((uint32_t *)OBJ_DATA_PTR(dp))+index) ); } break; case PREC_ULI: if( IS_BITMAP(dp) ){ FETCH_BIT } else {
*/ REBCNT Get_Part_Length(REBVAL *bval, REBVAL *eval) /* ** Determine the length of a /PART value. ** If /PART value is an integer just use it. ** If it is a series and it is the same series as the first, ** use the difference between the two indices. ** ** If the length ends up negative, back up the index as much ** as possible. If backed up over the head, adjust the length. ** ** Note: This one does not handle list datatypes. ** ***********************************************************************/ { REBINT len; REBCNT tail; if (IS_INTEGER(eval) || IS_DECIMAL(eval)) { len = Int32(eval); if (IS_SCALAR(bval) && VAL_TYPE(bval) != REB_PORT) Trap1(RE_INVALID_PART, bval); } else if ( ( // IF normal series and self referencing: VAL_TYPE(eval) >= REB_STRING && VAL_TYPE(eval) <= REB_BLOCK && VAL_TYPE(bval) == VAL_TYPE(eval) && VAL_SERIES(bval) == VAL_SERIES(eval) ) || ( // OR IF it is a port: IS_PORT(bval) && IS_PORT(eval) && VAL_OBJ_FRAME(bval) == VAL_OBJ_FRAME(eval) ) ) len = (REBINT)VAL_INDEX(eval) - (REBINT)VAL_INDEX(bval); else Trap1(RE_INVALID_PART, eval); /* !!!! if (IS_PORT(bval)) { PORT_STATE_OBJ *port; port = VAL_PORT(&VAL_PSP(bval)->state); if (PORT_FLAG(port) & PF_DIRECT) tail = 0x7fffffff; else tail = PORT_TAIL(VAL_PORT(&VAL_PSP(bval)->state)); } else */ tail = VAL_TAIL(bval); if (len < 0) { len = -len; if (len > (REBINT)VAL_INDEX(bval)) len = (REBINT)VAL_INDEX(bval); VAL_INDEX(bval) -= (REBCNT)len; } else if (!IS_INTEGER(eval) && (len + VAL_INDEX(bval)) > tail) len = (REBINT)(tail - VAL_INDEX(bval)); return (REBCNT)len; }
/** * @brief [tree,size] = create_ngrame_tree(texts, N) creates ngram tree from review texts * * @param texts Cell array of cell arrays, each filled with unigrams * @param N Type of grams to generate (2, 3, etc...) * @return tree Tree structure generated * @param size Size of the vocabulary */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // check inputs if(nrhs != 1 && nrhs != 2) { mexErrMsgIdAndTxt( "create_ngram_tree:invalidNumInputs", "One or two inputs required."); } else if (nlhs != 1 && nlhs != 2) { mexErrMsgIdAndTxt( "create_ngram_tree:invalidNumOutputs", "One or two outputs required."); } else if(!mxIsCell(prhs[0])) { mexErrMsgIdAndTxt( "create_ngram_tree:inputNotStruct", "Input must be a cell array."); } else if ((nrhs==2) && !IS_SCALAR(prhs[1])) { mexErrMsgIdAndTxt( "create_ngram_tree:inputNotScalar", "Second input must be a scalar"); } TreeNode * tree = 0; size_t num_observations = mxGetNumberOfElements(prhs[0]); if (num_observations == 0) { mexErrMsgIdAndTxt("create_ngram_tree:invalidInput", "There must be more than 0 observations!"); } double integral = 2.0; // default is 2 (bigrams) if (nrhs == 2) { const double gram_count_input = mxGetScalar(prhs[1]); if (std::modf(gram_count_input, &integral) != 0.0) { mexErrMsgIdAndTxt("create_ngram_tree:invalidInput", "Bigram count must be an integer!"); } } const int gram_count = static_cast<int>(integral); //mexPrintf("Running ngram tree on %i observations\n", num_observations); //mexPrintf("Building tree...\n"); //mexEvalString("drawnow;"); // force flush of IO // iterate over observations for (size_t i=0; i < num_observations; i++) { mxArray * cell = mxGetCell(prhs[0], i); if (!mxIsCell(cell)) { if (tree) { delete tree; } mexErrMsgIdAndTxt("create_ngram_tree:invalidInput", "Input must be a cell array."); } size_t num_unigrams = mxGetNumberOfElements(cell); // iterate over unigrams for this observation std::vector<std::string> unigrams_cleaned; unigrams_cleaned.reserve(num_unigrams); for (size_t n=0; n < num_unigrams; n++) { mxArray * gram_cell = mxGetCell(cell, n); if (!mxIsChar(gram_cell)) { if (tree) { delete tree; } mexErrMsgIdAndTxt( "create_ngram_tree:invalidInput", "Input cell arrays must contain strings."); } char * cstr = mxArrayToString(gram_cell); // convert ngram to cpp string std::string unigram_string = std::string(cstr); mxFree(cstr); // make lowercase std::transform(unigram_string.begin(), unigram_string.end(), unigram_string.begin(), ::tolower); // remove everything except alphanumerics + spaces and tabs unigram_string.erase(std::remove_if(unigram_string.begin(), unigram_string.end(), clean_predicate), unigram_string.end()); // trim starting and ending whitespace unigram_string = trim_whitespace(unigram_string); if (unigram_string.empty()) { continue; } //mexPrintf("extracted unigram: %s\n", unigram_string.c_str()); unigrams_cleaned.push_back(unigram_string); } // build bigrams std::vector <std::string> bigrams; build_ngrams(bigrams, unigrams_cleaned, gram_count); // append to tree for (std::vector <std::string> :: iterator it = bigrams.begin(); it != bigrams.end(); it++) { if (!tree) { tree = new TreeNode(*it); } tree->append_increment(*it, static_cast<int>(i)); } } int col=0; if (tree) { tree->assign_columns(col); // lazy - traverse tree to assign column values } //mexPrintf("Done building tree, %lu instances.\n", tree->count_observations()); // debug //std::string left = tree->leftmost_token(); //std::string right = tree->rightmost_token(); //mexPrintf("Leftmost term: %s, rightmost term: %s\n", left.c_str(), right.c_str()); // pass back tree if (tree) { plhs[0] = tree->create_mex_struct(); if (nlhs == 2) { plhs[1] = mxCreateDoubleScalar((double)tree->count_nodes()); } // cleanup delete tree; } else { // no tree was created, not enough unigrams - pass back logical false plhs[0] = mxCreateLogicalScalar(false); if (nlhs == 2) { plhs[1] = mxCreateDoubleScalar(0); } } }
static int32_t qb_validate_operands_define(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) { qb_operand *name = &operands[0], *value = &operands[1]; if(name->type != QB_OPERAND_ZVAL || Z_TYPE_P(name->constant) != IS_STRING) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "constant string"); return FALSE; } if(!(value->type == QB_OPERAND_ZVAL || (value->type == QB_OPERAND_ADDRESS && IS_IMMUTABLE(value->address) && IS_SCALAR(value->address)))) { qb_report_unexpected_intrinsic_argument_exception(cxt->line_id, cxt->intrinsic_function, 0, "constant expression"); return FALSE; } return TRUE; }