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; }
DaoValue* DaoCinValue_DoBinary( DaoValue *self, DaoVmCode *op, DaoValue *args[2], DaoProcess *proc ) { DaoRoutine *rout = NULL; DaoValue *selfvalue = NULL; DaoType *argtypes[2]; DaoType *type; int retc; 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; } type = self->xCinValue.cintype->vatype; argtypes[0] = proc->activeTypes[ op->a ]; argtypes[1] = proc->activeTypes[ op->b ]; if( op->c == op->a ){ rout = DaoType_FindFunctionChars( type, DaoVmCode_GetCompoundOperator( op->code ) ); if( rout != NULL ){ DaoProcess_PushCallWithTypes( proc, rout, self, args+1, argtypes+1, 1 ); goto TryTarget; } } rout = DaoType_FindFunctionChars( type, DaoVmCode_GetOperator( op->code ) ); if( rout == NULL ) goto TryTarget; if( op->c == op->a && self == args[0] ) selfvalue = self; if( op->c == op->b && self == args[1] ) selfvalue = self; retc = DaoProcess_PushCallWithTypes( proc, rout, selfvalue, args, argtypes, 2 ); // TODO: retc; if( retc == 0 ) return NULL; TryTarget: type = DaoValue_GetType( self->xCinValue.value, proc->vmSpace ); if( type == NULL ) type = self->xCinValue.cintype->target; if( type != NULL && type->core != NULL && type->core->DoBinary != NULL ){ DaoValue *args2[2]; args2[0] = args[0] == self ? self->xCinValue.value : args[0]; args2[1] = args[1] == self ? self->xCinValue.value : args[1]; return type->core->DoBinary( self->xCinValue.value, op, args2, proc ); } return NULL; }
DaoValue* DaoObject_DoBinary( DaoValue *self, DaoVmCode *op, DaoValue *args[2], DaoProcess *proc ) { DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL; DaoRoutine *rout = NULL; DaoValue *selfvalue = NULL; DaoType *argtypes[2]; 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; } argtypes[0] = proc->activeTypes[ op->a ]; argtypes[1] = proc->activeTypes[ op->b ]; if( op->c == op->a ){ const char *name = DaoVmCode_GetCompoundOperator( op->code ); rout = DaoClass_FindMethod( self->xObject.defClass, name, host ); if( rout != NULL ){ DaoProcess_PushCallWithTypes( proc, rout, self, args+1, argtypes + 1, 1 ); return NULL; } } rout = DaoClass_FindMethod( self->xObject.defClass, DaoVmCode_GetOperator( op->code ), host ); if( rout == NULL ){ switch( op->code ){ case DVM_EQ : DaoProcess_PutBoolean( proc, args[0] == args[1] ); break; case DVM_NE : DaoProcess_PutBoolean( proc, args[0] != args[1] ); break; default: break; } return NULL; } if( op->c == op->a && self == args[0] ) selfvalue = self; if( op->c == op->b && self == args[1] ) selfvalue = self; DaoProcess_PushCallWithTypes( proc, rout, selfvalue, args, argtypes, 2 ); // TODO: retc; 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; }
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; }