static DaoType* DaoInterface_CheckBinary( DaoType *self, DaoVmCode *op, DaoType *args[2], DaoRoutine *ctx ) { DaoRoutine *rout = NULL; DaoType *selftype = NULL; switch( op->code ){ case DVM_ADD : case DVM_SUB : case DVM_MUL : case DVM_DIV : case DVM_MOD : case DVM_POW : case DVM_BITAND : case DVM_BITOR : case DVM_AND : case DVM_OR : case DVM_LT : case DVM_LE : case DVM_EQ : case DVM_NE : break; default: return NULL; } if( op->c == op->a ){ rout = DaoType_FindFunctionChars( self, DaoVmCode_GetCompoundOperator( op->code ) ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, args+1, 1, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; } } rout = DaoType_FindFunctionChars( self, DaoVmCode_GetOperator( op->code ) ); if( rout == NULL ) return NULL; if( op->c == op->a && self == args[0] ) selftype = self; if( op->c == op->b && self == args[1] ) selftype = self; rout = DaoRoutine_MatchByType( rout, selftype, args, 2, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
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; }
DaoType* DaoCinValue_CheckUnary( DaoType *self, DaoVmCode *op, DaoRoutine *ctx ) { DaoRoutine *rout = NULL; DaoTypeCore *core; switch( op->code ){ case DVM_NOT : case DVM_MINUS : case DVM_TILDE : case DVM_SIZE : break; default: return NULL; } rout = DaoType_FindFunctionChars( self, DaoVmCode_GetOperator( op->code ) ); if( rout == NULL ) goto TryTarget; if( op->c == op->a ){ rout = DaoRoutine_MatchByType( rout, self, & self, 1, DVM_CALL ); }else{ rout = DaoRoutine_MatchByType( rout, NULL, & self, 1, DVM_CALL ); } if( rout != NULL ) return (DaoType*) rout->routType->aux; TryTarget: core = self->aux->xCinType.target->core; if( core != NULL && core->CheckUnary != NULL ){ return core->CheckUnary( self->aux->xCinType.target, op, ctx ); } return NULL; }
static DaoType* DaoInterface_CheckGetItem( DaoType *self, DaoType *index[], int N, DaoRoutine *ctx ) { DaoRoutine *rout = DaoType_FindFunctionChars( self, "[]" ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, index, N, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
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; }
DaoType* DaoCinValue_CheckBinary( DaoType *self, DaoVmCode *op, DaoType *args[2], DaoRoutine *ctx ) { DaoRoutine *rout = NULL; DaoType *selftype = NULL; DaoTypeCore *core; switch( op->code ){ case DVM_ADD : case DVM_SUB : case DVM_MUL : case DVM_DIV : case DVM_MOD : case DVM_POW : case DVM_BITAND : case DVM_BITOR : case DVM_AND : case DVM_OR : case DVM_LT : case DVM_LE : case DVM_EQ : case DVM_NE : case DVM_IN : break; default: return NULL; } if( op->c == op->a ){ rout = DaoType_FindFunctionChars( self, DaoVmCode_GetCompoundOperator( op->code ) ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, args+1, 1, DVM_CALL ); if( rout == NULL ) goto TryTarget; return (DaoType*) rout->routType->aux; } } rout = DaoType_FindFunctionChars( self, DaoVmCode_GetOperator( op->code ) ); if( rout == NULL ) goto TryTarget; if( op->c == op->a && self == args[0] ) selftype = self; if( op->c == op->b && self == args[1] ) selftype = self; rout = DaoRoutine_MatchByType( rout, selftype, args, 2, DVM_CALL ); if( rout == NULL ) return (DaoType*) rout->routType->aux; TryTarget: core = self->aux->xCinType.target->core; if( core != NULL && core->CheckBinary != NULL ){ DaoType *args2[2]; args2[0] = args[0] == self ? self->aux->xCinType.target : args[0]; args2[1] = args[1] == self ? self->aux->xCinType.target : args[1]; return core->CheckBinary( self->aux->xCinType.target, op, args2, ctx ); } return NULL; }
static DaoType* DaoObject_CheckGetItem( DaoType *self, DaoType *index[], int N, DaoRoutine *ctx ) { DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoRoutine *rout = DaoClass_FindMethod( (DaoClass*) self->aux, "[]", host ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, index, N, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
DaoType* DaoObject_CheckBinary( DaoType *self, DaoVmCode *op, DaoType *args[2], DaoRoutine *ctx ) { DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoRoutine *rout = NULL; DaoType *selftype = NULL; switch( op->code ){ case DVM_ADD : case DVM_SUB : case DVM_MUL : case DVM_DIV : case DVM_MOD : case DVM_POW : case DVM_BITAND : case DVM_BITOR : case DVM_BITXOR : case DVM_BITLFT : case DVM_BITRIT : case DVM_AND : case DVM_OR : case DVM_LT : case DVM_LE : case DVM_EQ : case DVM_NE : case DVM_IN : break; default: return NULL; } if( op->c == op->a ){ const char *name = DaoVmCode_GetCompoundOperator( op->code ); rout = DaoClass_FindMethod( (DaoClass*) self->aux, name, host ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, args+1, 1, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; } } rout = DaoClass_FindMethod( (DaoClass*) self->aux, DaoVmCode_GetOperator( op->code ), host ); if( rout == NULL ){ if( op->code == DVM_EQ || op->code == DVM_NE ) return dao_type_bool; return NULL; } if( op->c == op->a && self == args[0] ) selftype = self; if( op->c == op->b && self == args[1] ) selftype = self; rout = DaoRoutine_MatchByType( rout, selftype, args, 2, DVM_CALL ); if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
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; }
static DaoType* DaoInterface_CheckUnary( DaoType *self, DaoVmCode *op, DaoRoutine *ctx ) { DaoRoutine *rout = NULL; switch( op->code ){ case DVM_NOT : case DVM_MINUS : case DVM_TILDE : case DVM_SIZE : break; default: return NULL; } rout = DaoType_FindFunctionChars( self, DaoVmCode_GetOperator( op->code ) ); if( rout == NULL ) return NULL; if( op->c == op->a ){ rout = DaoRoutine_MatchByType( rout, self, & self, 1, DVM_CALL ); }else{ rout = DaoRoutine_MatchByType( rout, NULL, & self, 1, DVM_CALL ); } if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
static int DaoInterface_CheckSetItem( DaoType *self, DaoType *index[], int N, DaoType *value, DaoRoutine *ctx ) { DaoRoutine *rout = DaoType_FindFunctionChars( self, "[]=" ); DaoType *args[ DAO_MAX_PARAM + 1 ]; args[0] = value; memcpy( args + 1, index, N*sizeof(DaoType*) ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, args, N+1, DVM_CALL ); if( rout == NULL ) return DAO_ERROR_INDEX; return DAO_OK; }
static DaoType* DaoCinValue_CheckGetItem( DaoType *self, DaoType *index[], int N, DaoRoutine *ctx ) { DaoTypeCore *core; DaoRoutine *rout = DaoType_FindFunctionChars( self, "[]" ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, index, N, DVM_CALL ); if( rout != NULL ) return (DaoType*) rout->routType->aux; core = self->aux->xCinType.target->core; if( core != NULL && core->CheckGetItem != NULL ){ return core->CheckGetItem( self->aux->xCinType.target, index, N, ctx ); } return NULL; }
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; }
DaoType* DaoObject_CheckUnary( DaoType *self, DaoVmCode *op, DaoRoutine *ctx ) { DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoRoutine *rout = NULL; switch( op->code ){ case DVM_NOT : case DVM_MINUS : case DVM_TILDE : case DVM_SIZE : break; default: return NULL; } rout = DaoClass_FindMethod( (DaoClass*) self->aux, DaoVmCode_GetOperator( op->code ), host ); if( rout == NULL ) return NULL; if( op->c == op->a ){ rout = DaoRoutine_MatchByType( rout, self, & self, 1, DVM_CALL ); }else{ rout = DaoRoutine_MatchByType( rout, NULL, & self, 1, DVM_CALL ); } if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
static int DaoObject_CheckSetItem( DaoType *self, DaoType *index[], int N, DaoType *value, DaoRoutine *ctx ) { DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoRoutine *rout = DaoClass_FindMethod( (DaoClass*) self->aux, "[]=", host ); DaoType *args[ DAO_MAX_PARAM + 1 ]; args[0] = value; memcpy( args + 1, index, N*sizeof(DaoType*) ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, args, N+1, DVM_CALL ); if( rout == NULL ) return DAO_ERROR_INDEX; return DAO_OK; }
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; }
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; }
static int DaoCinValue_CheckSetItem( DaoType *self, DaoType *index[], int N, DaoType *value, DaoRoutine *ctx ) { DaoRoutine *rout = DaoType_FindFunctionChars( self, "[]=" ); DaoType *args[ DAO_MAX_PARAM + 1 ]; DaoTypeCore *core; args[0] = value; memcpy( args + 1, index, N*sizeof(DaoType*) ); if( rout != NULL ) rout = DaoRoutine_MatchByType( rout, self, args, N+1, DVM_CALL ); if( rout != NULL ) return DAO_OK; core = self->aux->xCinType.target->core; if( core != NULL && core->CheckSetItem != NULL ){ return core->CheckSetItem( self->aux->xCinType.target, index, N, value, ctx ); } return DAO_ERROR_INDEX; }
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; }