Beispiel #1
0
obj applyV(double (*func)(double), obj v, obj name){
	if(type(v)==tDouble)	return Double(func(udbl(v)));
	if(type(v)==INT)	return Double(func(uint(v)));
	if(type(v) == tDblArray) {
		DblArray* a;
		a = &(udar(v));
		obj r = dblArray(a->size);
//		obj r = new dblarr(a->size);
		for(int i=0; i<(a->size); i++) udar(r).v[i] = func(a->v[i]);
		return r;
	}
	if(isVec(type(v))){
		int len = size(v);
		obj r = aArray(len);
		for(int i=0; i<len; i++){
			obj lt = ind(v,i);
			uar(r).v[i] = applyV(func, lt, name); 
			release(lt);
		}
		return r;
	}
	if(type(v)==LIST){
		list l = nil;
		for(list l1 = ul(v); l1; l1=rest(l1)){
			l = cons(applyV(func,first(l1), name), l);
		}
		return List2v(reverse(l));
	}
	obj rr=nil;
	if(name){
		rr = udef_op0(name, v);
	}
	if(!rr) error("func: argument must be a scalar or an array.");
	return rr;
}
Beispiel #2
0
obj applyCS(obj (*func)(obj, obj), obj v1, obj v2){
	assert(!isVec(type(v2)));
	if(isVec(type(v1))){
		int len=size(v1);
		obj rr = aArray(len);
		for(int i=0; i<len; i++){
			obj lt=ind(v1,i);
			uar(rr).v[i] = call_fn(func, lt, v2); 
			release(lt);
		}
		return rr;
	}
	if(type(v1)==LIST){
		list l=phi();
		for(list l1=ul(v1); l1; l1=rest(l1)){
			l = cons(call_fn(func, first(l1), v2), l);
		}
		return List2v(reverse(l));
	}
	assert(0);
	return nil;
}
Beispiel #3
0
bool Inst::CastTo(CodeContext& context, RValue& value, SType* type, bool upcast)
{
	auto valueType = value.stype();

	if (type == valueType) {
		// non-assignment and non-comparison operations with enum types
		// must result in an int type to keep enum variables within range.
		if (upcast && valueType->isEnum())
			value.castToSubtype();
		return false;
	} else if (type->isComplex() || valueType->isComplex()) {
		context.addError("can not cast complex types");
		return true;
	} else if (type->isPointer()) {
		if (value.isNullPtr()) {
			// NOTE: discard current null value and create
			// a new one using the right type
			value = RValue::getNullPtr(context, type);
			return false;
		} else if (type->subType()->isVoid()) {
			value = RValue(new BitCastInst(value, *type, "", context), type);
			return false;
		}
		context.addError("can't cast value to pointer type");
		return true;
	} else if (type->isVec()) {
		// unwrap enum type
		if (valueType->isEnum())
			valueType = value.castToSubtype();

		if (valueType->isNumeric()) {
			CastTo(context, value, type->subType(), upcast);

			auto i32 = SType::getInt(context, 32);
			auto mask = RValue::getZero(context, SType::getVec(context, i32, type->size()));
			auto udef = UndefValue::get(*SType::getVec(context, type->subType(), 1));
			auto instEle = InsertElementInst::Create(udef, value, RValue::getZero(context, i32), "", context);
			auto retVal = new ShuffleVectorInst(instEle, udef, mask, "", context);

			value = RValue(retVal, type);
			return false;
		} else if (valueType->isPointer()) {
			context.addError("can not cast pointer to vec type");
			return true;
		} else if (type->size() != valueType->size()) {
			context.addError("can not cast vec types of different sizes");
			return true;
		} else if (type->subType()->isBool()) {
			// cast to bool is value != 0
			auto pred = getPredicate(ParserBase::TT_NEQ, valueType, context);
			auto op = valueType->subType()->isFloating()? Instruction::FCmp : Instruction::ICmp;
			auto val = CmpInst::Create(op, pred, value, RValue::getZero(context, valueType), "", context);
			value = RValue(val, type);
			return false;
		} else {
			auto op = getCastOp(valueType->subType(), type->subType());
			auto val = CastInst::Create(op, value, *type, "", context);
			value = RValue(val, type);
			return false;
		}
	} else if (type->isEnum()) {
		// casting to enum would violate value constraints
		context.addError("can't cast to enum type");
		return true;
	} else if (type->isBool()) {
		if (valueType->isVec()) {
			context.addError("can not cast vec type to bool");
			return true;
		} else if (valueType->isEnum()) {
			valueType = value.castToSubtype();
		}

		// cast to bool is value != 0
		auto pred = getPredicate(ParserBase::TT_NEQ, valueType, context);
		auto op = valueType->isFloating()? Instruction::FCmp : Instruction::ICmp;
		auto val = CmpInst::Create(op, pred, value, RValue::getZero(context, valueType), "", context);
		value = RValue(val, type);
		return false;
	}

	if (valueType->isPointer()) {
		context.addError("can't cast pointer to numeric type");
		return true;
	}

	// unwrap enum type
	if (valueType->isEnum())
		valueType = value.castToSubtype();

	auto op = getCastOp(valueType, type);
	auto val = op != Instruction::AddrSpaceCast? CastInst::Create(op, value, *type, "", context) : value;
	value = RValue(val, type);
	return false;
}
Beispiel #4
0
obj applyCC( obj (*func)(obj, obj), obj v1, obj v2){
	if(type(v1)==LIST && type(v2)==LIST) {
		list l1=ul(v1), l2=ul(v2);
		list l=nil;
		for(; l1 && l2; l1=rest(l1), l2=rest(l2)){
			l= cons(call_fn(func, first(l1), first(l2)), l); 
		}
		if(l1 || l2) error("unmatched num. of elems. in the lists");
		return List2v(reverse(l));
	}
	obj lt,rt;
	if(type(v1)==tDblArray && type(v2)==tDblArray){
		int len = udar(v1).size;
		if(len != udar(v2).size) error("num mismatch");
		obj rr = dblArray(len);
//		obj rr = new dblarr(len);
		double* v = udar(rr).v;
		for(int i=0; i<len; i++){
			lt = Double(udar(v1).v[i]);//íxÇ¢
			rt = Double(udar(v2).v[i]);
			obj rx = call_fnr(func, lt,rt);
		//	release(lt);
		//	release(rt);
			if(type(rx)!=tDouble) error("array: type mismatch");//kore mondai
			v[i] = udbl(rx);
			release(rx);
		}
		return rr;
	}
	if(isVec(type(v1)) && isVec(type(v2))){
		int len=size(v1);
		if(len!=size(v2)) error("num mismatch");
		obj rr = aArray(len);
		for(int i=0; i<len; i++){
			lt = ind(v1,i);
			rt = ind(v2,i);
			uar(rr).v[i] = call_fnr(func, lt, rt); 
		//	release(lt);
		//	release(rt);
		}
		return rr;
	}
	if( type(v1)==LIST && isVec(type(v2))){
		list l=nil, l1=ul(v1);
		int len=size(v2);
		for(int i=0; i<len; i++,l1=rest(l1)){
			if(! l1) error("num mismatch");
			rt = ind(v2,i);
			l = cons(call_fn(func, first(l1), rt), l);
			release(rt);
		}
		return List2v(reverse(l));
	}
	if( isVec(type(v1)) && type(v2)==LIST){
		list l=nil, l2=ul(v2);
		int len=size(v1);
		for(int i=0; i<len; i++,l2=rest(l2)){
			if(! l2) error("num mismatch");
			lt=ind(v1,i);
			l=cons(call_fn(func, lt, first(l2)), l);
			release(lt);
		}
		return List2v(reverse(l));
	}
	error("operation not defined.");
	return nil;
}