void DaoTaskEvent_Reset( DaoTaskEvent *self ) { self->type = 0; self->state = 0; self->timeout = 0; self->expiring = -1.0; GC_DecRC( self->future ); GC_DecRC( self->channel ); self->future = NULL; self->channel = NULL; if( self->channels ) DArray_Delete( self->channels ); self->channels = NULL; }
static void DaoCallServer_Delete( DaoCallServer *self ) { daoint i; for(i=0; i<self->threads->size; i++){ DaoCallThread_Delete( (DaoCallThread*)self->threads->items.pVoid[i] ); } for(i=0; i<self->caches->size; ++i){ DaoTaskEvent_Delete( (DaoTaskEvent*) self->caches->items.pVoid[i] ); } DArray_Delete( self->threads ); DArray_Delete( self->functions ); DArray_Delete( self->parameters ); DArray_Delete( self->events ); DArray_Delete( self->events2 ); DMap_Delete( self->waitings ); DMap_Delete( self->pending ); DMap_Delete( self->active ); DMutex_Destroy( & self->mutex ); DCondVar_Destroy( & self->condv ); DCondVar_Destroy( & self->condv2 ); DThread_Destroy( & self->timer ); dao_free( self ); }
static void DArray_DeleteItems( DArray *self, daoint M, daoint N ) { daoint i; switch( self->type ){ case DAO_DATA_VALUE : for(i=M; i<N; i++) GC_DecRC( self->items.pValue[i] ); break; case DAO_DATA_VMCODE : for(i=M; i<N; i++) DaoVmCodeX_Delete( self->items.pVmc[i] ); break; case DAO_DATA_TOKEN : for(i=M; i<N; i++) DaoToken_Delete( self->items.pToken[i] ); break; case DAO_DATA_STRING : for(i=M; i<N; i++) DString_Delete( self->items.pString[i] ); break; case DAO_DATA_VECTOR : for(i=M; i<N; i++) DVector_Delete( self->items.pVector[i] ); break; case DAO_DATA_ARRAY : for(i=M; i<N; i++) DArray_Delete( self->items.pArray[i] ); break; case DAO_DATA_MAP : for(i=M; i<N; i++) DMap_Delete( self->items.pMap[i] ); break; default : break; } }
static int DaoxDataFrame_SetArray( DaoxDataFrame *self, DaoArray *array ) { DaoValue value = {0}; DArray *destSlices = self->slices; DArray *fromSlices = array->slices; DArray *fromSlices2 = array->slices; daoint i, j, k, N, M, K; if( DaoxDataFrame_AlignArray( self, array ) == 0 ) return DAOX_DF_WRONG_SHAP; if( self->original == NULL ){ DaoxDataFrame_PrepareSlices( self ); DaoxDataFrame_MakeFullSlice( self, self->slices ); destSlices = self->slices; }else{ self = self->original; } if( array->original == NULL ){ fromSlices = DArray_New(D_VECTOR); DaoArray_MakeFullSlice( array, fromSlices ); }else{ array = array->original; } N = destSlices->items.pVector[0]->data.daoints[1]; M = destSlices->items.pVector[1]->data.daoints[1]; K = destSlices->items.pVector[2]->data.daoints[1]; for(j=0; j<M; ++j){ daoint jjdes = DaoSlice_GetIndex( destSlices->items.pVector[1], j ); daoint jjsrc = DaoSlice_GetIndex( fromSlices->items.pVector[1], j ); DaoxDataColumn *column = (DaoxDataColumn*) self->columns->items.pVoid[jjdes]; for(i=0; i<N; ++i){ daoint iides = DaoSlice_GetIndex( destSlices->items.pVector[0], i ); daoint iisrc = DaoSlice_GetIndex( fromSlices->items.pVector[0], i ); for(k=0; k<K; ++k){ daoint kkdes = DaoSlice_GetIndex( destSlices->items.pVector[2], k ); daoint kksrc = DaoSlice_GetIndex( fromSlices->items.pVector[2], k ); daoint idsrc = iisrc * M * K + jjsrc * K + kksrc; daoint iddes = kkdes * N + iides; DaoArray_GetValue( array, idsrc, & value ); DaoxDataColumn_SetCell( column, iddes, & value ); } } } if( fromSlices != fromSlices2 ) DArray_Delete( fromSlices ); return 0; }
void DString_ToUpper( DString *self ) { daoint i; char *bytes; DArray *wcs; DString_Detach( self, self->size ); if( DString_IsASCII( self ) ){ for(i=0,bytes=self->chars; i<self->size; i++, bytes++) *bytes = toupper( *bytes ); return; } wcs = DArray_New( sizeof(wchar_t) ); DString_DecodeUTF8( self, wcs ); self->size = 0; for(i=0; i<wcs->size; ++i){ DString_AppendWChar( self, towupper( wcs->data.wchars[i] ) ); } DArray_Delete( wcs ); }
void DaoxAnimation_Delete( DaoxAnimation *self ) { DArray_Delete( self->keyFrames ); DaoCstruct_Free( (DaoCstruct*) self ); dao_free( self ); }
int DaoClass_CopyField( DaoClass *self, DaoClass *other, DMap *deftypes ) { DaoNamespace *ns = other->classRoutine->nameSpace; DaoType *tp; DArray *offsets = DArray_New(0); DArray *routines = DArray_New(0); DNode *it; int i, k, st, up, id; for(i=0; i<other->superClass->size; i++){ DaoValue *sup = other->superClass->items.pValue[i]; if( sup->type == DAO_CLASS && sup->xClass.typeHolders ){ tp = DaoType_DefineTypes( sup->xClass.objType, ns, deftypes ); DArray_Append( self->superClass, tp->aux ); }else if( sup->type == DAO_CTYPE && sup->xCtype.ctype->typer->core->kernel->sptree ){ tp = DaoType_DefineTypes( sup->xCtype.ctype, ns, deftypes ); DArray_Append( self->superClass, tp->aux ); }else{ DArray_Append( self->superClass, sup ); } } DaoRoutine_CopyFields( self->classRoutine, other->classRoutine, 1, 1 ); for(it=DMap_First(other->lookupTable);it;it=DMap_Next(other->lookupTable,it)){ st = LOOKUP_ST( it->value.pInt ); up = LOOKUP_UP( it->value.pInt ); id = LOOKUP_ID( it->value.pInt ); if( up ==0 ){ if( st == DAO_CLASS_CONSTANT && id <self->constants->size ) continue; if( st == DAO_CLASS_VARIABLE && id <self->variables->size ) continue; if( st == DAO_OBJECT_VARIABLE && id <self->instvars->size ) continue; } DMap_Insert( self->lookupTable, it->key.pVoid, it->value.pVoid ); } for(i=self->objDataName->size; i<other->objDataName->size; i++) DArray_Append( self->objDataName, other->objDataName->items.pString[i] ); for(i=self->cstDataName->size; i<other->cstDataName->size; i++) DArray_Append( self->cstDataName, other->cstDataName->items.pString[i] ); for(i=self->glbDataName->size; i<other->glbDataName->size; i++) DArray_Append( self->glbDataName, other->glbDataName->items.pString[i] ); for(i=self->variables->size; i<other->variables->size; i++){ DaoVariable *var = other->variables->items.pVar[i]; var = DaoVariable_New( var->value, DaoType_DefineTypes( var->dtype, ns, deftypes ) ); DArray_Append( self->variables, var ); } for(i=self->instvars->size; i<other->instvars->size; i++){ DaoVariable *var = other->instvars->items.pVar[i]; var = DaoVariable_New( var->value, DaoType_DefineTypes( var->dtype, ns, deftypes ) ); DArray_Append( self->instvars, var ); /* TODO fail checking */ } for(i=self->constants->size; i<other->constants->size; i++){ DaoValue *value = other->constants->items.pConst[i]->value; DaoRoutine *rout = & value->xRoutine; if( value->type == DAO_ROUTINE && rout->overloads == NULL && rout->routHost == other->objType ){ DString *name = rout->routName; rout = DaoRoutine_Copy( rout, 1, 1 ); value = (DaoValue*) rout; k = DaoRoutine_Finalize( rout, self->objType, deftypes ); #if 0 printf( "%i %p: %s %s\n", i, rout, rout->routName->mbs, rout->routType->name->mbs ); #endif if( rout->attribs & DAO_ROUT_INITOR ){ DRoutines_Add( self->classRoutines->overloads, rout ); }else if( (it = DMap_Find( other->lookupTable, name )) ){ st = LOOKUP_ST( it->value.pInt ); up = LOOKUP_UP( it->value.pInt ); id = LOOKUP_ID( it->value.pInt ); if( st == DAO_CLASS_CONSTANT && up ==0 && id < i ){ DaoValue *v = self->constants->items.pConst[id]->value; if( v->type == DAO_ROUTINE && v->xRoutine.overloads ) DRoutines_Add( v->xRoutine.overloads, rout ); } } DArray_Append( self->constants, DaoConstant_New( value ) ); DArray_Append( routines, rout ); if( k == 0 ) goto Failed; continue; }else if( value->type == DAO_ROUTINE ){ /* 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 ); DArray_Append( self->constants, DaoConstant_New( (DaoValue*) routs ) ); continue; } DArray_Append( self->constants, DaoConstant_New( value ) ); DaoValue_Update( & self->constants->items.pConst[i]->value, ns, deftypes ); } for(i=0; i<routines->size; i++){ if( DaoRoutine_DoTypeInference( routines->items.pRoutine[i], 0 ) == 0 ) goto Failed; } DArray_Delete( offsets ); DArray_Delete( routines ); DaoRoutine_Finalize( self->classRoutine, self->objType, deftypes ); return DaoRoutine_DoTypeInference( self->classRoutine, 0 ); Failed: DArray_Delete( offsets ); DArray_Delete( routines ); return 0; }
static void DaoChannel_Delete( DaoChannel *self ) { DaoCstruct_Free( (DaoCstruct*) self ); DArray_Delete( self->buffer ); dao_free( self ); }
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 DCondVar_Destroy( DCondVar *self ) { DArray_Delete( self->thdWaiting ); DMutex_Destroy( & self->thdMutex ); CloseHandle( self->myCondVar ); }
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 ); }
void DaoClass_Delete( DaoClass *self ) { GC_DecRC( self->clsType ); DMap_Delete( self->abstypes ); DMap_Delete( self->lookupTable ); DMap_Delete( self->ovldRoutMap ); DArray_Delete( self->constants ); DArray_Delete( self->variables ); DArray_Delete( self->instvars ); DArray_Delete( self->objDataName ); DArray_Delete( self->cstDataName ); DArray_Delete( self->glbDataName ); DArray_Delete( self->allBases ); DArray_Delete( self->mixinBases ); DArray_Delete( self->mixins ); DVector_Delete( self->ranges ); DVector_Delete( self->offsets ); DArray_Delete( self->references ); if( self->decoTargets ) DArray_Delete( self->decoTargets ); DString_Delete( self->className ); dao_free( self ); }
static int DaoParser_MacroApply( DaoParser *self, DArray *tokens, DMacroGroup *group, DMap *tokMap, DMap *used, int level, DString *tag, int pos0, int adjust ) { DMacroUnit **units = (DMacroUnit**) group->units->items.pVoid; DMacroUnit *unit; DMacroGroup *grp; DMacroNode *node, *node2; DArray *toks = DArray_New(D_TOKEN); DaoToken *tk = DaoToken_New(); DaoToken *tt = NULL; DNode *kwnode = NULL; DMap *check = NULL; DMap one = { NULL, 0, 0, 0 }; int M, N = group->units->size; int i, j, gid = -1; int repeated = 0; int start_mbs = -1; int start_wcs = -1; int squote, dquote; if( group->repeat != DMACRO_AUTO ) level ++; for( i=0; i<N; i++ ){ unit = units[i]; if( tokens->size >0 ) pos0 = tokens->items.pToken[ tokens->size -1 ]->line; self->curLine = pos0; /* printf( "apply unit %i: %i\n", i, unit->type ); */ switch( unit->type ){ case DMACRO_TOK : squote = unit->marker->type == DTOK_ESC_SQUO; dquote = unit->marker->type == DTOK_ESC_DQUO; if( (squote && start_mbs >=0) || (dquote && start_wcs >=0) ){ int qstart = squote ? start_mbs : start_wcs; tt = tokens->items.pToken[ qstart ]; for(j=qstart+1,M=tokens->size; j<M; j++){ DaoToken *jtok = tokens->items.pToken[j]; int t = j ? tokens->items.pToken[j-1]->type : 0; if( t == DTOK_IDENTIFIER && jtok->type == t ) DString_AppendChar( & tt->string, ' ' ); DString_Append( & tt->string, & jtok->string ); } if( squote ){ DString_AppendChar( & tt->string, '\'' ); DArray_Erase( tokens, start_mbs+1, tokens->size ); }else{ DString_AppendChar( & tt->string, '\"' ); DArray_Erase( tokens, start_wcs+1, tokens->size ); } start_mbs = -1; break; }else if( squote ){ start_mbs = tokens->size; DArray_Append( tokens, unit->marker ); tt = tokens->items.pToken[ start_mbs ]; tt->type = tt->name = DTOK_MBS; DString_SetMBS( & tt->string, "\'" ); break; }else if( dquote ){ start_wcs = tokens->size; DArray_Append( tokens, unit->marker ); tt = tokens->items.pToken[ start_wcs ]; tt->type = tt->name = DTOK_WCS; DString_SetMBS( & tt->string, "\"" ); break; } DArray_Append( tokens, unit->marker ); tokens->items.pToken[ tokens->size-1 ]->cpos += adjust; break; case DMACRO_VAR : DaoToken_Assign( tk, unit->marker ); DString_Append( & tk->string, tag ); DArray_Append( tokens, tk ); break; case DMACRO_EXP : case DMACRO_ID : case DMACRO_OP : case DMACRO_BL : case DMACRO_IBL : kwnode = MAP_Find( tokMap, & unit->marker->string ); if( kwnode ==NULL ){ DaoParser_Error( self, DAO_CTW_UNDEF_MAC_MARKER, & unit->marker->string ); goto Failed; } node = (DMacroNode*) kwnode->value.pVoid; kwnode = MAP_Find( used, unit ); if( kwnode == NULL ){ DMap_Insert( used, unit, & one ); kwnode = MAP_Find( used, unit ); } check = (DMap*) kwnode->value.pVoid; repeated = 1; /* printf( ">>>\n%s level %i: \n", unit->marker->string.mbs, level ); DMacroNode_Print( node ); printf( "\n" ); */ /* search a leaf */ node2 = DMacroNode_FindLeaf( node, check, level ); if( node2 ){ /* printf( "appending tokens\n" ); DMacroNode_Print( node2 ); printf( "\n" ); */ DArray_InsertArray( tokens, tokens->size, node2->leaves, 0, -1 ); DMap_Insert( check, node2, NULL ); /* DArray_Clear( node2->leaves ); */ }else{ DMacroNode_RemoveEmptyLeftBranch( node, level ); goto Failed; } break; case DMACRO_GRP : case DMACRO_ALT : grp = (DMacroGroup*) unit; DArray_Clear( toks ); j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust ); switch( grp->repeat ){ case DMACRO_AUTO : case DMACRO_ONE : if( j <0 && group->type != DMACRO_ALT ) goto Failed; repeated = (j>0); if( j >=0 ){ gid = i; DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } break; case DMACRO_ZERO_OR_ONE : gid = i; repeated = (j>0); if( j >=0 ){ DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } break; case DMACRO_ZERO_OR_MORE : gid = i; repeated = (j>0); if( j >=0 ){ DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } while( j >0 ){ DArray_Clear( toks ); j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust ); if( j >0 ){ DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } } break; case DMACRO_ONE_OR_MORE : if( j <0 && group->type != DMACRO_ALT ) goto Failed; repeated = (j>0); if( j >=0 ){ DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } while( j >0 ){ gid = i; DArray_Clear( toks ); j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust ); if( j >0 ){ DArray_InsertArray( tokens, tokens->size, toks, 0, -1 ); } } break; } break; default : goto Failed; } if( group->type == DMACRO_ALT && gid >=0 ) break; } if( group->repeat != DMACRO_AUTO ) level --; if( group->type == DMACRO_ALT && gid <0 ) goto Failed; DaoToken_Delete( tk ); DArray_Delete( toks ); return repeated; Failed : DaoToken_Delete( tk ); DArray_Delete( toks ); return -1; }
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; }
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; }
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; }
void DMacroUnit_Delete( DMacroUnit *self ) { DArray_Delete( self->stops ); DaoToken_Delete( self->marker ); dao_free( self ); }
/* // 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; }
/* // Note: reference count is handled for "value2"! // // Item of list/tuple etc. can be directly passed as parameter "value2", // to avoid creating unnecessary intermediate objects. */ static int DaoParser_Deserialize( DaoParser *self, int start, int end, DaoValue **value2, DArray *types, DaoNamespace *ns, DaoProcess *proc, DMap *omap ) { DaoToken **tokens = self->tokens->items.pToken; DaoType *it1 = NULL, *it2 = NULL, *type = NULL; DaoValue *value = *value2; DaoValue *tmp = NULL; DaoValue *tmp2 = NULL; DaoObject *object; DaoCdata *cdata; DaoArray *array; DaoTuple *tuple; DaoList *list; DaoMap *map; DArray *dims; DNode *node; void *key = NULL; char *str; int i, j, k, n; int minus = 0; int next = start + 1; int tok2 = start < end ? tokens[start+1]->type : 0; int maybetype = tok2 == DTOK_COLON2 || tok2 == DTOK_LT || tok2 == DTOK_LCB; if( tokens[start]->type == DTOK_AT && tok2 == DTOK_LCB ){ int rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( rb < 0 ) return next; sscanf( tokens[start+2]->string.mbs, "%p", & key ); node = DMap_Find( omap, key ); if( node ) DaoValue_Copy( node->value.pValue, value2 ); return rb + 1; } if( tokens[start]->name == DTOK_ID_SYMBOL ){ DString *mbs = DString_New(1); while( tokens[start]->name == DTOK_ID_SYMBOL ){ DString_Append( mbs, & tokens[start]->string ); start += 1; } type = DaoNamespace_MakeType( ns, mbs->mbs, DAO_ENUM, NULL, NULL, 0 ); DString_Delete( mbs ); if( type == NULL ) return start; if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; }else if( tokens[start]->type == DTOK_IDENTIFIER && maybetype ){ type = DaoParser_ParseType( self, start, end, & start, NULL ); if( type == NULL ) return next; if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; } if( type == NULL ){ type = types->items.pType[0]; if( type && type->tid >= DAO_ARRAY ){ if( tokens[start]->name != DTOK_LCB ) return start; end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end ); if( end < 0 ) return start; next = end + 1; start += 1; end -= 1; } } if( type == NULL ) return next; DaoValue_Copy( type->value, value2 ); if( start > end ) return next; if( tokens[start]->name == DTOK_SUB ){ minus = 1; start += 1; if( start > end ) return next; } if( type->nested && type->nested->size >0 ) it1 = type->nested->items.pType[0]; if( type->nested && type->nested->size >1 ) it2 = type->nested->items.pType[1]; if( tokens[start]->name == DTOK_LB ){ int rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, start, end ); if( rb < 0 ) return next; sscanf( tokens[start+1]->string.mbs, "%p", & key ); DMap_Insert( omap, key, *value2 ); start = rb + 1; } str = tokens[start]->string.mbs; #if 0 printf( "type: %s %s\n", type->name->mbs, str ); for(i=start; i<=end; i++) printf( "%s ", tokens[i]->string.mbs ); printf( "\n" ); #endif value = *value2; switch( type->tid ){ case DAO_NONE : break; case DAO_INTEGER : value->xInteger.value = DaoDecodeInteger( str ); if( minus ) value->xInteger.value = - value->xInteger.value; break; case DAO_FLOAT : value->xFloat.value = DaoDecodeDouble( str ); if( minus ) value->xFloat.value = - value->xFloat.value; break; case DAO_DOUBLE : value->xDouble.value = DaoDecodeDouble( str ); if( minus ) value->xDouble.value = - value->xDouble.value; break; case DAO_COMPLEX : value->xComplex.value.real = DaoDecodeDouble( str ); if( minus ) value->xComplex.value.real = - value->xComplex.value.real; if( start + 1 > end ) return start+1; minus = 0; if( tokens[start + 1]->name == DTOK_SUB ){ minus = 1; start += 1; if( start + 1 > end ) return start+1; } value->xComplex.value.imag = DaoDecodeDouble( tokens[start+1]->string.mbs ); if( minus ) value->xComplex.value.imag = - value->xComplex.value.imag; next = start + 2; break; #ifdef DAO_WITH_LONGINT case DAO_LONG : value->xLong.value->base = DaoDecodeInteger( str ); start += 1; if( tokens[start]->name == DTOK_ADD ){ value->xLong.value->sign = 1; start += 1; }else if( tokens[start]->name == DTOK_SUB ){ value->xLong.value->sign = -1; start += 1; } for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DLong_PushBack( value->xLong.value, DaoDecodeInteger( tokens[i]->string.mbs ) ); } break; #endif case DAO_STRING : n = tokens[start]->string.size - 1; for(i=1; i<n; i++){ char c1 = str[i]; char c2 = str[i+1]; if( c1 < 'A' || c1 > 'P' ) continue; DString_AppendChar( value->xString.data, (char)((c1-'A')*16 + (c2-'A')) ); i += 1; } if( str[0] == '\"' ) DString_ToWCS( value->xString.data ); break; case DAO_ENUM : value->xEnum.value = DaoDecodeInteger( str ); break; case DAO_ARRAY : #ifdef DAO_WITH_NUMARRAY if( tokens[start]->name != DTOK_LSB ) return next; k = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, start, end ); if( k < 0 ) return next; n = 1; for(i=start+1; i<k; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; n *= strtol( tokens[i]->string.mbs, 0, 0 ); } if( n < 0 ) return next; if( it1 == NULL || it1->tid == 0 || it1->tid > DAO_COMPLEX ) return next; array = & value->xArray; dims = DArray_New(0); for(i=start+1; i<k; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; j = strtol( tokens[i]->string.mbs, 0, 0 ); DArray_Append( dims, (size_t) j ); } n = dims->size; DaoArray_ResizeArray( array, dims->items.pInt, n ); DArray_PushFront( types, it1 ); DArray_Delete( dims ); n = 0; for(i=k+1; i<=end; i++){ j = i + 1; while( j <= end && tokens[j]->name != DTOK_COMMA ) j += 1; DaoParser_Deserialize( self, i, j-1, & tmp, types, ns, proc, omap ); switch( it1->tid ){ case DAO_INTEGER : array->data.i[n] = tmp->xInteger.value; break; case DAO_FLOAT : array->data.f[n] = tmp->xFloat.value; break; case DAO_DOUBLE : array->data.d[n] = tmp->xDouble.value; break; } i = j; n += 1; } DArray_PopFront( types ); #endif break; case DAO_LIST : list = & value->xList; DArray_PushFront( types, it1 ); n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DArray_Append( & list->items, NULL ); k = DaoParser_Deserialize( self, i, end, list->items.items.pValue + n, types, ns, proc, omap ); i = k - 1; n += 1; } DArray_PopFront( types ); break; case DAO_MAP : map = & value->xMap; n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; DaoValue_Clear( & tmp ); DaoValue_Clear( & tmp2 ); DArray_PushFront( types, it1 ); i = DaoParser_Deserialize( self, i, end, &tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tokens[i]->name == DTOK_COMMA ) continue; if( map->items->size == 0 ){ if( tokens[i]->name == DTOK_COLON ){ DMap_Delete( map->items ); map->items = DHash_New( D_VALUE, D_VALUE ); } } if( tokens[i]->name == DTOK_COLON || tokens[i]->name == DTOK_FIELD ) i += 1; DArray_PushFront( types, it2 ); i = DaoParser_Deserialize( self, i, end, &tmp2, types, ns, proc, omap ); DArray_PopFront( types ); node = DMap_Insert( map->items, (void*) tmp, (void*) tmp2 ); i -= 1; n += 1; } break; case DAO_TUPLE : tuple = & value->xTuple; n = 0; for(i=start; i<=end; i++){ if( tokens[i]->name == DTOK_COMMA ) continue; it1 = NULL; if( type->nested && type->nested->size > n ){ it1 = type->nested->items.pType[n]; if( it1 && it1->tid == DAO_PAR_NAMED ) it1 = & it1->aux->xType; } DArray_PushFront( types, it1 ); i = DaoParser_Deserialize( self, i, end, tuple->items + n, types, ns, proc, omap ); DArray_PopFront( types ); i -= 1; n += 1; } break; case DAO_OBJECT : DArray_PushFront( types, NULL ); DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tmp == NULL ) break; object = DaoClass_MakeObject( & type->aux->xClass, tmp, proc ); if( object ) DaoValue_Copy( (DaoValue*) object, value2 ); break; case DAO_CDATA : case DAO_CSTRUCT : DArray_PushFront( types, NULL ); DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap ); DArray_PopFront( types ); if( tmp == NULL ) break; cdata = DaoCdata_MakeObject( & type->aux->xCdata, tmp, proc ); if( cdata ) DaoValue_Copy( (DaoValue*) cdata, value2 ); break; } DaoValue_Clear( & tmp ); DaoValue_Clear( & tmp2 ); return next; }
void DMacroNode_Delete( DMacroNode *self ) { DArray_Delete( self->nodes ); DArray_Delete( self->leaves ); dao_free( self ); }
/* assumed to be called before parsing class body */ void DaoClass_DeriveClassData( DaoClass *self ) { DaoType *type; DaoValue *value; DArray *parents, *offsets; DString *mbs; DNode *it, *search; daoint i, k, id, perm, index; mbs = DString_New(1); 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 ); for(i=0; i<self->superClass->size; i++){ if( self->superClass->items.pValue[i]->type == DAO_CLASS ){ DaoValue *klass = self->superClass->items.pValue[i]; DArray_Append( self->clsType->bases, klass->xClass.clsType ); DArray_Append( self->objType->bases, klass->xClass.objType ); DString_Assign( mbs, klass->xClass.className ); DString_AppendChar( mbs, '#' ); DString_AppendInteger( mbs, i+1 ); DaoClass_AddConst( self, mbs, klass, DAO_DATA_PRIVATE ); }else if( self->superClass->items.pValue[i]->type == DAO_CTYPE ){ DaoCtype *cdata = (DaoCtype*) self->superClass->items.pValue[i]; DaoTypeKernel *kernel = cdata->ctype->kernel; DMap *values = kernel->values; DMap *methods = kernel->methods; DArray_Append( self->clsType->bases, cdata->ctype ); DArray_Append( self->objType->bases, cdata->cdtype ); if( values == NULL ){ DaoNamespace_SetupValues( kernel->nspace, kernel->typer ); values = kernel->values; } if( methods == NULL ){ DaoNamespace_SetupMethods( kernel->nspace, kernel->typer ); methods = kernel->methods; } DString_Assign( mbs, cdata->ctype->name ); // XXX DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE ); DString_AppendChar( mbs, '#' ); DString_AppendInteger( mbs, i+1 ); DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE ); } } parents = DArray_New(0); offsets = DArray_New(0); DaoClass_Parents( self, parents, offsets ); for(i=1; i<parents->size; i++){ DaoClass *klass = parents->items.pClass[i]; DaoCdata *cdata = parents->items.pCdata[i]; if( klass->type == DAO_CLASS ){ if( klass->vtable ){ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); for(it=DMap_First(klass->vtable); it; it=DMap_Next(klass->vtable,it)){ DMap_Insert( self->vtable, it->key.pVoid, it->value.pVoid ); } } /* For class data: */ for( id=0; id<klass->cstDataName->size; id++ ){ DString *name = klass->cstDataName->items.pString[id]; value = klass->constants->items.pConst[ id ]->value; search = MAP_Find( klass->lookupTable, name ); if( search == NULL ) continue; perm = LOOKUP_PM( search->value.pInt ); /* NO deriving private member: */ if( perm <= DAO_DATA_PRIVATE ) continue; if( value->type == DAO_ROUTINE ){ if( DString_EQ( value->xRoutine.routName, klass->className ) ) continue; } search = MAP_Find( self->lookupTable, name ); if( search == NULL && value->type == DAO_ROUTINE && value->xRoutine.overloads ){ /* To skip the private methods: */ DaoClass_AddConst( self, name, (DaoValue*)value, perm ); }else if( search == NULL ){ index = LOOKUP_BIND( DAO_CLASS_CONSTANT, perm, i+1, self->constants->size ); MAP_Insert( self->lookupTable, name, index ); DArray_Append( self->constants, klass->constants->items.pConst[id] ); DArray_Append( self->cstDataName, (void*)name ); if( value->type == DAO_ROUTINE && (value->xRoutine.attribs & DAO_ROUT_VIRTUAL) ){ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); MAP_Insert( self->vtable, value, value ); } }else if( value->type == DAO_ROUTINE && value->xRoutine.overloads ){ DRoutines *routs = value->xRoutine.overloads; for(k=0; k<routs->routines->size; k++){ DaoRoutine *rout = routs->routines->items.pRoutine[k]; /* skip methods not defined in this parent type */ if( rout->routHost != klass->objType ) continue; if( rout->attribs & DAO_ROUT_PRIVATE ) continue; DaoClass_AddConst( self, name, (DaoValue*)rout, perm ); } }else if( value->type == DAO_ROUTINE ){ /* skip methods not defined in this parent type */ if( value->xRoutine.routHost != klass->objType ) continue; if( value->xRoutine.attribs & DAO_ROUT_PRIVATE ) continue; DaoClass_AddConst( self, name, value, perm ); } } /* class global data */ for( id=0; id<klass->glbDataName->size; id ++ ){ DString *name = klass->glbDataName->items.pString[id]; DaoVariable *var = klass->variables->items.pVar[id]; search = MAP_Find( klass->lookupTable, name ); perm = LOOKUP_PM( search->value.pInt ); /* NO deriving private member: */ if( perm <= DAO_DATA_PRIVATE ) continue; search = MAP_Find( self->lookupTable, name ); /* To overide data: */ if( search == NULL ){ index = LOOKUP_BIND( DAO_CLASS_VARIABLE, perm, i+1, self->variables->size ); MAP_Insert( self->lookupTable, name, index ); DArray_Append( self->variables, var ); DArray_Append( self->glbDataName, (void*)name ); } } }else if( cdata->type == DAO_CTYPE ){ DaoCtype *ctypeobj = (DaoCtype*) cdata; DaoTypeKernel *kernel = cdata->ctype->kernel; DaoTypeBase *typer = kernel->typer; DMap *values = kernel->values; DMap *methods = kernel->methods; DNode *it; int j; DaoCdataType_SpecializeMethods( cdata->ctype ); kernel = cdata->ctype->kernel; 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 && DMap_Find( self->lookupTable, & name ) == NULL ) DaoClass_AddConst( self, it->key.pString, it->value.pValue, DAO_DATA_PUBLIC ); } } for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){ DaoRoutine *func = it->value.pRoutine; DaoRoutine **funcs = & func; int k, count = 1; if( it->value.pValue->type == DAO_ROUTINE && it->value.pRoutine->overloads ){ DRoutines *routs = it->value.pRoutine->overloads; funcs = routs->routines->items.pRoutine; count = routs->routines->size; } for(k=0; k<count; k++){ DaoRoutine *func = funcs[k]; if( func->routHost != ctypeobj->cdtype ) continue; if( func->attribs & DAO_ROUT_INITOR ) continue; DaoClass_AddConst( self, it->key.pString, (DaoValue*)func, DAO_DATA_PUBLIC ); } } } } DArray_Delete( parents ); DArray_Delete( offsets ); DString_Delete( mbs ); }