Ejemplo n.º 1
0
DaoType* DaoCinValue_CheckConversion( DaoType *self, DaoType *type, DaoRoutine *ctx )
{
	DaoCinType *cintype = (DaoCinType*) self->aux;
	DaoTypeCore *core;
	DaoRoutine *rout;
	DString *buffer;

	if( cintype->target == type ){
		return type;
	}else if( DaoType_MatchTo( cintype->target, type, NULL ) >= DAO_MT_EQ ){
		return type;
	}

	buffer = DString_NewChars( "(" );
	DString_Append( buffer, type->name );
	DString_AppendChars( buffer, ")" );
	rout = DaoType_FindFunction( cintype->vatype, buffer );
	DString_Delete( buffer );
	if( rout != NULL ){
		DaoType *ttype = DaoNamespace_GetType( ctx->nameSpace, (DaoValue*) type );
		rout = DaoRoutine_MatchByType( rout, self, & ttype, 1, DVM_CALL );
		if( rout ) return type;
	}
	core = cintype->target->core;
	if( core != NULL && core->CheckConversion ){
		return core->CheckConversion( cintype->target, type, ctx );
	}
	return NULL;
}
Ejemplo n.º 2
0
DaoValue* DaoCinValue_DoConversion( DaoValue *self, DaoType *type, int copy, DaoProcess *proc )
{
	DaoCinType *cintype = self->xCinValue.cintype;
	DaoTypeCore *core;
	DaoRoutine *rout;
	DString *buffer;

	if( cintype->target == type ){
		if( copy ) return DaoValue_Convert( self->xCinValue.value, type, copy, proc );
		return self->xCinValue.value;
	}else if( DaoType_MatchTo( cintype->target, type, NULL ) >= DAO_MT_EQ ){
		if( copy ) return DaoValue_Convert( self->xCinValue.value, type, copy, proc );
		return self->xCinValue.value;
	}

	buffer = DString_NewChars( "(" );
	DString_Append( buffer, type->name );
	DString_AppendChars( buffer, ")" );
	rout = DaoType_FindFunction( cintype->vatype, buffer );
	DString_Delete( buffer );
	if( rout != NULL ){
		int rc = DaoProcess_PushCall( proc, rout, self, (DaoValue**) & type, 1 );
		if( rc == 0 ) return NULL;
	}
	return DaoValue_Convert( self->xCinValue.value, type, copy, proc );
}
Ejemplo n.º 3
0
static int DaoxDataFrame_SetFrame( DaoxDataFrame *self, DaoxDataFrame *df )
{
	DaoValue value = {0};
	DArray *destSlices = self->slices;
	DArray *fromSlices = df->slices;
	DArray *fromSlices2 = df->slices;
	daoint i, j, k, N, M, K;

	if( DaoxDataFrame_AlignFrame( self, df ) == 0 ) return DAOX_DF_WRONG_SHAP;

	if( self->original == NULL ){
		DaoxDataFrame_PrepareSlices( self );
		DaoxDataFrame_MakeFullSlice( self, self->slices );
		destSlices = self->slices;
	}else{
		self = self->original;
	}
	if( df->original == NULL ){
		fromSlices = DArray_New(D_VECTOR);
		DaoxDataFrame_MakeFullSlice( df, fromSlices );
	}else{
		df = df->original;
	}

	N = destSlices->items.pVector[0]->data.daoints[1];
	M = destSlices->items.pVector[1]->data.daoints[1];
	K = destSlices->items.pVector[2]->data.daoints[1];

	for(j=0; j<M; ++j){
		daoint jjdes = DaoSlice_GetIndex( destSlices->items.pVector[1], j );
		daoint jjsrc = DaoSlice_GetIndex( fromSlices->items.pVector[1], j );
		DaoxDataColumn *coldes = (DaoxDataColumn*) self->columns->items.pVoid[jjdes];
		DaoxDataColumn *colsrc = (DaoxDataColumn*) df->columns->items.pVoid[jjsrc];
		if( DaoType_MatchTo( colsrc->type, coldes->type, NULL ) < DAO_MT_SUB )
			return DAOX_DF_WRONG_VALUE;
		for(i=0; i<N; ++i){
			daoint iides = DaoSlice_GetIndex( destSlices->items.pVector[0], i );
			daoint iisrc = DaoSlice_GetIndex( fromSlices->items.pVector[0], i );
			for(k=0; k<K; ++k){
				daoint kkdes = DaoSlice_GetIndex( destSlices->items.pVector[2], k );
				daoint kksrc = DaoSlice_GetIndex( fromSlices->items.pVector[2], k );
				daoint idsrc = kksrc * N + iisrc;
				daoint iddes = kkdes * N + iides;
				DaoValue *val = DaoxDataColumn_GetCell( colsrc, idsrc, & value );
				DaoxDataColumn_SetCell( coldes, iddes, val );
			}
		}
	}

	if( fromSlices != fromSlices2 ) DArray_Delete( fromSlices );
	return 0;
}
Ejemplo n.º 4
0
DaoCinType* DaoInterface_GetConcrete( DaoInterface *self, DaoType *type )
{
	DNode *it;
	
	if( self->concretes == NULL ) return NULL;

	it = DMap_Find( self->concretes, type );
	if( it == NULL ){
		for(it=DMap_First(self->concretes); it; it=DMap_Next(self->concretes,it)){
			if( DaoType_MatchTo( it->key.pType, type, NULL ) >= DAO_MT_EQ ){
				return (DaoCinType*) it->value.pVoid;
			}
		}
		return NULL;
	}
	return (DaoCinType*) it->value.pVoid;
}
Ejemplo n.º 5
0
static int DaoObject_CheckSetField( DaoType *self, DaoString *name, DaoType *value, DaoRoutine *ctx )
{
	DaoClass *klass = (DaoClass*) self->aux;
	DaoType *type = ctx->routHost;
	DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL;
	DaoValue *data = DaoClass_GetData( klass, name->value, host );
	DaoRoutine *rout;
	int error = DAO_OK;

	error = 0;

	if( strcmp( name->value->chars, "self" ) ==0 ) return DAO_ERROR_FIELD_HIDDEN;
	if( data == NULL ){
		error = DAO_ERROR_FIELD_ABSENT;
	}else if( data->type == DAO_NONE ){
		error = DAO_ERROR_FIELD_HIDDEN;
	}else if( data->xBase.subtype == DAO_CLASS_CONSTANT ){
		error = DAO_ERROR_FIELD_HIDDEN; // XXX
	}else{
		/* data->xBase.subtype == DAO_CLASS_VARIABLE || DAO_OBJECT_VARIABLE */
		if( DaoType_MatchTo( value, data->xVar.dtype, NULL ) == 0 ) return DAO_ERROR_VALUE;
	}
	if( error ){
		DString *field = DString_NewChars( "." );
		DString_Append( field, name->value );
		DString_AppendChars( field, "=" );
		rout = DaoClass_FindMethod( klass, field->chars, host );
		DString_Delete( field );
		if( rout != NULL ){
			rout = DaoRoutine_MatchByType( rout, self, & value, 1, DVM_CALL );
		}else{
			DaoType *args[2];
			args[0] = dao_type_string;
			args[1] = value;
			rout = DaoClass_FindMethod( klass, ".=", host );
			if( rout == NULL ) return error;
			rout = DaoRoutine_MatchByType( rout, self, args, 2, DVM_CALL );
		}
		if( rout == NULL ) return error;
	}
	return DAO_OK;
}
Ejemplo n.º 6
0
static void STD_SubType( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoType *tp1 = DaoNamespace_GetType( proc->activeNamespace, p[0] );
	DaoType *tp2 = DaoNamespace_GetType( proc->activeNamespace, p[1] );
	DaoProcess_PutInteger( proc, DaoType_MatchTo( tp1, tp2, NULL ) );
}
Ejemplo n.º 7
0
int DaoValue_Move4( DaoValue *S, DaoValue **D, DaoType *T, DMap *defs, DaoDataCache *cache )
{
	int tm = 1;
	switch( (T->tid << 8) | S->type ){
	case (DAO_INTEGER << 8) | DAO_INTEGER :
	case (DAO_INTEGER << 8) | DAO_FLOAT   :
	case (DAO_INTEGER << 8) | DAO_DOUBLE  :
	case (DAO_FLOAT   << 8) | DAO_INTEGER :
	case (DAO_FLOAT   << 8) | DAO_FLOAT   :
	case (DAO_FLOAT   << 8) | DAO_DOUBLE  :
	case (DAO_DOUBLE  << 8) | DAO_INTEGER :
	case (DAO_DOUBLE  << 8) | DAO_FLOAT   :
	case (DAO_DOUBLE  << 8) | DAO_DOUBLE  :
	case (DAO_COMPLEX << 8) | DAO_COMPLEX :
	case (DAO_LONG    << 8) | DAO_LONG    :
	case (DAO_STRING  << 8) | DAO_STRING  :
		S = DaoValue_SimpleCopyWithTypeX( S, T, cache );
		GC_ShiftRC( S, *D );
		*D = S;
		return 1;
	}
	if( !(S->xTuple.trait & DAO_VALUE_CONST) ){
		DaoType *ST = NULL;
		switch( (S->type << 8) | T->tid ){
		case (DAO_TUPLE<<8)|DAO_TUPLE : ST = S->xTuple.unitype; break;
		case (DAO_ARRAY<<8)|DAO_ARRAY : ST = dao_array_types[ S->xArray.etype ]; break;
		case (DAO_LIST <<8)|DAO_LIST  : ST = S->xList.unitype; break;
		case (DAO_MAP  <<8)|DAO_MAP   : ST = S->xMap.unitype; break;
		case (DAO_CDATA<<8)|DAO_CDATA : ST = S->xCdata.ctype; break;
		case (DAO_CSTRUCT<<8)|DAO_CSTRUCT : ST = S->xCstruct.ctype; break;
		case (DAO_OBJECT<<8)|DAO_OBJECT : ST = S->xObject.defClass->objType; break;
		}
		if( ST == T ){
			DaoValue *D2 = *D;
			GC_ShiftRC( S, D2 );
			*D = S;
			return 1;
		}
	}
	if( (T->tid == DAO_OBJECT || T->tid == DAO_CDATA || T->tid == DAO_CSTRUCT) && S->type == DAO_OBJECT ){
		if( S->xObject.defClass != & T->aux->xClass ){
			S = DaoObject_CastToBase( S->xObject.rootObject, T );
			tm = (S != NULL);
		}
	}else if( (T->tid == DAO_CLASS || T->tid == DAO_CTYPE) && S->type == DAO_CLASS ){
		if( S->xClass.clsType != T && T->aux != NULL ){ /* T->aux == NULL for "class"; */
			S = DaoClass_CastToBase( (DaoClass*)S, T );
			tm = (S != NULL);
		}
	}else if( T->tid == DAO_CTYPE && S->type == DAO_CTYPE ){
		if( S->xCtype.ctype != T ){
			S = DaoType_CastToParent( S, T );
			tm = (S != NULL);
		}
	}else if( T->tid == DAO_ROUTINE && T->overloads == 0 && S->type == DAO_ROUTINE && S->xRoutine.overloads ){
		DArray *routines = S->xRoutine.overloads->routines;
		int i, k, n;
		/*
		// Do not use DaoRoutine_ResolveByType( S, ... )
		// "S" should match to "T", not the other way around!
		*/
		tm = 0;
		for(i=0,n=routines->size; i<n; i++){
			DaoRoutine *rout = routines->items.pRoutine[i];
			k = rout->routType == T ? DAO_MT_EQ : DaoType_MatchTo( rout->routType, T, defs );
			if( k > tm ) tm = k;
			if( rout->routType == T ){
				S = (DaoValue*) rout;
				break;
			}
		}
	}else{
		tm = DaoType_MatchValue( T, S, defs );
	}
#if 0
	if( tm ==0 ){
		printf( "T = %p; S = %p, type = %i %i\n", T, S, S->type, DAO_ROUTINE );
		printf( "T: %s %i %i\n", T->name->mbs, T->tid, tm );
		if( S->type == DAO_LIST ) printf( "%s\n", S->xList.unitype->name->mbs );
		if( S->type == DAO_TUPLE ) printf( "%p\n", S->xTuple.unitype );
	}
	printf( "S->type = %p %s %i\n", S, T->name->mbs, tm );
#endif
	if( tm == 0 ) return 0;
	/* composite known types must match exactly. example,
	 * where it will not work if composite types are allowed to match loosely.
	 * d : list<list<int>> = {};
	 * e : list<float> = { 1.0 };
	 * d.append( e );
	 *
	 * but if d is of type list<list<any>>,
	 * the matching do not necessary to be exact.
	 */
	S = DaoValue_SimpleCopyWithTypeX( S, T, cache );
	GC_ShiftRC( S, *D );
	*D = S;
	if( S->type == DAO_TUPLE && S->xTuple.unitype != T && tm >= DAO_MT_SIM ){
		return DaoValue_TryCastTuple( S, D, T );
	}else if( T && T->tid == S->type && !(T->attrib & DAO_TYPE_SPEC) ){
		DaoValue_SetType( S, T );
	}
	return 1;
}
Ejemplo n.º 8
0
DaoClass* DaoClass_Instantiate( DaoClass *self, DArray *types )
{
	DaoClass *klass = NULL;
	DaoType *type;
	DString *name;
	DNode *node;
	DMap *deftypes;
	daoint lt = DString_FindChar( self->className, '<', 0 );
	daoint i, holders = 0;
	if( self->typeHolders == NULL || self->typeHolders->size ==0 ) return self;
	while( types->size < self->typeHolders->size ){
		type = self->typeDefaults->items.pType[ types->size ];
		if( type == NULL ) type = self->typeHolders->items.pType[ types->size ];
		DArray_Append( types, type );
	}
	name = DString_New(1);
	DString_Append( name, self->className );
	if( lt != MAXSIZE ) DString_Erase( name, lt, MAXSIZE );
	DString_AppendChar( name, '<' );
	for(i=0; i<types->size; i++){
		type = types->items.pType[i];
		holders += type->tid == DAO_THT;
		if( i ) DString_AppendChar( name, ',' );
		DString_Append( name, type->name );
	}
	DString_AppendChar( name, '>' );
	while( self->templateClass ) self = self->templateClass;
	node = DMap_Find( self->instanceClasses, name );
	if( node ){
		klass = node->value.pClass;
	}else{
		deftypes = DMap_New(0,0);
		klass = DaoClass_New();
		if( holders ) klass->templateClass = self;
		DMap_Insert( self->instanceClasses, name, klass );
		DaoClass_AddReference( self, klass ); /* No need for cleanup of klass; */
		DaoClass_SetName( klass, name, self->classRoutine->nameSpace );
		for(i=0; i<types->size; i++){
			type = types->items.pType[i];
			if( DaoType_MatchTo( type, self->typeHolders->items.pType[i], deftypes ) ==0 ){
				DString_Delete( name );
				return NULL;
			}
			MAP_Insert( deftypes, self->typeHolders->items.pVoid[i], type );
		}
		klass->objType->nested = DArray_New(D_VALUE);
		DArray_Assign( klass->objType->nested, types );
		if( DaoClass_CopyField( klass, self, deftypes ) == 0 ){
			DString_Delete( name );
			return NULL;
		}
		DaoClass_DeriveClassData( klass );
		DaoClass_DeriveObjectData( klass );
		DaoClass_ResetAttributes( klass );
		DMap_Delete( deftypes );
		if( holders ){
			klass->typeHolders = DArray_New(0);
			klass->typeDefaults = DArray_New(0);
			klass->instanceClasses = DMap_New(D_STRING,0);
			DMap_Insert( klass->instanceClasses, klass->className, klass );
			for(i=0; i<types->size; i++){
				DArray_Append( klass->typeHolders, types->items.pType[i] );
				DArray_Append( klass->typeDefaults, NULL );
			}
			for(i=0; i<klass->typeHolders->size; i++){
				DaoClass_AddReference( klass, klass->typeHolders->items.pType[i] );
				DaoClass_AddReference( klass, klass->typeDefaults->items.pType[i] );
			}
		}
	}
	DString_Delete( name );
	return klass;
}
Ejemplo n.º 9
0
static int DaoType_Compare( DaoType *left, DaoType *right )
{
	if( DaoType_MatchTo( left, right, NULL ) >= DAO_MT_EQ ) return 0;
	return number_compare( (size_t)left, (size_t)right );
}
Ejemplo n.º 10
0
DaoValue* DaoValue_Convert( DaoValue *self, DaoType *type, int copy, DaoProcess *proc )
{
	DaoTypeCore *core = DaoValue_GetTypeCore( self );
	DaoValue *value = self;
	DaoType *at;

	if( type->tid & DAO_ANY ){
		if( copy == 0 ) return value;
		at = DaoValue_GetType( value, proc->vmSpace );
		at = DaoType_GetBaseType( at );
		if( at == NULL ) return NULL;
		if( DaoType_IsImmutable( at ) ) return value;
		if( value->type >= DAO_ARRAY && value->type <= DAO_TUPLE ){
			at = DaoNamespace_MakeInvarSliceType( proc->activeNamespace, at );
			return DaoValue_CopyContainer( value, at );
		}else if( core != NULL && core->Copy != NULL ){
			return core->Copy( value, NULL );
		}
		return NULL;
	}else if( type->tid == DAO_CINVALUE ){
		DaoCinType *cintype = (DaoCinType*) type->aux;

		if( value->type == DAO_CINVALUE && value->xCinValue.cintype == cintype ) return value;
		if( value->type == DAO_CINVALUE && DaoType_MatchValue( type, value, NULL ) ) return value;

		at = DaoNamespace_GetType( proc->activeNamespace, value );
		if( cintype->target == at || DaoType_MatchTo( cintype->target, at, NULL ) >= DAO_MT_CIV ){
			proc->cinvalue.cintype = cintype;
			proc->cinvalue.value = value;
			return (DaoValue*) & proc->cinvalue;
		}
		return NULL;
	}else if( type->tid == DAO_INTERFACE ){
		DaoInterface *inter = (DaoInterface*) type->aux;
		DaoRoutine *incompatible;

		if( type->aux == NULL ){ /* type "interface": */
			if( value->type != DAO_INTERFACE ) return NULL;
			return value;
		}
		if( value->type == DAO_CINVALUE && DaoType_MatchValue( type, value, NULL ) ) return value;

		at = DaoNamespace_GetType( proc->activeNamespace, value );
		if( inter->concretes ){
			DaoCinType *cintype = DaoInterface_GetConcrete( inter, at );
			if( cintype ){
				proc->cinvalue.cintype = cintype;
				proc->cinvalue.value = value;
				return (DaoValue*) & proc->cinvalue;
			}
		}
		switch( value->type ){
		case DAO_OBJECT  :
			value = (DaoValue*) value->xObject.rootObject;
			at = value->xObject.defClass->objType;
			break;
		case DAO_CSTRUCT :
		case DAO_CDATA :
			if( value->xCstruct.object ){
				value = (DaoValue*) value->xCstruct.object->rootObject;
				at = value->xObject.defClass->objType;
			}
			break;
		}
		/* Automatic binding when casted to an interface: */
		incompatible = DaoInterface_BindTo( inter, at, NULL );
		if( incompatible != NULL ){
			DString *buffer = DString_New();
			DString_AppendChars( buffer, "Interface method " );
			DString_Append( buffer, inter->abtype->name );
			DString_AppendChars( buffer, "::" );
			DString_Append( buffer, incompatible->routName );
			DString_AppendChars( buffer, "() is not available in the source type;" );
			DaoProcess_DeferException( proc, "Error::Type", buffer->chars );
			DString_Delete( buffer );
			return NULL;
		}
		return value;
	}else if( type->tid == DAO_VARIANT ){
		DaoType *best = NULL;
		int i, n, max = DAO_MT_NOT;
		for(i=0,n=type->args->size; i<n; i++){
			DaoType *itype = type->args->items.pType[i];
			int mt = DaoType_MatchValue( itype, self, NULL );
			if( mt > max ){
				best = itype;
				max = mt;
			}
		}
		if( best == NULL ) return NULL;
		return DaoValue_Convert( self, best, copy, proc );
	}

	if( core == NULL || core->DoConversion == NULL ) return NULL;
	value = core->DoConversion( self, type, copy, proc );

	if( value == NULL || value->type <= DAO_ENUM || copy == 0 ) return value;

	if( value == self /*|| DaoValue_ChildOf( value, self ) || DaoValue_ChildOf( self, value )*/ ){
		// No way to determine inheritance relationship between wrapped C++ objects;
		if( value->type >= DAO_ARRAY && value->type <= DAO_TUPLE ){
			DaoType *type = DaoValue_GetType( value, proc->vmSpace );
			if( type == NULL ) return NULL;
			type = DaoNamespace_MakeInvarSliceType( proc->activeNamespace, type );
			return DaoValue_CopyContainer( value, type );
		}
		if( core == NULL || core->Copy == NULL ) return NULL;

		value = core->Copy( value, NULL ); /* Copy invariable value; */
		if( value == NULL ) return NULL;

		DaoProcess_CacheValue( proc, value );
	}
	return value;
}
Ejemplo n.º 11
0
int DaoValue_Move5( DaoValue *S, DaoValue **D, DaoType *T, DaoType *C, DMap *defs )
{
	DaoValue *D2 = *D;
	if( S == D2 && (S == NULL || DaoValue_FastMatchTo( S, T )) ) return 1;
	if( S == NULL ){
		GC_DecRC( *D );
		*D = NULL;
		return 0;
	}
	if( T == NULL ){
		DaoValue_CopyX( S, D, C );
		return 1;
	}
	if( T->valtype ){
		if( DaoValue_Compare( S, T->value ) !=0 ) return 0;
		DaoValue_CopyX( S, D, C );
		return 1;
	}
	switch( T->tid ){
	case DAO_UDT :
		DaoValue_CopyX( S, D, C );
		return 1;
	case DAO_THT :
		if( T->aux ) return DaoValue_Move5( S, D, (DaoType*) T->aux, C, defs );
		DaoValue_CopyX( S, D, C );
		return 1;
	case DAO_ANY :
		DaoValue_CopyX( S, D, C );
		DaoValue_SetType( *D, T );
		return 1;
	case DAO_VARIANT :
		return DaoValue_MoveVariant( S, D, T, C );
	default : break;
	}
	if( S->type >= DAO_OBJECT || !(S->xBase.trait & DAO_VALUE_CONST) || T->invar ){
		if( DaoValue_FastMatchTo( S, T ) ){
			if( S->type == DAO_CDATA && S->xCdata.data == NULL ){
				if( ! DaoType_IsNullable( T ) ) return 0;
			}
			if( S->type == DAO_CSTRUCT || S->type == DAO_CDATA ){
				DaoValue_MoveCstruct( S, D, C != NULL && C->invar != 0 );
			}else if( S->type == DAO_CINVALUE ){
				DaoValue_MoveCinValue( (DaoCinValue*) S, D );
			}else{
				GC_Assign( D, S );
			}
			return 1;
		}
	}
	if( S->type == DAO_CINVALUE ){
		if( S->xCinValue.cintype->target == T ){
			S = S->xCinValue.value;
		}else if( DaoType_MatchTo( S->xCinValue.cintype->target, T, NULL ) >= DAO_MT_EQ ){
			S = S->xCinValue.value;
		}
	}
	if( D2 && D2->xBase.refCount > 1 ){
		GC_DecRC( D2 );
		*D = D2 = NULL;
	}
#if 0
	if( D2 && S->type == D2->type && S->type == T->tid && S->type <= DAO_ENUM ){
		switch( S->type ){
		case DAO_ENUM    :
			DaoEnum_SetType( & D2->xEnum, T->subtid == DAO_ENUM_ANY ? S->xEnum.etype : T );
			return DaoEnum_SetValue( & D2->xEnum, & S->xEnum );
		case DAO_BOOLEAN :
		case DAO_INTEGER : D2->xInteger.value = S->xInteger.value; break;
		case DAO_FLOAT   : D2->xFloat.value = S->xFloat.value; break;
		case DAO_COMPLEX : D2->xComplex.value = S->xComplex.value; break;
		case DAO_STRING  : DString_Assign( D2->xString.value, S->xString.value ); break;
		}
		return 1;
	}
#endif
	if( D2 == NULL || D2->type != T->tid ) return DaoValue_Move4( S, D, T, C, defs );

	switch( (S->type << 8) | T->tid ){
	case (DAO_STRING<<8)|DAO_STRING :
		DString_Assign( D2->xString.value, S->xString.value );
		break;
	case (DAO_ENUM<<8)|DAO_ENUM :
		DaoEnum_SetType( & D2->xEnum, T->subtid == DAO_ENUM_ANY ? S->xEnum.etype : T );
		DaoEnum_SetValue( & D2->xEnum, & S->xEnum );
		break;
	case (DAO_CINVALUE<<8)|DAO_CINVALUE :
		if( S->xCinValue.cintype->vatype != T ) return DaoValue_Move4( S, D, T, C, defs );
		DaoValue_MoveCinValue( (DaoCinValue*) S, D );
		break;
	case (DAO_BOOLEAN<<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xBoolean.value; break;
	case (DAO_BOOLEAN<<8)|DAO_INTEGER : D2->xInteger.value = S->xBoolean.value; break;
	case (DAO_BOOLEAN<<8)|DAO_FLOAT   : D2->xFloat.value   = S->xBoolean.value; break;
	case (DAO_INTEGER<<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xInteger.value; break;
	case (DAO_INTEGER<<8)|DAO_INTEGER : D2->xInteger.value = S->xInteger.value; break;
	case (DAO_INTEGER<<8)|DAO_FLOAT   : D2->xFloat.value   = S->xInteger.value; break;
	case (DAO_FLOAT  <<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xFloat.value; break;
	case (DAO_FLOAT  <<8)|DAO_INTEGER : D2->xInteger.value = S->xFloat.value; break;
	case (DAO_FLOAT  <<8)|DAO_FLOAT   : D2->xFloat.value   = S->xFloat.value; break;
	case (DAO_COMPLEX<<8)|DAO_COMPLEX : D2->xComplex.value = S->xComplex.value; break;
	default : return DaoValue_Move4( S, D, T, C, defs );
	}
	return 1;
}
Ejemplo n.º 12
0
int DaoValue_Move4( DaoValue *S, DaoValue **D, DaoType *T, DaoType *C, DMap *defs )
{
	DaoCinType *cintype;
	int tm = 1;
	switch( (T->tid << 8) | S->type ){
	case (DAO_BOOLEAN << 8) | DAO_BOOLEAN :
	case (DAO_BOOLEAN << 8) | DAO_INTEGER :
	case (DAO_BOOLEAN << 8) | DAO_FLOAT   :
	case (DAO_INTEGER << 8) | DAO_BOOLEAN :
	case (DAO_INTEGER << 8) | DAO_INTEGER :
	case (DAO_INTEGER << 8) | DAO_FLOAT   :
	case (DAO_FLOAT   << 8) | DAO_BOOLEAN :
	case (DAO_FLOAT   << 8) | DAO_INTEGER :
	case (DAO_FLOAT   << 8) | DAO_FLOAT   :
	case (DAO_COMPLEX << 8) | DAO_COMPLEX :
	case (DAO_STRING  << 8) | DAO_STRING  :
	case (DAO_CINVALUE<< 8) | DAO_CINVALUE  :
		S = DaoValue_SimpleCopyWithTypeX( S, T, C );
		GC_Assign( D, S );
		return 1;
	}
	switch( S->type ){
	case DAO_ENUM : if( S->xEnum.subtype == DAO_ENUM_SYM && T->realnum ) return 0; break;
	case DAO_OBJECT : if( S->xObject.isNull ) return 0; break;
	case DAO_CDATA  : if( S->xCdata.data == NULL && ! DaoType_IsNullable(T) ) return 0; break;
	}
	if( !(S->xBase.trait & DAO_VALUE_CONST) ){
		DaoVmSpace *vms;
		DaoType *ST = NULL;
		switch( (S->type << 8) | T->tid ){
		case (DAO_ARRAY<<8)|DAO_ARRAY :
			vms = DaoType_GetVmSpace( T );
			ST = vms->typeArrays[ S->xArray.etype ]; break;
		case (DAO_TUPLE<<8)|DAO_TUPLE : ST = S->xTuple.ctype; break;
		case (DAO_LIST <<8)|DAO_LIST  : ST = S->xList.ctype; break;
		case (DAO_MAP  <<8)|DAO_MAP   : ST = S->xMap.ctype; break;
		case (DAO_CDATA<<8)|DAO_CDATA : ST = S->xCdata.ctype; break;
		case (DAO_CSTRUCT<<8)|DAO_CSTRUCT : ST = S->xCstruct.ctype; break;
		case (DAO_OBJECT<<8)|DAO_OBJECT : ST = S->xObject.defClass->objType; break;
		}
		if( ST == T ){
			if( ST->tid == DAO_CSTRUCT || ST->tid == DAO_CDATA ){
				DaoValue_MoveCstruct( S, D, C != NULL && C->invar != 0 );
			}else{
				GC_Assign( D, S );
			}
			return 1;
		}
	}
	if( (T->tid == DAO_OBJECT || T->tid == DAO_CSTRUCT || T->tid == DAO_CDATA) && S->type == DAO_OBJECT ){
		if( S->xObject.defClass != & T->aux->xClass ){
			S = DaoObject_CastToBase( S->xObject.rootObject, T );
			if( S != NULL && S->type == DAO_CDATA && S->xCdata.data == NULL ){
				if( ! DaoType_IsNullable( T ) ) return 0;
			}
			tm = (S != NULL);
		}
	}else if( (T->tid == DAO_CLASS || T->tid == DAO_CTYPE) && S->type == DAO_CLASS ){
		if( S->xClass.clsType != T && T->aux != NULL ){ /* T->aux == NULL for "class"; */
			S = DaoClass_CastToBase( (DaoClass*)S, T );
			tm = (S != NULL);
		}
	}else if( T->tid == DAO_CTYPE && S->type == DAO_CTYPE ){
		if( S->xCtype.classType != T ){
			S = DaoType_CastToParent( S, T );
			tm = (S != NULL);
		}
	}else if( T->tid == DAO_ROUTINE && T->subtid != DAO_ROUTINES && S->type == DAO_ROUTINE && S->xRoutine.overloads ){
		DList *routines = S->xRoutine.overloads->routines;
		int i, k, n;
		/*
		// Do not use DaoRoutine_ResolveByType( S, ... )
		// "S" should match to "T", not the other way around!
		*/
		tm = 0;
		for(i=0,n=routines->size; i<n; i++){
			DaoRoutine *rout = routines->items.pRoutine[i];
			k = rout->routType == T ? DAO_MT_EQ : DaoType_MatchTo( rout->routType, T, defs );
			if( k > tm ) tm = k;
			if( rout->routType == T ){
				S = (DaoValue*) rout;
				break;
			}
		}
	}else{
		tm = DaoType_MatchValue( T, S, defs );
	}
#if 0
	if( tm ==0 ){
		printf( "T = %p; S = %p, type = %i %i\n", T, S, S->type, DAO_ROUTINE );
		printf( "T: %s %i %i\n", T->name->chars, T->tid, tm );
		if( S->type == DAO_LIST ) printf( "%s\n", S->xList.ctype->name->chars );
		if( S->type == DAO_TUPLE ) printf( "%p\n", S->xTuple.ctype );
	}
	printf( "S->type = %p %s %i\n", S, T->name->chars, tm );
#endif
	if( tm == 0 ) return 0;


	/*
	// Composite types must match exactly. Example,
	// where it will not work if composite types are allowed to match loosely.
	// d : list<list<int>> = {};
	// e : list<float> = { 1.0 };
	// d.append( e );
	//
	// But if d is of type list<list<any>>,
	// the matching do not necessary to be exact.
	*/
	cintype = NULL;
	if( T->tid == DAO_CINVALUE ){
		if( DaoType_MatchValue( T->aux->xCinType.target, S, NULL ) >= DAO_MT_CIV ){
			cintype = (DaoCinType*) T->aux;
		}
	}else if( T->tid == DAO_INTERFACE && T->aux->xInterface.concretes ){
		DaoInterface *inter = (DaoInterface*) T->aux;
		DaoType *st = DaoValue_GetType( S, inter->nameSpace->vmSpace );
		DNode *it; 
		cintype = DaoInterface_GetConcrete( inter, st );
		if( cintype == NULL ){
			for(it=DMap_First(inter->concretes); it; it=DMap_Next(inter->concretes,it)){
				if( DaoType_MatchValue( it->key.pType, S, NULL ) >= DAO_MT_CIV ){
					cintype = (DaoCinType*) it->value.pVoid;
					break;
				}
			}
		}
	}
	if( cintype ){
		S = (DaoValue*) DaoCinValue_New( cintype, S );
	}else if( S->type == DAO_CSTRUCT || S->type == DAO_CDATA ){
		DaoValue_MoveCstruct( S, D, C != NULL && C->invar != 0 );
		return 1;
	}else{
		S = DaoValue_SimpleCopyWithTypeX( S, T, C );
	}
	GC_Assign( D, S );
	if( S->type == DAO_TUPLE && S->xTuple.ctype != T && tm == DAO_MT_SIM ){
		return DaoValue_TryCastTuple( S, D, T );
	}else if( T && T->tid == S->type && !(T->attrib & DAO_TYPE_SPEC) ){
		DaoValue_SetType( S, T );
	}
	return 1;
}