예제 #1
0
파일: daoClass.c 프로젝트: hooloong/dao
void DaoValue_Update( DaoValue **self, DaoNamespace *ns, DMap *deftypes )
{
	DaoValue *value = *self;
	DaoType *tp, *tp2;

	if( value == NULL || value->type < DAO_ENUM ) return;
	tp = DaoNamespace_GetType( ns, value );
	/* DaoType_DefineTypes() will make proper specialization of template-like type: */
	tp2 = DaoType_DefineTypes( tp, ns, deftypes );
	if( tp == tp2 ) return;
	if( tp2->tid == DAO_OBJECT && value->type == DAO_OBJECT && value->xObject.isDefault ){
		/* "self" is supposed to be a constant, so it has to be a default instance: */
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized Dao class; */
		*self = tp2->value;
		return;
	}else if( tp2->tid == DAO_CLASS && value->type == DAO_CLASS ){
		GC_ShiftRC( tp2->aux, value ); /* specialized Dao class; */
		*self = tp2->aux;
		return;
	}else if( tp2->tid == DAO_CTYPE && value->type == DAO_CTYPE ){
		GC_ShiftRC( tp2->aux, value ); /* specialized C type; */
		*self = tp2->aux;
		return;
	}else if( tp2->tid == DAO_CDATA && value->type == DAO_CDATA ){
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized C type; */
		*self = tp2->value;
		return;
	}else if( tp2->tid == DAO_CSTRUCT && value->type == DAO_CSTRUCT ){
		GC_ShiftRC( tp2->value, value ); /* default instance of specialized C type; */
		*self = tp2->value;
		return;
	}
	DaoValue_Move( value, self, tp2 );
}
예제 #2
0
파일: daoInterface.c 프로젝트: daokoder/dao
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;
}
예제 #3
0
파일: daoStdlib.c 프로젝트: carriercomm/dao
/* modules/debugger */
DAO_DLL void Dao_AboutVar( DaoProcess *proc, DaoType *type, DaoValue *var, DString *str )
{
	DaoType *abtp = DaoNamespace_GetType( proc->activeNamespace, var );
	char buf[50];
	if( abtp ){
		if( var->type == DAO_ROUTINE ){
			DString_Append( str, var->xRoutine.routName );
			DString_AppendChars( str, "{" );
			DString_Append( str, abtp->name );
			DString_AppendChars( str, "}" );
		}else{
			DString_Append( str, abtp->name );
		}
		sprintf( buf, "[%p]", var );
		DString_AppendChars( str, buf );
		if( var->type == DAO_CDATA ){
			sprintf( buf, "(%p)", var->xCdata.data );
			DString_AppendChars( str, buf );
		}
	}else{
		DString_AppendChars( str, "none[0x0]" );
	}
	if( type ){
		DString_AppendChars( str, ":" );
		DString_Append( str, type->name );
	}
}
예제 #4
0
static int DaoCdata_Serialize( DaoCdata *self, DString *serial, DaoNamespace *ns, DaoProcess *proc, DString *buf, DMap *omap )
{
	DaoType *type;
	DaoRoutine *meth = DaoType_FindFunctionMBS( self->ctype, "serialize" );
	if( meth == NULL ) return 0;
	if( DaoProcess_Call( proc, meth, (DaoValue*)self, NULL, 0 ) ) return 0;
	type = DaoNamespace_GetType( ns, proc->stackValues[0] );
	DaoValue_Serialize2( proc->stackValues[0], serial, ns, proc, type, buf, omap );
	return 1;
}
예제 #5
0
static int DaoObject_Serialize( DaoObject *self, DString *serial, DaoNamespace *ns, DaoProcess *proc, DString *buf, DMap *omap )
{
	DaoType *type;
	DaoValue *value = NULL;
	DaoValue *selfpar = (DaoValue*) self;
	DString name = DString_WrapMBS( "serialize" );
	int errcode = DaoObject_GetData( self, & name, & value, NULL );
	if( errcode || value == NULL || value->type != DAO_ROUTINE ) return 0;
	if( DaoProcess_Call( proc, (DaoRoutine*)value, selfpar, NULL, 0 ) ) return 0;
	type = DaoNamespace_GetType( ns, proc->stackValues[0] );
	DaoValue_Serialize2( proc->stackValues[0], serial, ns, proc, type, buf, omap );
	return 1;
}
예제 #6
0
int DaoValue_Serialize( DaoValue *self, DString *serial, DaoNamespace *ns, DaoProcess *proc )
{
	DaoType *type = DaoNamespace_GetType( ns, self );
	DString *buf = DString_New(1);
	DMap *omap = DMap_New(0,0);
	int rc;
	DString_Clear( serial );
	DString_ToMBS( serial );
	rc = DaoValue_Serialize2( self, serial, ns, proc, type, buf, omap );
	DString_Delete( buf );
	DMap_Delete( omap );
	return rc;
}
예제 #7
0
static int DaoMap_Serialize( DaoMap *self, DString *serial, DaoNamespace *ns, DaoProcess *proc, DString *buf, DMap *omap )
{
	DaoType *type = self->unitype;
	DaoType *keytype = NULL;
	DaoType *valtype = NULL;
	DNode *node;
	char *sep = self->items->hashing ? ":" : "=>";
	int i = 0, rc = 1;
	if( type->nested && type->nested->size >0 ) keytype = type->nested->items.pType[0];
	if( type->nested && type->nested->size >1 ) valtype = type->nested->items.pType[1];
	if( keytype && (keytype->tid == 0 || keytype->tid >= DAO_ENUM)) keytype = NULL;
	if( valtype && (valtype->tid == 0 || valtype->tid >= DAO_ENUM)) valtype = NULL;
	for(node=DMap_First(self->items); node; node=DMap_Next(self->items,node)){
		DaoType *kt = NULL, *vt = NULL;
		if( keytype == NULL ) kt = DaoNamespace_GetType( ns, node->key.pValue );
		if( valtype == NULL ) vt = DaoNamespace_GetType( ns, node->value.pValue );
		if( (i++) ) DString_AppendChar( serial, ',' );
		rc &= DaoValue_Serialize2( node->key.pValue, serial, ns, proc, kt, buf, omap );
		DString_AppendMBS( serial, sep );
		rc &= DaoValue_Serialize2( node->value.pValue, serial, ns, proc, vt, buf, omap );
	}
	return rc;
}
예제 #8
0
static int DaoTuple_Serialize( DaoTuple *self, DString *serial, DaoNamespace *ns, DaoProcess *proc, DString *buf, DMap *omap )
{
	DArray *nested = self->unitype ? self->unitype->nested : NULL;
	int i, rc = 1;
	for(i=0; i<self->size; i++){
		DaoType *type = NULL;
		DaoType *it = NULL;
		if( nested && nested->size > i ) type = nested->items.pType[i];
		if( type && type->tid == DAO_PAR_NAMED ) type = & type->aux->xType;
		if( type && (type->tid == 0 || type->tid >= DAO_ENUM)) type = NULL;
		if( type == NULL ) it = DaoNamespace_GetType( ns, self->items[i] );
		if( i ) DString_AppendChar( serial, ',' );
		rc &= DaoValue_Serialize2( self->items[i], serial, ns, proc, it, buf, omap );
	}
	return rc;
}
예제 #9
0
파일: daoStdlib.c 프로젝트: hooloong/dao
static void Dao_AboutVar( DaoNamespace *ns, DaoValue *var, DString *str )
{
	DaoType *abtp = DaoNamespace_GetType( ns, var );
	char buf[50];
	if( abtp ){
		DString_Append( str, abtp->name );
		sprintf( buf, "[%p]", var );
		DString_AppendMBS( str, buf );
		if( var->type == DAO_CDATA ){
			sprintf( buf, "(%p)", var->xCdata.data );
			DString_AppendMBS( str, buf );
		}
	}else{
		DString_AppendMBS( str, "NULL" );
	}
}
예제 #10
0
static int DaoList_Serialize( DaoList *self, DString *serial, DaoNamespace *ns, DaoProcess *proc, DString *buf, DMap *omap )
{
	DaoType *type = self->unitype;
	int i, rc = 1;
	if( type->nested && type->nested->size ) type = type->nested->items.pType[0];
	if( type && type->simtype == 0 && (type->tid == 0 || type->tid >= DAO_ENUM)) type = NULL;
	for(i=0; i<self->items.size; i++){
		DaoType *it = NULL;
		if( type == NULL ) it = DaoNamespace_GetType( ns, self->items.items.pValue[i] );
		if( i ) DString_AppendChar( serial, ',' );
		if( it == NULL && type && type->tid >= DAO_ARRAY ) DString_AppendChar( serial, '{' );
		rc &= DaoValue_Serialize2( self->items.items.pValue[i], serial, ns, proc, it, buf, omap );
		if( it == NULL && type && type->tid >= DAO_ARRAY ) DString_AppendChar( serial, '}' );
	}
	return rc;
}
예제 #11
0
파일: daoInterface.c 프로젝트: daokoder/dao
static DaoType* DaoInterface_CheckConversion( DaoType *self, DaoType *type, DaoRoutine *ctx )
{
	DaoRoutine *rout;
	DString *buffer = DString_NewChars( "(" );

	DString_Append( buffer, type->name );
	DString_AppendChars( buffer, ")" );
	rout = DaoType_FindFunction( self, 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;
	}
	return NULL;
}
예제 #12
0
파일: daoValue.c 프로젝트: wherby/dao
static void DaoValue_BasicPrint( DaoValue *self, DaoProcess *proc, DaoStream *stream, DMap *cycData )
{
	DaoType *type = DaoNamespace_GetType( proc->activeNamespace, self );
	if( self->type <= DAO_TUPLE )
		DaoStream_WriteMBS( stream, coreTypeNames[ self->type ] );
	else
		DaoStream_WriteMBS( stream, DaoValue_GetTyper( self )->name );
	if( self->type == DAO_NONE ) return;
	if( self->type == DAO_TYPE ){
		DaoStream_WriteMBS( stream, "<" );
		DaoStream_WriteMBS( stream, self->xType.name->mbs );
		DaoStream_WriteMBS( stream, ">" );
	}
	DaoStream_WriteMBS( stream, "_" );
	DaoStream_WriteInt( stream, self->type );
	DaoStream_WriteMBS( stream, "_" );
	DaoStream_WritePointer( stream, self );
	if( self->type <= DAO_TUPLE ) return;
	if( type && self == type->value ) DaoStream_WriteMBS( stream, "[default]" );
}
예제 #13
0
static DaoType* DaoObject_CheckConversion( DaoType *self, DaoType *type, DaoRoutine *ctx )
{
	DString *buffer;
	DaoRoutine *rout;
	DaoType *hostype = ctx->routHost;
	DaoClass *host = hostype != NULL && hostype->tid == DAO_OBJECT ? (DaoClass*) hostype->aux : NULL;

	if( DaoType_ChildOf( self, type ) ) return type;
	if( DaoType_ChildOf( type, self ) ) return type;

	buffer = DString_NewChars( "(" );
	DString_Append( buffer, type->name );
	DString_AppendChars( buffer, ")" );
	rout = DaoClass_FindMethod( (DaoClass*) self->aux, buffer->chars, host );
	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 != NULL ) return type;
	return NULL;
}
예제 #14
0
static DaoType* DaoObject_CheckGetField( DaoType *self, DaoString *name, 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;

	if( data == NULL ){
		error = DAO_ERROR_FIELD_ABSENT;
	}else if( data->type == DAO_NONE ){
		error = DAO_ERROR_FIELD_HIDDEN;
	}else{
		switch( data->xBase.subtype ){
		case DAO_OBJECT_VARIABLE : return data->xVar.dtype;
		case DAO_CLASS_VARIABLE  : return data->xVar.dtype;
		case DAO_CLASS_CONSTANT  : return DaoNamespace_GetType( ctx->nameSpace, data->xConst.value );
		}
	}
	if( error ){
		DString *field = DString_NewChars( "." );
		DString_Append( field, name->value );
		rout = DaoClass_FindMethod( klass, field->chars, host );
		DString_Delete( field );
		if( rout != NULL ){
			rout = DaoRoutine_MatchByType( rout, self, NULL, 0, DVM_CALL );
		}else{
			rout = DaoClass_FindMethod( klass, ".", host );
			if( rout == NULL ) return NULL;
			rout = DaoRoutine_MatchByType( rout, self, & dao_type_string, 1, DVM_CALL );
		}
		if( rout == NULL ) return NULL;
		return (DaoType*) rout->routType->aux;
	}
	return NULL;
}
예제 #15
0
파일: daoValue.c 프로젝트: daokoder/dao
DaoType* DaoValue_CheckGetValueField( DaoType *self, DaoString *field, DaoRoutine *ctx )
{
	DaoValue *value = DaoType_FindValue( self, field->value );
	if( value ) return DaoNamespace_GetType( ctx->nameSpace, value );
	return NULL;
}
예제 #16
0
파일: daoStdlib.c 프로젝트: hooloong/dao
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 ) );
}
예제 #17
0
파일: daoValue.c 프로젝트: daokoder/dao
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;
}
예제 #18
0
파일: daoValue.c 프로젝트: daokoder/dao
DaoValue* DaoValue_DoGetValueField( DaoValue *self, DaoString *field, DaoProcess *proc )
{
	DaoType *type = DaoNamespace_GetType( proc->activeNamespace, self );
	return DaoType_FindValue( type, field->value );
}