int DaoType_MatchInterface( DaoType *self, DaoInterface *inter, DMap *binds ) { DMap *inters = self->interfaces; DNode *it; daoint i; if( inter == NULL ) return DAO_MT_NOT; if( inter->abtype->kernel->SetupMethods ){ DaoTypeKernel *kernel = inter->abtype->kernel; kernel->SetupMethods( kernel->nspace, kernel->typer ); } if( inters == NULL ) return DAO_MT_SUB * DaoInterface_BindTo( inter, self, binds ); if( (it = DMap_Find( inters, inter )) ) return it->value.pVoid ? DAO_MT_SUB : DAO_MT_NOT; return DAO_MT_SUB * DaoInterface_BindTo( inter, self, binds ); }
DaoRoutine* DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds ) { DNode *it; DMap *newbinds = NULL; DList *methods; DaoRoutine *incompatible; void *pvoid[2]; daoint i, n; if( self->abtype->kernel->SetupMethods ){ DaoTypeKernel *kernel = self->abtype->kernel; kernel->SetupMethods( kernel->nspace, self->abtype->core ); } /* XXX locking */ if( type->interfaces == NULL ){ type->interfaces = DHash_New( DAO_DATA_VALUE, DAO_DATA_VALUE ); } pvoid[0] = type; pvoid[1] = self->abtype; if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pRoutine; if( binds && DMap_Find( binds, pvoid ) ) return NULL; if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 ); DaoInterface_TempBind( self, type, binds ); methods = DList_New(0); DMap_SortMethods( self->methods, methods ); incompatible = DaoInterface_CheckBind( methods, type, binds ); DList_Delete( methods ); if( newbinds ) DMap_Delete( newbinds ); DMap_Insert( type->interfaces, self, incompatible ); if( incompatible ) return incompatible; for(i=0,n=self->bases->size; i<n; i++){ DaoInterface *base = (DaoInterface*) self->bases->items.pValue[i]; if( DMap_Find( type->interfaces, base ) ) continue; DMap_Insert( type->interfaces, base, NULL ); } return NULL; }
/* 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; }