/* Backward traverse the macro units and set stopping tokens for each unit. * A stopping token is defined as the content of a macro unit of type DMACRO_TOK. * XXX, also define stopping token by DMACRO_BR units? */ static void DMacroGroup_SetStop( DMacroGroup *self, DArray *stops ) { DMacroGroup *group; daoint i, j; /* printf( "stop : %i\n", stops->size ); */ for(i=self->units->size-1; i>=0; i--){ DMacroUnit *unit = (DMacroUnit*) self->units->items.pVoid[i]; if( unit->type == DMACRO_GRP || unit->type == DMACRO_ALT ){ group = (DMacroGroup*) unit; /* self->stops as temporary array: */ DArray_Assign( self->stops, stops ); /* recursive set stopping tokens for macro groups: */ DMacroGroup_SetStop( group, self->stops ); /* if the group has to be presented at least once, * no propagating the stopping tokens to the previous macro units. */ if( group->repeat > DMACRO_ZERO_OR_MORE ) DArray_Clear( stops ); /* add stopping token, why only one ? XXX */ if( group->stops->size >0) DArray_PushFront( stops, group->stops->items.pString[0] ); }else if( unit->type == DMACRO_TOK ){ /* printf( "%s", unit->marker->mbs ); */ DArray_Clear( stops ); /* define a stopping token */ DArray_Append( stops, unit->marker ); DArray_Append( unit->stops, unit->marker ); }else{ /* printf( "%s", unit->marker->mbs ); */ for(j=0; j<stops->size; j++) DArray_Append( unit->stops, stops->items.pString[j] ); } /* printf( " : %i; ", unit->stops->size ); */ } if( self->repeat == DMACRO_ZERO_OR_MORE || self->repeat == DMACRO_ONE_OR_MORE ){ /* this is fine for DMACRO_GRP unit, what about DMACRO_ALT unit? XXX */ if( self->units->size >1 ){ DMacroUnit *first = (DMacroUnit*) self->units->items.pVoid[0]; DMacroGroup_AddStop( self, first->stops ); } } DArray_Assign( self->stops, stops ); /* printf( "group : %i\n", self->stops->size ); */ }
DArray* DArray_Copy( DArray *self ) { DArray *copy = DArray_New( self->type ); DArray_Assign( copy, self ); return copy; }
DaoClass* DaoClass_Instantiate( DaoClass *self, DArray *types ) { DaoClass *klass = NULL; DaoType *type; DString *name; DNode *node; DMap *deftypes; daoint lt = DString_FindChar( self->className, '<', 0 ); daoint i, holders = 0; if( self->typeHolders == NULL || self->typeHolders->size ==0 ) return self; while( types->size < self->typeHolders->size ){ type = self->typeDefaults->items.pType[ types->size ]; if( type == NULL ) type = self->typeHolders->items.pType[ types->size ]; DArray_Append( types, type ); } name = DString_New(1); DString_Append( name, self->className ); if( lt != MAXSIZE ) DString_Erase( name, lt, MAXSIZE ); DString_AppendChar( name, '<' ); for(i=0; i<types->size; i++){ type = types->items.pType[i]; holders += type->tid == DAO_THT; if( i ) DString_AppendChar( name, ',' ); DString_Append( name, type->name ); } DString_AppendChar( name, '>' ); while( self->templateClass ) self = self->templateClass; node = DMap_Find( self->instanceClasses, name ); if( node ){ klass = node->value.pClass; }else{ deftypes = DMap_New(0,0); klass = DaoClass_New(); if( holders ) klass->templateClass = self; DMap_Insert( self->instanceClasses, name, klass ); DaoClass_AddReference( self, klass ); /* No need for cleanup of klass; */ DaoClass_SetName( klass, name, self->classRoutine->nameSpace ); for(i=0; i<types->size; i++){ type = types->items.pType[i]; if( DaoType_MatchTo( type, self->typeHolders->items.pType[i], deftypes ) ==0 ){ DString_Delete( name ); return NULL; } MAP_Insert( deftypes, self->typeHolders->items.pVoid[i], type ); } klass->objType->nested = DArray_New(D_VALUE); DArray_Assign( klass->objType->nested, types ); if( DaoClass_CopyField( klass, self, deftypes ) == 0 ){ DString_Delete( name ); return NULL; } DaoClass_DeriveClassData( klass ); DaoClass_DeriveObjectData( klass ); DaoClass_ResetAttributes( klass ); DMap_Delete( deftypes ); if( holders ){ klass->typeHolders = DArray_New(0); klass->typeDefaults = DArray_New(0); klass->instanceClasses = DMap_New(D_STRING,0); DMap_Insert( klass->instanceClasses, klass->className, klass ); for(i=0; i<types->size; i++){ DArray_Append( klass->typeHolders, types->items.pType[i] ); DArray_Append( klass->typeDefaults, NULL ); } for(i=0; i<klass->typeHolders->size; i++){ DaoClass_AddReference( klass, klass->typeHolders->items.pType[i] ); DaoClass_AddReference( klass, klass->typeDefaults->items.pType[i] ); } } } DString_Delete( name ); return klass; }