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;
}
Beispiel #3
0
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;
}
Beispiel #6
0
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;
}
Beispiel #9
0
/* & | ! */
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 */
}
Beispiel #10
0
/* & | ! */
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;
}
Beispiel #14
0
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;
}
Beispiel #21
0
/*
 * 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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
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 {
Beispiel #28
0
*/	 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;
}