Beispiel #1
0
DaoRoutine* DaoObject_GetMethod( DaoObject *self, const char *name )
{
	DaoValue *V;
	DString str = DString_WrapChars( name );
	int id = DaoClass_FindConst( self->defClass, & str );
	if( id < 0 ) return NULL;
	V = DaoClass_GetConst( self->defClass, id );
	if( V == NULL || V->type != DAO_ROUTINE ) return NULL;
	return (DaoRoutine*) V;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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 );
}
Beispiel #4
0
/* assumed to be called before parsing class body */
int DaoClass_DeriveClassData( DaoClass *self )
{
	DaoType *type;
	DaoValue *value;
	DString *mbs;
	DNode *it, *search;
	DaoMethodFields *mf;
	daoint i, j, k, id;

	if( DaoCass_DeriveMixinData( self ) == 0 ) return 0;

	mbs = DString_New(1);
	mf = DaoMethodFields_New();

	if( self->clsType->bases == NULL ) self->clsType->bases = DArray_New(D_VALUE);
	if( self->objType->bases == NULL ) self->objType->bases = DArray_New(D_VALUE);
	DArray_Clear( self->clsType->bases );
	DArray_Clear( self->objType->bases );

	self->cstParentStart = self->constants->size;
	self->glbParentStart = self->variables->size;

	DVector_PushUshort( self->offsets, self->constants->size );
	DVector_PushUshort( self->offsets, self->variables->size );
	if( self->parent && self->parent->type == DAO_CLASS ){
		DaoClass *klass = (DaoClass*) self->parent;
		DArray_Append( self->clsType->bases, klass->clsType );
		DArray_Append( self->objType->bases, klass->objType );
		DArray_AppendArray( self->cstDataName, klass->cstDataName );
		DArray_AppendArray( self->glbDataName, klass->glbDataName );
		for(j=0; j<klass->constants->size; ++j){
			DaoValue *cst = klass->constants->items.pConst[j]->value;
			DArray_Append( self->constants, klass->constants->items.pVoid[j] );
		}
		for(j=0; j<klass->variables->size; ++j){
			DArray_Append( self->variables, klass->variables->items.pVoid[j] );
		}
		for(it=DMap_First(klass->lookupTable); it; it=DMap_Next(klass->lookupTable,it)){
			daoint pm = LOOKUP_PM( it->value.pInt );
			daoint st = LOOKUP_ST( it->value.pInt );
			daoint up = LOOKUP_UP( it->value.pInt );
			daoint id = LOOKUP_ID( it->value.pInt );
			DaoValue *cst;
			if( st == DAO_CLASS_CONSTANT ){
				id = LOOKUP_ID( it->value.pInt );
				cst = klass->constants->items.pConst[id]->value;
				if( cst->type == DAO_ROUTINE ){
					DArray_Append( mf->names, it->key.pString );
					DArray_Append( mf->perms, IntToPointer( pm ) );
					DArray_Append( mf->routines, cst );
				}
			}
			if( st == DAO_OBJECT_VARIABLE ) continue;
			if( pm == DAO_DATA_PRIVATE ) continue;
			if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
			switch( st ){
			case DAO_CLASS_CONSTANT : id += self->cstParentStart; break;
			case DAO_CLASS_VARIABLE : id += self->glbParentStart; break;
			case DAO_OBJECT_VARIABLE : continue;
			}
			id = LOOKUP_BIND( st, pm, up+1, id );
			DMap_Insert( self->lookupTable, it->key.pString, (void*)id );
		}
	}else if( self->parent && self->parent->type == DAO_CTYPE ){
		DaoCtype *cdata = (DaoCtype*) self->parent;
		DaoTypeKernel *kernel = cdata->ctype->kernel;
		DaoTypeBase *typer = kernel->typer;
		DMap *methods = kernel->methods;
		DMap *values = kernel->values;

		DArray_Append( self->clsType->bases, cdata->ctype );
		DArray_Append( self->objType->bases, cdata->cdtype );
		DaoClass_AddConst( self, cdata->ctype->name, (DaoValue*)cdata, DAO_DATA_PUBLIC );

		if( kernel->SetupValues ) kernel->SetupValues( kernel->nspace, kernel->typer );
		if( kernel->SetupMethods ) kernel->SetupMethods( kernel->nspace, kernel->typer );

		DaoCdataType_SpecializeMethods( cdata->ctype );
		kernel = cdata->ctype->kernel;
		values = kernel->values;
		methods = kernel->methods;

		if( typer->numItems ){
			for(j=0; typer->numItems[j].name!=NULL; j++){
				DString name = DString_WrapMBS( typer->numItems[j].name );
				it = DMap_Find( values, & name );
				if( it == NULL ) continue;
				if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
				id = self->constants->size;
				id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id );
				DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) );
				DArray_Append( self->cstDataName, it->key.pString );
				DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) );
			}
		}
		for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){
			if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
			id = self->constants->size;
			id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id );
			DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) );
			DArray_Append( self->cstDataName, it->key.pString );
			DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) );

			DArray_Append( mf->names, it->key.pString );
			DArray_Append( mf->perms, IntToPointer( DAO_DATA_PUBLIC ) );
			DArray_Append( mf->routines, it->value.pValue );
		}
	}
	DaoClass_SetupMethodFields( self, mf );
	DaoMethodFields_Delete( mf );

	self->cstParentEnd = self->constants->size;
	self->glbParentEnd = self->variables->size;

#if 0
	for(j=0; j<self->constants->size; ++j){
		DaoValue *value = self->constants->items.pConst[j]->value;
		DaoRoutine *routine = (DaoRoutine*) value;
		printf( "%3i: %3i %s\n", j, value->type, self->cstDataName->items.pString[j]->mbs );
		if( value->type != DAO_ROUTINE ) continue;
		printf( "%3i: %3i %s\n", j, value->type, routine->routName->mbs );
		if( routine->overloads ){
			DArray *routs = routine->overloads->routines;
			for(k=0; k<routs->size; ++k){
				DaoRoutine *rout = routs->items.pRoutine[k];
			}
		}else{
			if( routine->attribs & DAO_ROUT_PRIVATE ) continue;
		}
	}
	for(it=DMap_First(self->lookupTable); it; it=DMap_Next(self->lookupTable,it)){
		printf( "%s %i\n", it->key.pString->mbs, it->value.pInt );
		if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue;
		DaoValue *value = DaoClass_GetConst( self, it->value.pInt );
		printf( "%i\n", value->type );
	}
#endif

	DString_Delete( mbs );
	return 1;
}