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; }
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; }
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; }
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; }