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; }
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 ); }
int DaoValue_CheckSetField( DaoType *self, DaoString *name, DaoType *value ) { DString *buffer = DString_NewChars( "." ); DaoRoutine *rout; DaoType *args[2]; DString_Append( buffer, name->value ); DString_AppendChars( buffer, "=" ); rout = DaoType_FindFunction( self, buffer ); DString_Delete( buffer ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, & value, 1, DVM_CALL ); if( rout == NULL ) return DAO_ERROR_VALUE; }else{ rout = DaoType_FindFunctionChars( self, ".=" ); if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT; args[0] = rout->nameSpace->vmSpace->typeString; args[1] = value; rout = DaoRoutine_MatchByType( rout, self, args, 2, DVM_CALL ); if( rout == NULL ) return DAO_ERROR_VALUE; } return DAO_OK; }
static DaoType* DaoCinType_CheckGetField( DaoType *self, DaoString *name, DaoRoutine *ctx ) { DaoRoutine *rout = DaoType_FindFunction( self, name->value ); if( rout != NULL ) return rout->routType; return NULL; }
static DaoCdata* DaoCdata_MakeObject( DaoCdata *self, DaoValue *param, DaoProcess *proc ) { DaoValue *value; DaoRoutine *routine = DaoType_FindFunction( self->ctype, self->ctype->name ); if( DaoProcess_PushCallable( proc, routine, NULL, & param, 1 ) ) return NULL; proc->topFrame->active = proc->firstFrame; DaoProcess_SetActiveFrame( proc, proc->firstFrame ); /* return value in stackValues[0] */ if( DaoProcess_Execute( proc ) == 0 ) return NULL; value = proc->stackValues[0]; if( value && (value->type == DAO_CDATA || value->type == DAO_CSTRUCT) ) return & value->xCdata; return NULL; }
int DaoInterface_CheckBind( DList *methods, DaoType *type, DMap *binds ) { DNode *it; DaoRoutine *rout2; daoint i, n, id; if( type->tid == DAO_OBJECT || type->tid == DAO_CLASS ){ DaoClass *klass = & type->aux->xClass; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; rout2 = klass->initRoutines; if( !(rout->attribs & DAO_ROUT_INITOR) ){ id = DaoClass_FindConst( klass, rout->routName ); if( id <0 ) return 0; rout2 = (DaoRoutine*) DaoClass_GetConst( klass, id ); if( rout2->type != DAO_ROUTINE ) return 0; } /*printf( "AAA: %s %s\n", rout->routType->name->chars,rout2->routType->name->chars);*/ if( DaoRoutine_IsCompatible( rout2, rout->routType, binds ) ==0 ) return 0; } }else if( type->tid == DAO_INTERFACE ){ DaoInterface *inter = (DaoInterface*) type->aux; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; if( rout->attribs & DAO_ROUT_INITOR ) name = inter->abtype->name; it = DMap_Find( inter->methods, name ); if( it == NULL ) return 0; if( DaoRoutine_IsCompatible( it->value.pRoutine, rout->routType, binds ) ==0 ) return 0; } }else if( type->tid == DAO_CINVALUE ){ DaoCinType *cintype = (DaoCinType*) type->aux; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; if( rout->attribs & DAO_ROUT_INITOR ) name = cintype->vatype->name; it = DMap_Find( cintype->methods, name ); if( it == NULL ) return 0; if( DaoRoutine_IsCompatible( it->value.pRoutine, rout->routType, binds ) ==0 ) return 0; } }else{ for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; DaoRoutine *func; if( rout->attribs & DAO_ROUT_INITOR ) name = type->name; func = DaoType_FindFunction( type, name ); if( func == NULL ) return 0; if( DaoRoutine_IsCompatible( func, rout->routType, binds ) ==0 ) return 0; } } return 1; }
DaoType* DaoValue_CheckGetField( DaoType *self, DaoString *name ) { DaoRoutine *rout = DaoType_FindFunction( self, name->value ); DaoType *argtype; DString *buffer; if( rout != NULL ) return rout->routType; buffer = DString_NewChars( "." ); DString_Append( buffer, name->value ); rout = DaoType_FindFunction( self, buffer ); DString_Delete( buffer ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, NULL, 0, DVM_CALL ); }else{ rout = DaoType_FindFunctionChars( self, "." ); if( rout == NULL ) return NULL; argtype = rout->nameSpace->vmSpace->typeString; rout = DaoRoutine_MatchByType( rout, self, & argtype, 1, DVM_CALL ); } if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
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; }
int DaoValue_DoSetField( DaoValue *self, DaoType *type, DaoString *name, DaoValue *value, DaoProcess *proc ) { DaoRoutine *rout; DString_SetChars( proc->string, "." ); DString_Append( proc->string, name->value ); DString_AppendChars( proc->string, "=" ); rout = DaoType_FindFunction( type, proc->string ); if( rout != NULL ){ return DaoProcess_PushCall( proc, rout, self, & value, 1 ); }else{ DaoValue *args[2]; args[0] = (DaoValue*) name; args[1] = value; rout = DaoType_FindFunctionChars( type, ".=" ); if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT; return DaoProcess_PushCall( proc, rout, self, args, 2 ); } return DAO_ERROR_FIELD_ABSENT; }
DaoValue* DaoValue_DoGetField( DaoValue *self, DaoType *type, DaoString *name, DaoProcess *proc ) { DaoValue *value = DaoType_FindValue( type, name->value ); DaoRoutine *rout; if( value != NULL ) return value; DString_SetChars( proc->string, "." ); DString_Append( proc->string, name->value ); rout = DaoType_FindFunction( type, proc->string ); if( rout != NULL ){ DaoProcess_PushCall( proc, rout, self, NULL, 0 ); }else{ DaoValue *arg = (DaoValue*) name; rout = DaoType_FindFunctionChars( type, "." ); if( rout == NULL ) return NULL; DaoProcess_PushCall( proc, rout, self, & arg, 1 ); } return NULL; }
static int DaoInterface_CheckMethod( DaoRoutine *routine, DaoType *type, DMap *binds ) { DaoRoutine *method = NULL; DNode *it; if( type->tid == DAO_OBJECT || type->tid == DAO_CLASS ){ DaoClass *klass = & type->aux->xClass; method = klass->initRoutines; if( !(routine->attribs & DAO_ROUT_INITOR) ){ int id = DaoClass_FindConst( klass, routine->routName ); if( id <0 ) return 0; method = (DaoRoutine*) DaoClass_GetConst( klass, id ); if( method->type != DAO_ROUTINE ) return 0; } }else if( type->tid == DAO_INTERFACE ){ DaoInterface *inter = (DaoInterface*) type->aux; DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = inter->abtype->name; it = DMap_Find( inter->methods, name ); if( it != NULL ) method = it->value.pRoutine; }else if( type->tid == DAO_CINVALUE ){ DaoCinType *cintype = (DaoCinType*) type->aux; DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = cintype->vatype->name; it = DMap_Find( cintype->methods, name ); if( it == NULL && cintype->target != NULL ){ return DaoInterface_CheckMethod( routine, cintype->target, binds ); } if( it != NULL ) method = it->value.pRoutine; }else{ DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = type->name; method = DaoType_FindFunction( type, name ); } if( method == NULL ) return 0; /*printf( "AAA: %s %s\n", routine->routType->name->chars,method->routType->name->chars);*/ return DaoRoutine_IsCompatible( method, routine->routType, binds ); }