/* // Note: reference count is not handled for "self"! // But it is cached in the DaoProcess object, so no need to handle it by user! */ int DaoValue_Deserialize( DaoValue **self, DString *serial, DaoNamespace *ns, DaoProcess *proc ) { DaoParser *parser = DaoParser_New(); DArray *types = DArray_New(0); DMap *omap = DMap_New(0,0); int rc; *self = NULL; parser->nameSpace = ns; parser->vmSpace = ns->vmSpace; DaoParser_LexCode( parser, DString_GetMBS( serial ), 0 ); if( parser->tokens->size == 0 ) goto Failed; DArray_PushFront( types, NULL ); rc = DaoParser_Deserialize( parser, 0, parser->tokens->size-1, self, types, ns, proc, omap ); if( *self ) DaoProcess_CacheValue( proc, *self ); DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return rc; Failed: DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return 0; }
int DaoCass_DeriveMixinData( DaoClass *self ) { DMap *mixed = DMap_New(0,D_MAP); DaoMethodFields *mf = DaoMethodFields_New(); DNode *it, *search; daoint i, bl = 1; self->cstMixinStart = self->constants->size; self->glbMixinStart = self->variables->size; self->objMixinStart = self->instvars->size; for(i=0; i<self->mixinBases->size; ++i){ DaoClass *mixin = self->mixinBases->items.pClass[i]; bl &= DaoClass_MixIn( self, mixin, mixed, mf ); } self->cstMixinEnd = self->constants->size; self->glbMixinEnd = self->variables->size; self->objMixinEnd = self->instvars->size; DaoClass_SetupMethodFields( self, mf ); self->cstMixinEnd2 = self->constants->size; self->glbMixinEnd2 = self->variables->size; self->objMixinEnd2 = self->instvars->size; DMap_Delete( mixed ); DaoMethodFields_Delete( mf ); return bl; }
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms ) { DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}}; DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) ); DMutex_Init( & self->mutex ); DCondVar_Init( & self->condv ); DCondVar_Init( & self->condv2 ); DThread_Init( & self->timer ); self->finishing = 0; self->timing = 0; self->total = 0; self->idle = 0; self->stopped = 0; self->threads = DArray_New(0); self->functions = DArray_New(0); self->parameters = DArray_New(0); self->events = DArray_New(0); self->events2 = DArray_New(0); self->waitings = DMap_New(D_VALUE,0); self->pending = DHash_New(0,0); self->active = DHash_New(0,0); self->caches = DArray_New(0); self->vmspace = vms; self->timestamp = com; return self; }
DaoClass* DaoClass_New() { DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) ); DaoValue_Init( self, DAO_CLASS ); self->trait |= DAO_VALUE_DELAYGC; self->className = DString_New(1); self->lookupTable = DHash_New(D_STRING,0); self->ovldRoutMap = DHash_New(D_STRING,0); self->abstypes = DMap_New(D_STRING,D_VALUE); self->constants = DArray_New(D_VALUE); self->variables = DArray_New(D_VALUE); self->instvars = DArray_New(D_VALUE); self->objDataName = DArray_New(D_STRING); self->cstDataName = DArray_New(D_STRING); self->glbDataName = DArray_New(D_STRING); self->parent = NULL; self->mixinBases = DArray_New(0); /* refcount handled in ::allBases; */ self->allBases = DArray_New(D_VALUE); self->mixins = DArray_New(0); self->ranges = DVector_New(sizeof(ushort_t)); self->offsets = DVector_New(sizeof(ushort_t)); self->references = DArray_New(D_VALUE); self->inter = NULL; self->cstMixinStart = self->cstMixinEnd = self->cstMixinEnd2 = 0; self->glbMixinStart = self->glbMixinEnd = self->glbMixinEnd2 = 0; self->objMixinStart = self->objMixinEnd = self->objMixinEnd2 = 0; self->cstParentStart = self->cstParentEnd = 0; self->glbParentStart = self->glbParentEnd = 0; return self; }
static void DMap_SortMethods( DMap *hash, DList *methods ) { DMap *map = DMap_New( DAO_DATA_STRING, 0 ); DString *name = DString_New(); DNode *it; daoint i, n; for(it=DMap_First(hash); it; it=DMap_Next(hash,it)){ if( it->value.pRoutine->overloads ){ DRoutines *one = it->value.pRoutine->overloads; for(i=0,n=one->routines->size; i<n; i++){ DaoRoutine *rout = one->routines->items.pRoutine[i]; DString_Assign( name, rout->routName ); DString_AppendChars( name, " " ); DString_Append( name, rout->routType->name ); DMap_Insert( map, name, (void*)rout ); } }else{ DaoRoutine *rout = it->value.pRoutine; DString_Assign( name, rout->routName ); DString_AppendChars( name, " " ); DString_Append( name, rout->routType->name ); DMap_Insert( map, name, (void*)rout ); } } DList_Clear( methods ); for(it=DMap_First(map); it; it=DMap_Next(map,it)) DList_Append( methods, it->value.pVoid ); DMap_Delete( map ); DString_Delete( name ); }
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms ) { DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) ); DMutex_Init( & self->mutex ); DCondVar_Init( & self->condv ); DCondVar_Init( & self->condv2 ); DThread_Init( & self->timer ); self->finishing = 0; self->timing = 0; self->total = 0; self->vacant = 0; self->idle = 0; self->stopped = 0; self->threads = DList_New(0); self->functions = DList_New(0); self->parameters = DList_New(0); self->owners = DList_New(0); self->events = DList_New(0); self->events2 = DList_New(0); self->waitings = DMap_New( DAO_DATA_COMPLEX, 0 ); self->pending = DHash_New(0,0); self->active = DHash_New(0,0); self->caches = DList_New(0); self->vmspace = vms; self->timestamp.real = 0.0; self->timestamp.imag = 0.0; return self; }
DaoxFont* DaoxFont_New() { DaoxFont *self = (DaoxFont*) dao_calloc( 1, sizeof(DaoxFont) ); DaoCstruct_Init( (DaoCstruct*)self, daox_type_font ); self->buffer = DString_New(); self->glyphs = DMap_New(0,DAO_DATA_VALUE); return self; }
static void DaoIO_Write0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DMap *cycData; int i; if( (self->attribs & (DAO_IO_FILE | DAO_IO_PIPE)) && self->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not open!" ); return; } cycData = DMap_New(0,0); for(i=0; i<N; i++) DaoValue_Print( p[i], proc, self, cycData ); DMap_Delete( cycData ); }
void DaoValue_Print( DaoValue *self, DaoProcess *proc, DaoStream *stream, DMap *cycData ) { DString *name; DaoTypeBase *typer; DMap *cd = cycData; if( self == NULL ){ DaoStream_WriteMBS( stream, "none[0x0]" ); return; } if( cycData == NULL ) cycData = DMap_New(0,0); switch( self->type ){ case DAO_INTEGER : DaoStream_WriteInt( stream, self->xInteger.value ); break; case DAO_FLOAT : DaoStream_WriteFloat( stream, self->xFloat.value ); break; case DAO_DOUBLE : DaoStream_WriteFloat( stream, self->xDouble.value ); break; case DAO_COMPLEX : DaoStream_WriteFloat( stream, self->xComplex.value.real ); if( self->xComplex.value.imag >= -0.0 ) DaoStream_WriteMBS( stream, "+" ); DaoStream_WriteFloat( stream, self->xComplex.value.imag ); DaoStream_WriteMBS( stream, "C" ); break; #ifdef DAO_WITH_LONGINT case DAO_LONG : name = DString_New(1); DLong_Print( self->xLong.value, name ); DaoStream_WriteString( stream, name ); DString_Delete( name ); break; #endif case DAO_ENUM : name = DString_New(1); DaoEnum_MakeName( & self->xEnum, name ); DaoStream_WriteMBS( stream, name->mbs ); DaoStream_WriteMBS( stream, "(" ); DaoStream_WriteInt( stream, self->xEnum.value ); DaoStream_WriteMBS( stream, ")" ); DString_Delete( name ); break; case DAO_STRING : DaoStream_WriteString( stream, self->xString.data ); break; default : typer = DaoVmSpace_GetTyper( self->type ); if( typer->core->Print == DaoValue_Print ){ DaoValue_BasicPrint( self, proc, stream, cycData ); break; } typer->core->Print( self, proc, stream, cycData ); break; } if( cycData != cd ) DMap_Delete( cycData ); }
int DaoValue_Serialize( DaoValue *self, DString *serial, DaoNamespace *ns, DaoProcess *proc ) { DaoType *type = DaoNamespace_GetType( ns, self ); DString *buf = DString_New(1); DMap *omap = DMap_New(0,0); int rc; DString_Clear( serial ); DString_ToMBS( serial ); rc = DaoValue_Serialize2( self, serial, ns, proc, type, buf, omap ); DString_Delete( buf ); DMap_Delete( omap ); return rc; }
DaoClass* DaoClass_New() { DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) ); DaoValue_Init( self, DAO_CLASS ); self->trait |= DAO_VALUE_DELAYGC; self->className = DString_New(1); self->lookupTable = DHash_New(D_STRING,0); self->ovldRoutMap = DHash_New(D_STRING,0); self->abstypes = DMap_New(D_STRING,D_VALUE); self->constants = DArray_New(D_VALUE); self->variables = DArray_New(D_VALUE); self->instvars = DArray_New(D_VALUE); self->objDataName = DArray_New(D_STRING); self->cstDataName = DArray_New(D_STRING); self->glbDataName = DArray_New(D_STRING); self->superClass = DArray_New(D_VALUE); self->references = DArray_New(D_VALUE); return self; }
static void DaoClass_SetupMethodFields( DaoClass *self, DaoMethodFields *mf ) { DaoValue *cst; DMap *overloads = DMap_New(D_STRING,0); DNode *it, *search; daoint i, id, pm, pm2; for(i=0; i<mf->names->size; ++i){ DString *name = mf->names->items.pString[i]; it = DMap_Find( self->lookupTable, name ); if( it == NULL ) continue; if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue; id = LOOKUP_ID( it->value.pInt ); DMap_Insert( overloads, name, self->constants->items.pConst[id]->value ); } for(i=0; i<mf->names->size; ++i){ DString *name = mf->names->items.pString[i]; it = DMap_Find( self->lookupTable, name ); if( it == NULL ) continue; if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue; cst = mf->routines->items.pValue[i]; search = DMap_Find( overloads, name ); if( cst == search->value.pValue ) continue; pm = LOOKUP_PM( it->value.pInt ); pm2 = mf->perms->items.pInt[i]; if( pm2 > pm ) pm = pm2; /* // Add again the overloaded methods, so that a new overloading structure // will be created for the host class. This is necessary to avoid messing // the function calls in the methods of the mixins. */ DaoClass_AddConst( self, name, cst, pm ); } DMap_Delete( overloads ); }
int DaoParser_ParseMacro( DaoParser *self, int start ) { int rb1, rb2, i = start, N = self->tokens->size; DaoToken **toks = self->tokens->items.pToken; DMacroUnit *first; DaoMacro *macro; DString *lang = NULL; DArray *stops; DMap *markers; DNode *it; if( start + 5 >= N ) return -1; if( toks[start+1]->type != DTOK_LCB ){ lang = & toks[start+1]->string; if( toks[start+1]->type != DTOK_IDENTIFIER ){ DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang ); return -1; } if( lang->size == 3 && strcmp( lang->mbs, "dao" ) == 0 ){ DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang ); return -1; } start += 1; } if( toks[start+1]->name != DTOK_LCB ) return -1; self->curLine = toks[start]->line; rb1 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, -1 ); if( rb1 <0 || rb1 +3 >= N ) return -1; if( toks[rb1+1]->name != DKEY_AS || toks[rb1+2]->name != DTOK_LCB ){ DaoParser_Error( self, DAO_CTW_INV_MAC_DEFINE, NULL ); return -1; } rb2 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, rb1 + 1, -1 ); if( rb2 <0 ) return -1; /* for( i=start; i<rb2; i++ ) printf( "%s ", toks[i]->string.mbs ); printf("\n"); */ macro = DaoMacro_New(); markers = DMap_New(D_STRING,0); if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1, markers, NULL ) ==0 ){ goto Error; } if( macro->macroMatch->units->size == 0 ) goto Error; first = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0]; if( first->type != DMACRO_TOK ){ DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string ); goto Error; } for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){ if( it->value.pInt > 1 ){ DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, it->key.pString ); goto Error; } } DMap_Clear( markers ); if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos; if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2, NULL, markers ) ==0 ){ goto Error; } for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){ DArray_Append( macro->keyListApply, it->key.pString ); } stops = DArray_New(D_TOKEN); DMacroGroup_SetStop( macro->macroMatch, stops ); DMacroGroup_FindVariables( macro->macroMatch ); DArray_Clear( stops ); DMacroGroup_SetStop( macro->macroApply, stops ); DaoNamespace_AddMacro( self->nameSpace, lang, & first->marker->string, macro ); DArray_Delete( stops ); DMap_Delete( markers ); return rb2; Error: DaoMacro_Delete( macro ); DMap_Delete( markers ); return -1; }
void DaoProfiler_Report( DaoProfiler *self0, DaoStream *stream ) { DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}}; DaoxProfiler *self = (DaoxProfiler*) self0; DMap *summary = DMap_New( DAO_DATA_VALUE, 0 ); DMap *summary2 = DMap_New( DAO_DATA_VALUE, 0 ); DString *name1 = DString_New(); DString *name2 = DString_New(); DNode *it, *it2; int count, max = 20; char buf1[32]; char buf2[24]; char buf[120]; for(it=DMap_First(self->profile); it; it=DMap_Next(self->profile,it)){ DaoRoutine *callee = (DaoRoutine*) it->key.pValue; com.value = DaoProfiler_Sum( it->value.pMap ); com.value.real = - com.value.real; com.value.imag = - com.value.imag; DMap_Insert( summary, & com, it ); } DaoStream_WriteChars( stream, "\n" ); DaoStream_WriteChars( stream, delimiter ); DaoStream_WriteChars( stream, delimiter2 ); snprintf( buf, sizeof(buf), header_format, "Routine", "#Calls", "CPU Time" ); DaoStream_WriteChars( stream, buf ); DaoStream_WriteChars( stream, delimiter2 ); for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){ DNode *it2 = (DNode*) it->value.pVoid; dao_complex data = it->key.pValue->xComplex.value; DaoRoutine *callee = (DaoRoutine*) it2->key.pValue; DaoRoutine_MakeName( callee, name1, 28, 10, 2 ); snprintf( buf, sizeof(buf), row_format, name1->chars, (int) -data.imag, -data.real ); DaoStream_WriteChars( stream, buf ); if( count == 0 ) break; } DaoStream_WriteChars( stream, "\n" ); DaoStream_WriteChars( stream, delimiter3 ); snprintf( buf, sizeof(buf), header_format2, "Routine", "Caller", "#Calls", "CPU Time" ); DaoStream_WriteChars( stream, buf ); DaoStream_WriteChars( stream, delimiter3 ); for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){ DNode *it2 = (DNode*) it->value.pVoid; DaoRoutine *callee = (DaoRoutine*) it2->key.pValue; DMap *profile = it2->value.pMap; DaoRoutine_MakeName( callee, name1, 30, 0, 0 ); DMap_Reset( summary2 ); for(it2=DMap_First(profile); it2; it2=DMap_Next(profile,it2)){ DaoRoutine *caller = (DaoRoutine*) it2->key.pValue; DaoComplex *data = (DaoComplex*) it2->value.pValue; com.value.real = - data->value.real; com.value.imag = - data->value.imag; DMap_Insert( summary2, & com, caller ); } for(it2=DMap_First(summary2); it2; it2=DMap_Next(summary2,it2)){ DaoRoutine *caller = (DaoRoutine*) it2->value.pValue; dao_complex data = it2->key.pValue->xComplex.value; DString_Reset( name2, 0 ); if( caller ) DaoRoutine_MakeName( caller, name2, 22, 0, 0 ); snprintf( buf, sizeof(buf), row_format2, name1->chars, name2->chars, (int) -data.imag, -data.real ); DaoStream_WriteChars( stream, buf ); DString_Reset( name1, 0 ); } if( count == 0 ) break; } DString_Delete( name1 ); DString_Delete( name2 ); }
/* // The layout of mixins in a host class: // 1. Each mixin occupies a continuous segment in the data arrays of the host. // The ranges of the segments are stored in DaoClass::ranges; // 2. If the mixin contains other mixins, those mixins occupy segments preceding // the segment for this mixin; // 3. The segments for the direct mixins of the host are arranged in the same // order as the mixins; // // For example, there are the following mixins: // class AA { var x = 1 } // class BB { var x = 1 } // class CC ( AA, BB ) { var x = 1 } // class DD ( CC, AA ) { var x = 1 } // The mixin layout for CC: // CC_Header, AA_Header, AA_Data, BB_Header, BB_Data, CC_Data // The mixin layout for DD: // DD_Header, AA_Header, AA_Data, BB_Header, BB_Data, CC_Header, CC_Data, DD_Data // // Where XX_Header are the data fields that are always placed at the header // of the data array. For example, XX_Header for class constants contains // two fields: one for the class itself, the other for the class constructor(s); // XX_Header for class static variables is empty; and XX_Header for class // instance variables contains only the field for the "self" variable. // And XX_Data constains the mixin's own data which are not from its // component mixins or from its paraent classes (actually only classes // without parent classes can be used as mixins). // // // To mix a mixin in the host class, the mixin (and its component mixins if any) // are properly arranged in the host class with layouts described above. // The non-trivial part is the update of variable types and the methods // that are added to the host class from the mixin. To update the types, // the type for the mixin are all replaced with the type for the host class. // // The update of methods involves three major steps: // 1. Update the routine signature type, local variable types and the static // variable types; // 2. Update the lookup table of the host class for the data from the mixins, // which is done by mapping the indices for the mixin data arrays to the // indices for the host data arrays; // 3. Update the method code (VM instructions) such that operands involving // class or class instance data are properly mapped from the indices for // the mixin data arrays to the indices for the host data arrays. */ static int DaoClass_MixIn( DaoClass *self, DaoClass *mixin, DMap *mixed, DaoMethodFields *mf ) { daoint i, j, k, id, bl = 1; DaoNamespace *ns = self->classRoutine->nameSpace; DArray *routines; DMap *deftypes; DMap *routmap; DMap *idmap; DNode *it; if( mixin->parent != NULL ) return 0; if( DMap_Find( mixed, mixin ) != NULL ) return 1; /* Mix the component mixins first: */ for(i=0; i<mixin->mixinBases->size; ++i){ DaoClass *mx = mixin->mixinBases->items.pClass[i]; bl = bl && DaoClass_MixIn( self, mx, mixed, mf ); } if( bl == 0 ) return 0; idmap = DMap_New(0,0); routmap = DMap_New(0,0); deftypes = DMap_New(0,0); routines = DArray_New(0); DMap_Insert( mixed, mixin, idmap ); DMap_Delete( idmap ); idmap = DMap_Find( mixed, mixin )->value.pMap; /* Add this mixin to the mixin list for both direct and indirect mixins: */ DArray_Append( self->mixins, mixin ); /* Save the starts of the ranges for this mixin in the host class: */ DVector_PushUshort( self->ranges, self->constants->size ); DVector_PushUshort( self->ranges, self->variables->size ); DVector_PushUshort( self->ranges, self->instvars->size ); /* For updating the types for the mixin to the types for the host class: */ DMap_Insert( deftypes, mixin->clsType, self->clsType ); DMap_Insert( deftypes, mixin->objType, self->objType ); #if 0 printf( "MixIn: %s %p %i\n", mixin->className->mbs, mixin, mixin->cstDataName->size ); #endif /* Add the own constants of the mixin to the host class: */ for(i=0; i<mixin->cstDataName->size; ++i){ daoint src = LOOKUP_BIND( DAO_CLASS_CONSTANT, 0, 0, i ); daoint des = LOOKUP_BIND( DAO_CLASS_CONSTANT, 0, 0, self->constants->size ); DString *name = mixin->cstDataName->items.pString[i]; DaoValue *value = mixin->constants->items.pConst[i]->value; DaoRoutine *rout = (DaoRoutine*) value; if( i >= mixin->cstMixinStart && i < mixin->cstMixinEnd2 ) continue; MAP_Insert( idmap, src, des ); /* Setup index mapping; */ DArray_Append( self->cstDataName, (void*) name ); if( value->type != DAO_ROUTINE || rout->routHost != mixin->objType ){ DaoConstant *cst = DaoConstant_New( value ); DArray_Append( self->constants, cst ); continue; } if( rout->overloads == NULL ){ DaoRoutine *old = rout; rout = DaoRoutine_Copy( rout, 1, 1, 1 ); bl = bl && DaoRoutine_Finalize( rout, self->objType, deftypes ); #if 0 printf( "%2i: %s %s\n", i, rout->routName->mbs, rout->routType->name->mbs ); #endif /* // Do not use DaoClass_AddConst() here, so that the original // method overloading structures will be mantained, without // interference from methods of other mixin component classes // or of the host class. */ it = DMap_Find( routmap, old ); if( it ) DRoutines_Add( it->value.pRoutine->overloads, rout ); DArray_Append( self->constants, DaoConstant_New( (DaoValue*) rout ) ); DArray_Append( routines, rout ); if( bl == 0 ) goto Finalize; }else{ /* No need to added the overloaded routines now; */ /* Each of them has an entry in constants, and will be handled later: */ DaoRoutine *routs = DaoRoutines_New( ns, self->objType, NULL ); routs->trait |= DAO_VALUE_CONST; DArray_Append( self->constants, DaoConstant_New( (DaoValue*) routs ) ); for(j=0; j<rout->overloads->routines->size; ++j){ DaoRoutine *R = rout->overloads->routines->items.pRoutine[j]; DMap_Insert( routmap, R, routs ); } } } for(i=mixin->glbMixinEnd2; i<mixin->glbDataName->size; ++i){ daoint src = LOOKUP_BIND( DAO_CLASS_VARIABLE, 0, 0, i ); daoint des = LOOKUP_BIND( DAO_CLASS_VARIABLE, 0, 0, self->variables->size ); DString *name = mixin->glbDataName->items.pString[i]; DaoValue *var = mixin->variables->items.pVar[i]->value; DaoType *type = mixin->variables->items.pVar[i]->dtype; type = DaoType_DefineTypes( type, ns, deftypes ); MAP_Insert( idmap, src, des ); DArray_Append( self->glbDataName, (void*) name ); DArray_Append( self->variables, DaoVariable_New( var, type ) ); } for(i=mixin->objMixinEnd2; i<mixin->objDataName->size; ++i){ daoint src = LOOKUP_BIND( DAO_OBJECT_VARIABLE, 0, 0, i ); daoint des = LOOKUP_BIND( DAO_OBJECT_VARIABLE, 0, 0, self->instvars->size ); DString *name = mixin->objDataName->items.pString[i]; DaoValue *var = mixin->instvars->items.pVar[i]->value; DaoType *type = mixin->instvars->items.pVar[i]->dtype; type = DaoType_DefineTypes( type, ns, deftypes ); MAP_Insert( idmap, src, des ); DArray_Append( self->objDataName, (void*) name ); DArray_Append( self->instvars, DaoVariable_New( var, type ) ); } /* Find the ends of own data of this mixin: */ DVector_PushUshort( self->ranges, self->constants->size ); DVector_PushUshort( self->ranges, self->variables->size ); DVector_PushUshort( self->ranges, self->instvars->size ); /* Update the lookup table: */ for(it=DMap_First(mixin->lookupTable); it; it=DMap_Next(mixin->lookupTable,it)){ int pm = LOOKUP_PM( it->value.pInt ); int st = LOOKUP_ST( it->value.pInt ); int up = LOOKUP_UP( it->value.pInt ); int id = LOOKUP_ID( it->value.pInt ); DaoValue *cst; /* Skip names from component mixins (because they have been handled): */ switch( st ){ case DAO_CLASS_CONSTANT : if( id >= mixin->cstMixinStart && id < mixin->cstMixinEnd2 ) continue; break; case DAO_CLASS_VARIABLE : if( id >= mixin->glbMixinStart && id < mixin->glbMixinEnd2 ) continue; break; case DAO_OBJECT_VARIABLE : if( id >= mixin->objMixinStart && id < mixin->objMixinEnd2 ) continue; break; } if( st != DAO_OBJECT_VARIABLE || id != 0 ){ /* not a "self": */ DNode *it2 = MAP_Find( idmap, LOOKUP_BIND( st, 0, 0, id ) ); if( it2 ) id = LOOKUP_ID( it2->value.pInt ); /* map index; */ } MAP_Insert( self->lookupTable, it->key.pString, LOOKUP_BIND( st, pm, up, id ) ); if( st != DAO_CLASS_CONSTANT ) continue; cst = self->constants->items.pConst[id]->value; if( cst->type != DAO_ROUTINE ) continue; DArray_Append( mf->names, it->key.pString ); DArray_Append( mf->perms, IntToPointer( pm ) ); DArray_Append( mf->routines, cst ); } for(i=0; i<routines->size; i++){ DaoRoutine *rout = routines->items.pRoutine[i]; DaoType **types; if( rout->body == NULL ) continue; //DaoRoutine_PrintCode( rout, rout->nameSpace->vmSpace->stdioStream ); types = rout->body->regType->items.pType; for(j=0; j<rout->body->annotCodes->size; ++j){ DaoVmCodeX *vmc = rout->body->annotCodes->items.pVmc[j]; DaoClass *klass; DString *name; switch( vmc->code ){ case DVM_GETCK: case DVM_GETCK_I: case DVM_GETCK_F: case DVM_GETCK_D: case DVM_GETCK_C: vmc->b = DaoClass_MapIndex( mixin, DAO_CLASS_CONSTANT, vmc->b, mixed ); break; case DVM_GETVK: case DVM_GETVK_I: case DVM_GETVK_F: case DVM_GETVK_D: case DVM_GETVK_C: case DVM_SETVK: case DVM_SETVK_II: case DVM_SETVK_FF: case DVM_SETVK_DD: case DVM_SETVK_CC: vmc->b = DaoClass_MapIndex( mixin, DAO_CLASS_VARIABLE, vmc->b, mixed ); break; case DVM_GETVO: case DVM_GETVO_I: case DVM_GETVO_F: case DVM_GETVO_D: case DVM_GETVO_C: case DVM_SETVO: case DVM_SETVO_II: case DVM_SETVO_FF: case DVM_SETVO_DD: case DVM_SETVO_CC: vmc->b = DaoClass_MapIndex( mixin, DAO_OBJECT_VARIABLE, vmc->b, mixed ); break; case DVM_GETF_KC: case DVM_GETF_KCI: case DVM_GETF_KCF: case DVM_GETF_KCD: case DVM_GETF_KCC: case DVM_GETF_OC: case DVM_GETF_OCI: case DVM_GETF_OCF: case DVM_GETF_OCD: case DVM_GETF_OCC: klass = (DaoClass*) types[ vmc->a ]->aux; name = DaoClass_GetDataName( klass, DAO_CLASS_CONSTANT, vmc->b ); vmc->b = DaoRoutine_GetFieldIndex( rout, name ); vmc->code = DVM_GETF; break; case DVM_GETF_KG: case DVM_GETF_KGI: case DVM_GETF_KGF: case DVM_GETF_KGD: case DVM_GETF_KGC: case DVM_GETF_OG: case DVM_GETF_OGI: case DVM_GETF_OGF: case DVM_GETF_OGD: case DVM_GETF_OGC: klass = (DaoClass*) types[ vmc->a ]->aux; name = DaoClass_GetDataName( klass, DAO_CLASS_VARIABLE, vmc->b ); vmc->b = DaoRoutine_GetFieldIndex( rout, name ); vmc->code = DVM_GETF; break; case DVM_GETF_OV: case DVM_GETF_OVI: case DVM_GETF_OVF: case DVM_GETF_OVD: case DVM_GETF_OVC: klass = (DaoClass*) types[ vmc->a ]->aux; name = DaoClass_GetDataName( klass, DAO_OBJECT_VARIABLE, vmc->b ); vmc->b = DaoRoutine_GetFieldIndex( rout, name ); vmc->code = DVM_GETF; break; case DVM_SETF_KG: case DVM_SETF_KGII: case DVM_SETF_KGFF: case DVM_SETF_KGDD: case DVM_SETF_KGCC: case DVM_SETF_OG: case DVM_SETF_OGII: case DVM_SETF_OGFF: case DVM_SETF_OGDD: case DVM_SETF_OGCC: klass = (DaoClass*) types[ vmc->c ]->aux; name = DaoClass_GetDataName( klass, DAO_CLASS_VARIABLE, vmc->b ); vmc->b = DaoRoutine_GetFieldIndex( rout, name ); vmc->code = DVM_SETF; break; case DVM_SETF_OV: case DVM_SETF_OVII: case DVM_SETF_OVFF: case DVM_SETF_OVDD: case DVM_SETF_OVCC: klass = (DaoClass*) types[ vmc->c ]->aux; name = DaoClass_GetDataName( klass, DAO_OBJECT_VARIABLE, vmc->b ); vmc->b = DaoRoutine_GetFieldIndex( rout, name ); vmc->code = DVM_SETF; break; } } //DaoRoutine_PrintCode( rout, rout->nameSpace->vmSpace->stdioStream ); bl = bl && DaoRoutine_DoTypeInference( rout, 0 ); if( bl == 0 ) goto Finalize; } Finalize: DArray_Delete( routines ); DMap_Delete( routmap ); DMap_Delete( deftypes ); return bl; }
void STD_Debug( DaoProcess *proc, DaoValue *p[], int N ) { DaoUserHandler *handler = proc->vmSpace->userHandler; DaoRoutine *routine = proc->activeRoutine; DaoStream *stream = proc->vmSpace->stdioStream; DString *input; DArray *tokens; DMap *cycData; char *chs, *cmd; int i; if( ! (proc->vmSpace->options & DAO_OPTION_DEBUG ) ) return; input = DString_New(1); if( N > 0 && DaoValue_CastCstruct( p[0], dao_type_stream ) ){ stream = (DaoStream*)p[0]; p ++; N --; } if( N > 0 ){ Dao_AboutVars( proc->activeNamespace, p, N, input ); DaoStream_WriteString( stream, input ); DaoStream_WriteMBS( stream, "\n" ); DString_Delete( input ); return; } if( handler && handler->StdlibDebug ){ handler->StdlibDebug( handler, proc ); return; } tokens = DArray_New(D_STRING); cycData = DMap_New(0,0); while(1){ if( proc->vmSpace->ReadLine ){ chs = proc->vmSpace->ReadLine( "(debug) " ); if( chs ){ DString_SetMBS( input, chs ); DString_Trim( input ); if( input->size && proc->vmSpace->AddHistory ) proc->vmSpace->AddHistory( chs ); dao_free( chs ); } }else{ DaoStream_WriteMBS( stream, "(debug) " ); DaoStream_ReadLine( stream, input ); } if( input->size == 0 ) continue; SplitByWhiteSpaces( input->mbs, tokens ); if( tokens->size == 0 ) continue; cmd = tokens->items.pString[0]->mbs; if( strcmp( cmd, "q" ) == 0 || strcmp( cmd, "quit" ) == 0 ){ break; }else if( strcmp( cmd, "k" ) == 0 || strcmp( cmd, "kill" ) == 0 ){ proc->status = DAO_PROCESS_ABORTED; break; }else if( strcmp( cmd, "a" ) == 0 || strcmp( cmd, "about" ) == 0 ){ if( tokens->size > 1 ){ ushort_t reg = (ushort_t)strtod( tokens->items.pString[1]->mbs, 0 ); DaoType *tp = proc->activeTypes[ reg ]; DString_Clear( input ); Dao_AboutVar( proc->activeNamespace, proc->activeValues[reg], input ); DaoStream_WriteMBS( stream, "type: " ); if( tp ) DaoStream_WriteString( stream, tp->name ); else DaoStream_WriteMBS( stream, "?" ); DaoStream_WriteMBS( stream, ", value: " ); DaoStream_WriteString( stream, input ); DaoStream_WriteMBS( stream, "\n" ); } }else if( strcmp( cmd, "g" ) == 0 || strcmp( cmd, "goto" ) == 0 ){ if( tokens->size > 1 ){ int n = atoi( tokens->items.pString[1]->mbs ); int entry = proc->activeCode - proc->activeRoutine->body->vmCodes->data.codes; if( n < 0 ) n = entry - n; if( n >= routine->body->vmCodes->size ) n = routine->body->vmCodes->size -1; proc->topFrame->entry = n; proc->status = DAO_PROCESS_STACKED; return; } }else if( strcmp( cmd, "h" ) == 0 || strcmp( cmd, "help" ) == 0 ){ DaoStream_WriteMBS( stream, help ); }else if( strcmp( cmd, "l" ) == 0 || strcmp( cmd, "list" ) == 0 ){ DString *mbs = DString_New(1); int entry = proc->activeCode - proc->activeRoutine->body->vmCodes->data.codes; int start = entry - 10; int end = entry; if( tokens->size >1 ){ int dn = atoi( tokens->items.pString[1]->mbs ); if( dn < 0 ){ start = entry + dn; }else if( dn > 0 ){ start = entry; end = entry + dn; } } if( start < 0 ) start = 0; if( end >= routine->body->vmCodes->size ) end = routine->body->vmCodes->size - 1; DaoStream_WriteString( stream, routine->routName ); DaoStream_WriteMBS( stream, "(): " ); if( routine->routType ) DaoStream_WriteString( stream, routine->routType->name ); DaoStream_WriteMBS( stream, "\n" ); DaoStream_WriteMBS( stream, daoRoutineCodeHeader ); DaoStream_WriteMBS( stream, sep ); for( i=start; i<=end; i++ ){ DaoRoutine_FormatCode( routine, i, *routine->body->annotCodes->items.pVmc[i], mbs ); DaoStream_WriteString( stream, mbs ); } DString_Delete( mbs ); }else if( strcmp( cmd, "p" ) == 0 || strcmp( cmd, "print" ) == 0 ){ if( tokens->size > 1 ){ ushort_t reg = (ushort_t)atoi( tokens->items.pString[1]->mbs ); DaoValue_Print( proc->activeValues[reg], proc, stream, cycData ); DaoStream_WriteMBS( stream, "\n" ); } }else if( strcmp( cmd, "t" ) == 0 || strcmp( cmd, "trace" ) == 0 ){ int depth = 1; if( tokens->size >1 ) depth = atoi( tokens->items.pString[1]->mbs ); DaoProcess_Trace( proc, depth ); }else{ DaoStream_WriteMBS( stream, "Unknown debugging command.\n" ); } } DString_Delete( input ); DArray_Delete( tokens ); }
void DaoNamespace_Restore( DaoNamespace *self, DaoProcess *proc, FILE *fin ) { DaoParser *parser = DaoParser_New(); DString *line = DString_New(1); DArray *types = DArray_New(0); DArray *tokens = parser->tokens; DMap *omap = DMap_New(0,0); DString *name; DNode *node; parser->nameSpace = self; parser->vmSpace = self->vmSpace; while( DaoFile_ReadLine( fin, line ) ){ DaoValue *value = NULL; int st = DAO_GLOBAL_VARIABLE; int pm = DAO_DATA_PRIVATE; int i, n, start = 0; char *mbs; DaoParser_LexCode( parser, line->mbs, 0 ); if( tokens->size == 0 ) continue; name = & tokens->items.pToken[start]->string; if( name->size == 6 && strcmp( name->mbs, "inputs" ) == 0 ){ if( tokens->size < 3 ) continue; DString_Clear( line ); n = tokens->items.pToken[start+2]->string.size; mbs = tokens->items.pToken[start+2]->string.mbs; for(i=0; i<n; i++){ char c1 = mbs[i]; char c2 = mbs[i+1]; if( c1 < 'A' || c1 > 'P' ) continue; DString_AppendChar( line, (char)((c1-'A')*16 + (c2-'A')) ); i += 1; } /* printf( "%s\n", line->mbs ); */ DaoProcess_Eval( proc, self, line->mbs ); continue; } switch( tokens->items.pToken[start]->name ){ case DKEY_PRIVATE : pm = DAO_DATA_PRIVATE; start += 1; break; case DKEY_PROTECTED : pm = DAO_DATA_PROTECTED; start += 1; break; case DKEY_PUBLIC : pm = DAO_DATA_PUBLIC; start += 1; break; } if( start >= tokens->size ) continue; switch( tokens->items.pToken[start]->name ){ case DKEY_CONST : st = DAO_GLOBAL_CONSTANT; start += 1; break; case DKEY_VAR : st = DAO_GLOBAL_VARIABLE; start += 1; break; } if( tokens->items.pToken[start]->name != DTOK_IDENTIFIER ) continue; name = & tokens->items.pToken[start]->string; start += 1; if( start + 3 >= tokens->size ) continue; if( tokens->items.pToken[start]->name != DTOK_ASSN ) continue; start += 1; DArray_Clear( parser->errors ); DArray_Clear( types ); DArray_PushFront( types, NULL ); DaoParser_Deserialize( parser, start, tokens->size-1, &value, types, self, proc, omap ); if( value == NULL ) continue; node = DMap_Find( self->lookupTable, name ); if( node ) continue; if( st == DAO_GLOBAL_CONSTANT ){ DaoNamespace_AddConst( self, name, value, pm ); }else{ DaoNamespace_AddVariable( self, name, value, NULL, pm ); } } DMap_Delete( omap ); DString_Delete( line ); DArray_Delete( types ); DaoParser_Delete( parser ); }
int DaoParser_MacroTransform( DaoParser *self, DaoMacro *macro, int start, int tag ) { DString *mbs = DString_New(1); DArray *toks = DArray_New(D_TOKEN); DArray *all = DArray_New(0); DMap *tokMap = DMap_New(D_STRING,0); DMap *used = DMap_New(0,D_MAP); DNode *it; daoint i; int j, p0, lev = 0, adjust=0; int indent[10]; char buf[20]; sprintf( buf, " %p %x", self->nameSpace, tag ); DString_SetMBS( mbs, buf ); for(i=0; i<10; i++) indent[i] = -1; j = DaoParser_MacroMatch( self, start, self->tokens->size, macro->macroMatch, tokMap, lev, all, indent ); /* printf( "MacroTransform %i\n", j ); */ if( j <0 ) goto Failed; for( it = DMap_First( tokMap ); it != NULL; it = DMap_Next( tokMap, it ) ){ DMacroNode *node = (DMacroNode*) it->value.pVoid; while( node->parent ) node = node->parent; it->value.pVoid = node; } lev = 0; p0 = self->tokens->items.pToken[start]->line; adjust = self->tokens->items.pToken[start]->cpos - macro->macroApply->cpos; if( DaoParser_MacroApply( self, toks, macro->macroApply, tokMap, used, lev, mbs, p0, adjust ) <0 ) goto Failed; /* for(i=0; i<toks->size; i++) printf( "%s ", toks->items.pToken[i]->string.mbs ); printf( "\n" ); */ DArray_Erase( self->tokens, start, j-start ); DArray_InsertArray( self->tokens, start, toks, 0, -1 ); /* for(i=0; i<toks->size; i++){ DArray_Insert( self->tokStr, (void*)toks->items.pString[i], start+i ); DArray_Insert( self->tokPos, (void*)poss->items.pInt[i], start+i ); } */ j = toks->size; DString_Delete( mbs ); for(i=0; i<all->size; i++) DMacroNode_Delete( (DMacroNode*) all->items.pVoid[i] ); DArray_Delete( all ); DArray_Delete( toks ); DMap_Delete( tokMap ); DMap_Delete( used ); return start + j; Failed : DString_Delete( mbs ); for(i=0; i<all->size; i++) DMacroNode_Delete( (DMacroNode*) all->items.pVoid[i] ); DArray_Delete( all ); DArray_Delete( toks ); DMap_Delete( tokMap ); DMap_Delete( used ); return -1; }
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; }
/* // C printf format: %[parameter][flags][width][.precision][length]type // // Dao writef format: %[parameter][flags][width][.precision]type[color] // // Where 'parameter', 'flags', 'width' and 'precision' will conform to the // C format, but 'type' can only be: // c, d, i, o, u, x/X : for integer; // e/E, f/F, g/G : for float and double; // s : for string; // p : for any type, write address; // a : automatic, for any type, write in the default format; // Namely the standard ones exception 'n', and plus 'a'. // // Optional 'color' format will be in form of: [foreground:background], [foreground] // or [:background]. The supported color name format will depend on the color printing // handle. Mininum requirement is the support of the following 8 color names: // black, white, red, green, blue, yellow, magenta, cyan. */ static void DaoIO_Writef0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *value; DMap *cycData; DString *format, *fmt2; DString *fgcolor, *bgcolor; const char *convs = "aspcdiouxXfFeEgG"; char F, *s, *end, *fg, *bg, *fmt, message[100]; int k, id = 1; if( (self->attribs & (DAO_IO_FILE | DAO_IO_PIPE)) && self->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not open!" ); return; } cycData = DMap_New(0,0); fmt2 = DString_New(1); fgcolor = DString_New(1); bgcolor = DString_New(1); format = DString_Copy( p[0]->xString.data ); DString_ToMBS( format ); s = format->mbs; end = s + format->size; for(; s<end; s++){ k = 0; if( *s =='%' ){ fmt = s; s += 1; if( *s =='%' || *s == '[' ){ DaoStream_WriteChar( self, *s ); continue; } if( isdigit( *s ) && (*s > '0') ){ while( isdigit( *s ) ) s += 1; if( *s == '$' ){ /* parameter: number$ */ *s = '\0'; k = strtol( fmt + 1, NULL, 10 ); if( k == 0 || k >= N ){ DaoProcess_RaiseException( proc, DAO_WARNING, "invalid parameter number" ); } *s = '%'; fmt = s ++; } } /* flags: */ while( *s == '+' || *s == '-' || *s == '#' || *s == '0' || *s == ' ' ) s += 1; while( isdigit( *s ) ) s += 1; /* width; */ if( *s == '.' ){ /* precision: */ s += 1; while( isdigit( *s ) ) s += 1; } DString_SetDataMBS( fmt2, fmt, s - fmt + 1 ); if( strchr( convs, *s ) == NULL ){ DaoProcess_RaiseException( proc, DAO_WARNING, "invalid format conversion" ); continue; } F = *s; s += 1; fg = bg = NULL; if( *s == '[' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; DString_SetDataMBS( fgcolor, fmt, s - fmt ); if( fgcolor->size ) fg = fgcolor->mbs; if( *s == ':' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; DString_SetDataMBS( bgcolor, fmt, s - fmt ); if( bgcolor->size ) bg = bgcolor->mbs; } if( *s != ']' ) DaoProcess_RaiseException( proc, DAO_WARNING, "invalid color format" ); }else{ s -= 1; } if( k == 0 ) k = id; value = p[k]; id += 1; if( fg || bg ) DaoStream_SetColor( self, fg, bg ); self->format = fmt2->mbs; if( value == NULL ){ if( F == 'p' ){ DaoStream_WriteMBS( self, "0x0" ); }else{ DaoProcess_RaiseException( proc, DAO_WARNING, "null parameter" ); } } self->format = fmt2->mbs; if( F == 'c' || F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){ if( sizeof(daoint) != 4 ) DString_InsertChar( fmt2, DAO_INT_FORMAT[0], fmt2->size-1 ); self->format = fmt2->mbs; if( value->type == DAO_INTEGER ){ DaoStream_WriteInt( self, value->xInteger.value ); }else{ goto WrongParameter; } }else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){ if( value->type == DAO_FLOAT ){ DaoStream_WriteFloat( self, value->xFloat.value ); }else if( value->type == DAO_DOUBLE ){ DaoStream_WriteFloat( self, value->xDouble.value ); }else{ goto WrongParameter; } }else if( F == 's' && value->type == DAO_STRING ){ DaoStream_WriteString( self, value->xString.data ); }else if( F == 'p' ){ DaoStream_WritePointer( self, value ); }else if( F == 'a' ){ self->format = NULL; DaoValue_Print( value, proc, self, cycData ); }else{ goto WrongParameter; } self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); continue; WrongParameter: self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", k, fmt2->mbs ); DaoProcess_RaiseException( proc, DAO_WARNING, message ); }else{ DaoStream_WriteChar( self, *s ); } } DString_Delete( fgcolor ); DString_Delete( bgcolor ); DString_Delete( format ); DString_Delete( fmt2 ); DMap_Delete( cycData ); }
int DaoParser_ParseMacro( DaoParser *self, int start ) { int rb1, rb2, i = start, N = self->tokens->size; DaoToken **toks = self->tokens->items.pToken; DaoMacro *macro; DString *lang = NULL; DArray *stops; DMap *markers; if( start + 5 >= N ) return -1; if( toks[start+1]->type != DTOK_LCB ){ lang = & toks[start+1]->string; if( toks[start+1]->type != DTOK_IDENTIFIER ){ DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang ); return -1; } if( lang->size == 3 && strcmp( lang->mbs, "dao" ) == 0 ){ DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang ); return -1; } start += 1; } if( toks[start+1]->name != DTOK_LCB ) return -1; self->curLine = toks[start]->line; rb1 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, -1 ); if( rb1 <0 || rb1 +3 >= N ) return -1; if( toks[rb1+1]->name != DKEY_AS || toks[rb1+2]->name != DTOK_LCB ){ DaoParser_Error( self, DAO_CTW_INV_MAC_DEFINE, NULL ); return -1; } rb2 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, rb1 + 1, -1 ); if( rb2 <0 ) return -1; /* for( i=start; i<rb2; i++ ) printf( "%s ", toks[i]->string.mbs ); printf("\n"); */ macro = DaoMacro_New(); if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1 ) ==0 ){ DaoMacro_Delete( macro ); return -1; } if( macro->macroMatch->units->size >0 ){ DMacroUnit *unit = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0]; if( unit->type != DMACRO_TOK ) DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string ); } if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos; if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2 ) ==0 ){ DaoMacro_Delete( macro ); return -1; } markers = DMap_New(D_STRING,0); for(i=start+2; i<rb1; i++){ if( toks[i]->string.mbs[0] == '$' ){ if( MAP_Find( markers, & toks[i]->string ) != NULL ){ self->curLine = toks[i]->line; DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, & toks[i]->string ); return 0; } MAP_Insert( markers, & toks[i]->string, 0 ); } } DMap_Clear( markers ); i = rb1+3; if( DString_EQ( & toks[start+2]->string, & toks[rb1+3]->string ) ) i ++; while( i < rb2 ){ char ch = toks[i]->string.mbs[0]; if( ch != '$' && ch != '\\' && ch != '\'' ){ if( MAP_Find( markers, & toks[i]->string ) == NULL ){ DArray_Append( macro->keyListApply, & toks[i]->string ); MAP_Insert( markers, & toks[i]->string, 0 ); } } i ++; } stops = DArray_New(D_TOKEN); DMacroGroup_SetStop( macro->macroMatch, stops ); DMacroGroup_FindVariables( macro->macroMatch ); DArray_Clear( stops ); DMacroGroup_SetStop( macro->macroApply, stops ); DaoNamespace_AddMacro( self->nameSpace, lang, & toks[start+2]->string, macro ); DArray_Delete( stops ); DMap_Delete( markers ); return rb2; }