示例#1
0
static DaoValue* DaoObject_DoGetField( DaoValue *self, DaoString *name, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoObject *host = proc->activeObject;
	DaoClass *hostClass = host ? host->defClass : NULL;
	DaoValue *value = NULL;
	int rc = DaoObject_GetData( object, name->value, & value, host );
	if( rc ){
		DaoRoutine *rout;
		DString *field = proc->string;

		DString_SetChars( field, "." );
		DString_Append( field, name->value );
		rout = DaoClass_FindMethod( object->defClass, field->chars, hostClass );
		if( rout != NULL ){
			rc = DaoProcess_PushCall( proc, rout, self, NULL, 0 );
		}else{
			DaoValue *arg = (DaoValue*) name;
			rout = DaoClass_FindMethod( object->defClass, ".", hostClass );
			if( rout != NULL ) rc = DaoProcess_PushCall( proc, rout, self, & arg, 1 );
		}
		if( rout == NULL ) return NULL;
	}else{
		DaoProcess_PutValue( proc, value );
	}
	if( rc ) DaoProcess_RaiseError( proc, daoExceptionNames[rc], name->value->chars );
	return NULL;
}
示例#2
0
static int DaoObject_DoSetField( DaoValue *self, DaoString *name, DaoValue *value, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoObject *host = proc->activeObject;
	DaoClass *hostClass = host ? host->defClass : NULL;
	int ec = DaoObject_SetData( object, name->value, value, host );
	if( ec != DAO_OK ){
		DString *field = proc->string;
		DaoRoutine *rout;

		DString_SetChars( field, "." );
		DString_Append( field, name->value );
		DString_AppendChars( field, "=" );
		rout = DaoClass_FindMethod( object->defClass, field->chars, hostClass );
		if( rout != NULL ){
			ec = DaoProcess_PushCall( proc, rout, self, & value, 1 );
		}else{
			DaoValue *args[2];
			args[0] = (DaoValue*) name;
			args[1] = value;
			rout = DaoClass_FindMethod( object->defClass, ".=", hostClass );
			if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT;
			ec = DaoProcess_PushCall( proc, rout, self, args, 2 );
		}
		if( rout == NULL ) return DAO_ERROR_FIELD_ABSENT;
	}
	if( ec ) DaoProcess_RaiseError( proc, daoExceptionNames[ec], name->value->chars );
	return ec;
}
示例#3
0
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;
}
示例#4
0
void DaoObject_Print( DaoValue *self, DaoStream *stream, DMap *cycmap, DaoProcess *proc )
{
	int ec = 0;
	char buf[50];
	DMap *inmap = cycmap;
	DaoObject *object = (DaoObject*) self;
	DaoValue *params[2];
	DaoRoutine *meth;

	sprintf( buf, "[%p]", object );
	if( self == object->defClass->objType->value ){
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, "[null]" );
		return;
	}
	if( cycmap != NULL && DMap_Find( cycmap, object ) != NULL ){
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, buf );
		return;
	}
	if( cycmap == NULL ) cycmap = DHash_New(0,0);
	DMap_Insert( cycmap, self, self );

	DaoValue_Clear( & proc->stackValues[0] );

	params[0] = (DaoValue*) dao_type_string;
	params[1] = (DaoValue*) stream;
	meth = DaoClass_FindMethod( object->defClass, "(string)", NULL );
	if( meth ){
		ec = DaoProcess_Call( proc, meth, self, params, 2 );
		if( ec ) ec = DaoProcess_Call( proc, meth, self, params, 1 );
	}else{
		meth = DaoClass_FindMethod( object->defClass, "serialize", NULL );
		if( meth ) ec = DaoProcess_Call( proc, meth, self, NULL, 0 );
	}
	if( ec ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL );
	}else if( meth && proc->stackValues[0] ){
		DaoValue_Print( proc->stackValues[0], stream, cycmap, proc );
	}else{
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, buf );
	}
	if( inmap == NULL ) DMap_Delete( cycmap );
}
示例#5
0
static DaoValue* DaoObject_DoGetItem( DaoValue *self, DaoValue *index[], int N, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoRoutine *rout = DaoClass_FindMethod( object->defClass, "[]", host );
	int rc = DaoProcess_PushCall( proc, rout, self, index, N );
	if( rc ) DaoProcess_RaiseError( proc, daoExceptionNames[rc], NULL );
	return NULL;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
int DaoObject_DoForEach( DaoValue *self, DaoTuple *iterator, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoRoutine *rout = DaoClass_FindMethod( object->defClass, "for", host );
	if( rout != NULL ){
		return DaoProcess_PushCall( proc, rout, self, (DaoValue**) & iterator, 1 );
	}
	return DAO_ERROR;
}
示例#9
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;
}
示例#10
0
static void DaoObject_Print( DaoValue *self0, DaoProcess *proc, DaoStream *stream, DMap *cycData )
{
	int ec = 0;
	char buf[50];
	DaoObject *self = & self0->xObject;
	DaoValue *params[2];
	DaoRoutine *meth;

	sprintf( buf, "[%p]", self );
	if( self0 == self->defClass->objType->value ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, "[null]" );
		return;
	}
	if( cycData != NULL && DMap_Find( cycData, self ) != NULL ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
		return;
	}
	if( cycData ) MAP_Insert( cycData, self, self );

	DaoValue_Clear( & proc->stackValues[0] );

	params[0] = (DaoValue*) dao_type_string;
	params[1] = (DaoValue*) stream;
	meth = DaoClass_FindMethod( self->defClass, "(string)", NULL );
	if( meth ){
		ec = DaoProcess_Call( proc, meth, self0, params, 2 );
		if( ec ) ec = DaoProcess_Call( proc, meth, self0, params, 1 );
	}else{
		meth = DaoClass_FindMethod( self->defClass, "serialize", NULL );
		if( meth ) ec = DaoProcess_Call( proc, meth, self0, NULL, 0 );
	}
	if( ec ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL );
	}else if( meth && proc->stackValues[0] ){
		DaoValue_Print( proc->stackValues[0], proc, stream, cycData );
	}else{
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
	}
}
示例#11
0
static int DaoObject_DoSetItem( DaoValue *self, DaoValue *index[], int N, DaoValue *value, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoRoutine *rout = DaoClass_FindMethod( object->defClass, "[]=", host );
	DaoValue *args[DAO_MAX_PARAM+1];
	int rc;

	args[0] = value;
	memcpy( args+1, index, N*sizeof(DaoValue*) );
	return DaoProcess_PushCall( proc, rout, self, args, N+1 );
	//if( rc ) DaoProcess_RaiseError( proc, daoExceptionNames[rc], NULL );
}
示例#12
0
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;
}
示例#13
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;
}
示例#14
0
DaoType* DaoObject_CheckForEach( DaoType *self, DaoRoutine *ctx )
{
	DaoType *hostype = ctx->routHost;
	DaoClass *host = hostype != NULL && hostype->tid == DAO_OBJECT ? (DaoClass*) hostype->aux : NULL;
	DaoRoutine *rout = DaoClass_FindMethod( (DaoClass*) self->aux, "for", host );
	if( rout != NULL ){
		DaoType *type, *itype;
		if( rout->routType->args->size != 2 ) return NULL;
		type = rout->routType->args->items.pType[1];
		if( type->tid == DAO_PAR_NAMED ) type = (DaoType*) type->aux;
		if( type->tid != DAO_TUPLE || type->args->size != 2 ) return NULL;
		itype = type->args->items.pType[0];
		if( itype->tid != DAO_BOOLEAN ) return NULL;
		return DaoNamespace_MakeIteratorType( ctx->nameSpace, type->args->items.pType[1] );
	}
	return NULL;
}
示例#15
0
static DaoValue* DaoObject_DoConversion( DaoValue *self, DaoType *type, int copy, DaoProcess *proc )
{
	DaoObject *object = (DaoObject*) self;
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoValue *base = DaoObject_CastToBase( object->rootObject, type );
	DaoRoutine *rout;
	DString *buffer;

	if( base ) return base;

	buffer = DString_NewChars( "(" );
	DString_Append( buffer, type->name );
	DString_AppendChars( buffer, ")" );
	rout = DaoClass_FindMethod( object->defClass, buffer->chars, host );
	DString_Delete( buffer );
	if( rout != NULL ){
		int rc = DaoProcess_PushCall( proc, rout, self, (DaoValue**) & type, 1 );
		if( rc ) return NULL;
	}
	return NULL;
}
示例#16
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;
}
示例#17
0
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;
}
示例#18
0
DaoValue* DaoObject_DoUnary( DaoValue *self, DaoVmCode *op, DaoProcess *proc )
{
	DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL;
	DaoType *argtype = proc->activeTypes[op->a];;
	DaoRoutine *rout = NULL;
	int retc = 0;

	switch( op->code ){
	case DVM_NOT   :
	case DVM_MINUS :
	case DVM_TILDE :
	case DVM_SIZE  : break;
	default: return NULL;
	}
	rout = DaoClass_FindMethod( self->xObject.defClass, DaoVmCode_GetOperator( op->code ), host );
	if( rout == NULL ) return NULL;
	if( op->c == op->a ){
		retc = DaoProcess_PushCallWithTypes( proc, rout, self, & self, & argtype, 1 );
	}else{
		retc = DaoProcess_PushCallWithTypes( proc, rout, NULL, & self, & argtype, 1 );
	}
	// TODO: retc;
	return NULL;
}