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 ); }
void DaoClass_MakeInterface( DaoClass *self ) { daoint i, j; DaoType *tp; DaoRoutine *meth; DaoInterface *inter = self->inter; DMap *deftypes = DHash_New(0,0); DArray_Clear( self->inter->supers ); DMap_Clear( self->inter->methods ); if( self->parent && self->parent->type == DAO_CLASS ) DArray_Append( inter->supers, self->parent->xClass.inter ); for(i=0; i<self->cstDataName->size; ++i){ DString *name = self->cstDataName->items.pString[i]; DaoValue *value = self->constants->items.pConst[i]->value; DaoRoutine *rout = (DaoRoutine*) value; DNode *it; if( value->type != DAO_ROUTINE ) continue; if( value->xRoutine.attribs & DAO_ROUT_DECORATOR ) continue; it = MAP_Find( self->lookupTable, rout->routName ); if( it == NULL || LOOKUP_PM( it->value.pInt ) != DAO_DATA_PUBLIC ) continue; DMap_Reset( deftypes ); DMap_Insert( deftypes, rout->routHost, inter->abtype ); if( rout->overloads == NULL ){ tp = DaoType_DefineTypes( rout->routType, rout->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout->nameSpace, inter->abtype, 0 ); meth->attribs = rout->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); }else{ for(j=0; j<rout->overloads->routines->size; ++j){ DaoRoutine *rout2 = rout->overloads->routines->items.pRoutine[j]; if( rout2->attribs & DAO_ROUT_DECORATOR ) continue; tp = DaoType_DefineTypes( rout2->routType, rout2->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout2->nameSpace, inter->abtype, 0 ); meth->attribs = rout2->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); } } } DMap_Delete( deftypes ); }
void DaoClass_SetName( DaoClass *self, DString *name, DaoNamespace *ns ) { DaoRoutine *rout; DString *str; if( self->classRoutine ) return; self->inter = DaoInterface_New( ns, name->mbs ); DString_SetMBS( self->inter->abtype->name, "interface<" ); DString_Append( self->inter->abtype->name, name ); DString_AppendChar( self->inter->abtype->name, '>' ); DaoClass_AddReference( self, self->inter ); self->objType = DaoType_New( name->mbs, DAO_OBJECT, (DaoValue*)self, NULL ); self->clsType = DaoType_New( name->mbs, DAO_CLASS, (DaoValue*) self, NULL ); GC_IncRC( self->clsType ); DString_InsertMBS( self->clsType->name, "class<", 0, 0, 0 ); DString_AppendChar( self->clsType->name, '>' ); str = DString_New(1); DString_SetMBS( str, "self" ); DaoClass_AddObjectVar( self, str, NULL, self->objType, DAO_DATA_PRIVATE ); DString_Assign( self->className, name ); DaoClass_AddType( self, name, self->objType ); rout = DaoRoutine_New( ns, self->objType, 1 ); DString_Assign( rout->routName, name ); DString_AppendMBS( rout->routName, "::" ); DString_Append( rout->routName, name ); self->classRoutine = rout; /* XXX class<name> */ GC_IncRC( rout ); rout->routType = DaoType_New( "routine<=>", DAO_ROUTINE, (DaoValue*)self->objType, NULL ); DString_Append( rout->routType->name, name ); DString_AppendMBS( rout->routType->name, ">" ); GC_IncRC( rout->routType ); rout->attribs |= DAO_ROUT_INITOR; DaoClass_AddConst( self, name, (DaoValue*) self, DAO_DATA_PUBLIC ); self->classRoutines = DaoRoutines_New( ns, self->objType, NULL ); DString_Assign( self->classRoutines->routName, name ); DaoClass_AddConst( self, rout->routName, (DaoValue*)self->classRoutines, DAO_DATA_PUBLIC ); self->objType->value = (DaoValue*) DaoObject_Allocate( self, 0 ); self->objType->value->xObject.trait |= DAO_VALUE_CONST|DAO_VALUE_NOCOPY; self->objType->value->xObject.isDefault = 1; GC_IncRC( self->objType->value ); DString_SetMBS( str, "default" ); DaoClass_AddConst( self, str, self->objType->value, DAO_DATA_PUBLIC ); DString_Delete( str ); }
void DaoValue_CopyX( DaoValue *src, DaoValue **dest, DaoDataCache *cache ) { DaoValue *dest2 = *dest; if( src == dest2 ) return; if( dest2 && dest2->xBase.refCount >1 ){ GC_DecRC( dest2 ); *dest = dest2 = NULL; } if( dest2 == NULL ){ src = DaoValue_SimpleCopyWithTypeX( src, NULL, cache ); GC_IncRC( src ); *dest = src; return; } if( src->type != dest2->type || src->type > DAO_ENUM ){ src = DaoValue_SimpleCopyWithTypeX( src, NULL, cache ); GC_ShiftRC( src, dest2 ); *dest = src; return; } switch( src->type ){ case DAO_ENUM : DaoEnum_SetType( & dest2->xEnum, src->xEnum.etype ); DaoEnum_SetValue( & dest2->xEnum, & src->xEnum, NULL ); break; case DAO_INTEGER : dest2->xInteger.value = src->xInteger.value; break; case DAO_FLOAT : dest2->xFloat.value = src->xFloat.value; break; case DAO_DOUBLE : dest2->xDouble.value = src->xDouble.value; break; case DAO_COMPLEX : dest2->xComplex.value = src->xComplex.value; break; #ifdef DAO_WITH_LONGINT case DAO_LONG : DLong_Move( dest2->xLong.value, src->xLong.value ); break; #endif case DAO_STRING : DString_Assign( dest2->xString.data, src->xString.data ); break; } }
static void SYS_Popen( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; DString *fname; stream = DaoStream_New(); stream->attribs |= DAO_IO_PIPE; fname = stream->fname; DString_Assign( fname, p[0]->xString.data ); if( DString_Size( fname ) >0 ){ mode = DString_GetMBS( p[1]->xString.data ); stream->file = popen( DString_GetMBS( fname ), mode ); if( stream->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "error opening pipe" ); } stream->mode = 0; if( strstr( mode, "+" ) ) stream->mode = DAO_IO_WRITE | DAO_IO_READ; else{ if( strstr( mode, "r" ) ) stream->mode |= DAO_IO_READ; if( strstr( mode, "w" ) || strstr( mode, "a" ) ) stream->mode |= DAO_IO_WRITE; } }else{ DaoProcess_RaiseException( proc, DAO_ERROR, "empty command line" ); } DaoProcess_PutValue( proc, (DaoValue*)stream ); }
static void DaoIO_GetString( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; DString *res = DaoProcess_PutMBString( proc, "" ); DString_Assign( res, self->streamString ); DString_Clear( self->streamString ); }
static int DaoStringStream_Read( DaoStream *stream, DString *data, int count ) { DaoStringStream *self = (DaoStringStream*) stream; DString_Reset( data, 0 ); if( self->offset >= self->base.buffer->size ) return -1; if( count >= 0 ){ DString_SubString( self->base.buffer, data, self->offset, count ); self->offset += data->size; }else if( count == -1 ){ int delim = '\n'; daoint pos = DString_FindChar( self->base.buffer, delim, self->offset ); if( self->offset == 0 && (pos == DAO_NULLPOS || pos == self->base.buffer->size-1) ){ DString_Append( data, self->base.buffer ); self->offset = self->base.buffer->size; }else if( pos == DAO_NULLPOS ){ DString_SubString( self->base.buffer, data, pos, -1 ); self->offset = self->base.buffer->size; }else{ DString_SubString( self->base.buffer, data, pos, pos - self->offset + 1 ); self->offset = pos + 1; } if( self->base.mode & DAO_STREAM_AUTOCONV ) DString_ToUTF8( data ); return self->offset < self->base.buffer->size; }else{ if( self->offset == 0 ){ DString_Assign( data, self->base.buffer ); }else{ DString_SubString( self->base.buffer, data, self->offset, -1 ); } self->offset += data->size; } return data->size; }
static void DaoToken_Assign( DaoToken *self, DaoToken *other ) { self->type = other->type; self->name = other->name; self->line = other->line; self->cpos = other->cpos; DString_Assign( & self->string, & other->string ); }
int DaoxFont_Init( DaoxFont *self, DString *ttfData ) { DString_Assign( self->buffer, ttfData ); if( stbtt_InitFont( & self->info, (uchar_t*) self->buffer->chars, 0 ) == 0 ) return 0; stbtt_GetFontVMetrics( & self->info, & self->ascent, & self->descent, & self->lineSpace ); self->fontHeight = self->ascent - self->descent; self->lineSpace += self->fontHeight; return 1; }
int DaoxResource_SearchFile( DaoxResource *self, DString *fname, DString *search ) { DString *tmp; if( DaoVmSpace_SearchResource( self->vmSpace, fname, search ) ) return 1; tmp = DString_Copy( fname ); Dao_MakePath( search, tmp ); if( DaoVmSpace_TestFile( self->vmSpace, tmp ) ){ DString_Assign( fname, tmp ); DString_Delete( tmp ); return 1; } DString_Delete( tmp ); return 0; }
static void WIN_New( DaoProcess *proc, DaoValue *p[], int N ) { DaoxWindow *self = DaoxWindow_New(); DString_Assign( self->title, p[2]->xString.value ); self->width = self->context->deviceWidth = p[0]->xInteger.value; self->height = self->context->deviceHeight = p[1]->xInteger.value; self->handle = glfwCreateWindow( self->width, self->height, self->title->chars, NULL, NULL); if( self->handle == NULL ){ DaoProcess_RaiseError( proc, NULL, "Failed to create window" ); return; } glfwSetWindowUserPointer( self->handle, self ); glfwSetWindowCloseCallback( self->handle, DaoxWindow_CloseCallback ); glfwHideWindow( self->handle ); glfwMakeContextCurrent( self->handle ); DaoProcess_PutValue( proc, (DaoValue*) self ); }
DString* DaoValue_GetString( DaoValue *self, DString *str ) { dao_complex *com; char chs[100] = {0}; DString_Clear( str ); switch( self->type ){ case DAO_COMPLEX : com = & self->xComplex.value; sprintf( chs, (com->imag < 0) ? "%g%gC" : "%g+%gC", com->real, com->imag ); break; case DAO_BOOLEAN : strcat( chs, self->xBoolean.value ? "true" : "false" ); break; case DAO_INTEGER : sprintf( chs, "%"DAO_I64, (long long) self->xInteger.value ); break; case DAO_FLOAT : sprintf( chs, "%g", self->xFloat.value ); break; case DAO_STRING : DString_Assign( str, self->xString.value ); break; case DAO_ENUM : DaoEnum_MakeName( & self->xEnum, str ); break; default : break; } if( self->type <= DAO_COMPLEX ) DString_SetChars( str, chs ); return str; }
DString* DaoValue_GetString( DaoValue *self, DString *str ) { char chs[100] = {0}; DString_Clear( str ); switch( self->type ){ case DAO_INTEGER : sprintf( chs, "%" DAO_INT_FORMAT, self->xInteger.value ); break; case DAO_FLOAT : sprintf( chs, "%g", self->xFloat.value ); break; case DAO_DOUBLE : sprintf( chs, "%g", self->xDouble.value ); break; case DAO_COMPLEX : sprintf( chs, (self->xComplex.value.imag < 0) ? "%g%gC" : "%g+%gC", self->xComplex.value.real, self->xComplex.value.imag ); break; #ifdef DAO_WITH_LONGINT case DAO_LONG : DLong_Print( self->xLong.value, str ); break; #endif case DAO_ENUM : DaoEnum_MakeName( & self->xEnum, str ); break; case DAO_STRING : DString_Assign( str, self->xString.data ); break; default : break; } if( self->type <= DAO_COMPLEX ) DString_SetMBS( str, chs ); return str; }
int DaoStream_ReadLine( DaoStream *self, DString *line ) { int ch, delim = '\n'; char buf[IO_BUF_SIZE]; char *start = buf, *end = buf + IO_BUF_SIZE; DString_Clear( line ); DString_ToMBS( line ); if( self->redirect && self->redirect->StdioRead ){ self->redirect->StdioRead( self->redirect, line, 0 ); return line->size >0; }else if( self->file ){ return DaoFile_ReadLine( self->file, line ); }else if( self->attribs & DAO_IO_STRING ){ daoint pos = DString_FindWChar( self->streamString, delim, 0 ); if( pos == MAXSIZE ){ DString_Assign( line, self->streamString ); DString_Clear( self->streamString ); }else{ DString_SubString( self->streamString, line, 0, pos+1 ); DString_Erase( self->streamString, 0, pos+1 ); } return self->streamString->size >0; }else{ *start = ch = getchar(); start += 1; while( ch != delim && ch != EOF ){ *start = ch = getchar(); start += 1; if( start == end ){ if( ch == EOF ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); start = buf; } } if( ch == EOF && start != buf ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); clearerr( stdin ); return ch != EOF; } return 0; }
static void DaoIO_Open( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } stream = DaoStream_New(); stream->attribs |= DAO_IO_FILE; if( N==0 ){ stream->file = tmpfile(); if( stream->file <= 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "failed to create temporary file" ); return; } }else{ /* XXX Error handling? */ mode = DString_GetMBS( p[1]->xString.data ); if( p[0]->type == DAO_INTEGER ){ stream->file = fdopen( p[0]->xInteger.value, mode ); }else{ DString_Assign( stream->fname, p[0]->xString.data ); DString_ToMBS( stream->fname ); stream->file = DaoIO_OpenFile( proc, stream->fname, mode, 0 ); } stream->mode = 0; if( strstr( mode, "+" ) ) stream->mode = DAO_IO_WRITE | DAO_IO_READ; else{ if( strstr( mode, "r" ) ) stream->mode |= DAO_IO_READ; if( strstr( mode, "w" ) || strstr( mode, "a" ) ) stream->mode |= DAO_IO_WRITE; } } DaoProcess_PutValue( proc, (DaoValue*)stream ); }
void DaoValue_CopyX( DaoValue *src, DaoValue **dest, DaoType *cst ) { DaoValue *dest2 = *dest; if( src == dest2 ) return; if( dest2 && dest2->xBase.refCount >1 ){ GC_DecRC( dest2 ); *dest = dest2 = NULL; } if( src->type == DAO_CSTRUCT || src->type == DAO_CDATA ){ DaoValue_MoveCstruct( src, dest, cst != NULL && cst->invar != 0 ); return; }else if( src->type == DAO_CINVALUE ){ DaoValue_MoveCinValue( (DaoCinValue*) src, dest ); return; } if( dest2 == NULL ){ src = DaoValue_SimpleCopyWithTypeX( src, NULL, cst ); GC_IncRC( src ); *dest = src; return; } if( src->type != dest2->type || src->type > DAO_ENUM ){ src = DaoValue_SimpleCopyWithTypeX( src, NULL, cst ); GC_Assign( dest, src ); return; } switch( src->type ){ case DAO_ENUM : DaoEnum_SetType( & dest2->xEnum, src->xEnum.etype ); DaoEnum_SetValue( & dest2->xEnum, & src->xEnum ); break; case DAO_BOOLEAN : dest2->xBoolean.value = src->xBoolean.value; break; case DAO_INTEGER : dest2->xInteger.value = src->xInteger.value; break; case DAO_FLOAT : dest2->xFloat.value = src->xFloat.value; break; case DAO_COMPLEX : dest2->xComplex.value = src->xComplex.value; break; case DAO_STRING : DString_Assign( dest2->xString.value, src->xString.value ); break; } }
void DString_MakePath( DString *base, DString *path ) { if( base->size == 0 ) return; if( path->size >= 2 && path->chars[0] == '$' && path->chars[1] == '(' ) return; if( path->size >= 2 && isalpha( path->chars[0] ) && path->chars[1] == ':' ) return; if( path->chars[0] == '/' ) return; base = DString_Copy( base ); Dao_NormalizePathSep( base ); Dao_NormalizePathSep( path ); while( DString_Match( path, " ^ %.%. / ", NULL, NULL ) ){ if( DString_Match( base, " [^/] + ( / | ) $ ", NULL, NULL ) ){ DString_Change( path, " ^ %.%. / ", "", 1 ); DString_Change( base, " [^/] + ( / |) $ ", "", 0 ); }else{ DString_Delete( base ); return; } } if( DString_Match( path, " ^ %.%. $ ", NULL, NULL ) ){ if( DString_Match( base, " [^/] + ( / | ) $ ", NULL, NULL ) ){ DString_Clear( path ); DString_Change( base, " [^/] + ( / |) $ ", "", 0 ); } } if( base->size && path->size ){ if( base->chars[ base->size-1 ] != '/' && path->chars[0] != '/' ) DString_InsertChar( path, '/', 0 ); DString_Insert( path, base, 0, 0, 0 ); }else if( base->size && path->size == 0 ){ DString_Assign( path, base ); } while( DString_Change( path, "/ %. (/|$)", "/", 0 ) ); DString_Delete( base ); }
bool DaoxDebugger::EditContinue ( DaoProcess *process, int newEntryLine, QList<int> & lineMap, QStringList & newCodes, QStringList & routCodes ) { DaoRoutine *oldrout = process->activeRoutine; int i, j, k, dest = 0; //printf( "=======%s\n", routCodes.join("\n").toLocal8Bit().data() ); //printf( "=======%s\n", newCodes.join("\n").toLocal8Bit().data() ); if( routCodes.size() == newCodes.size() ){ DaoLexer *lexer = DaoLexer_New(); bool eq = true; for(i=0; i<routCodes.size(); i++){ QString s1 = NormalizeCodes( routCodes[i], lexer ); QString s2 = NormalizeCodes( newCodes[i], lexer ); if( s1 != s2 ){ eq = false; break; } } DaoLexer_Delete( lexer ); if( eq ) return true; } QString codes = newCodes.join( "\n" ); DaoParser *parser = DaoParser_New(); DaoRoutine *routine = DaoRoutine_New( oldrout->nameSpace, oldrout->routHost, 1 ); routine->routType = oldrout->routType; routine->parCount = oldrout->parCount; routine->attribs = oldrout->attribs; routine->defLine = oldrout->defLine; parser->routine = routine; parser->nameSpace = routine->nameSpace = oldrout->nameSpace; parser->vmSpace = oldrout->nameSpace->vmSpace; DString_Assign( parser->fileName, oldrout->nameSpace->name ); routine->body->codeStart = oldrout->body->codeStart; routine->body->codeEnd = oldrout->body->codeStart + newCodes.size() + 1; parser->regCount = routine->parCount; parser->levelBase = oldrout->defLine != 0; bool res = DaoParser_LexCode( parser, codes.toLocal8Bit().data(), 1 ); for(i=0; i<(int)parser->tokens->size; i++){ parser->tokens->items.pToken[i]->line += routine->body->codeStart; } for(i=0; i<(int)oldrout->body->defLocals->size; i++){ DaoToken *tok = oldrout->body->defLocals->items.pToken[i]; if( tok->index >= oldrout->parCount || tok->type ==0 ) break; MAP_Insert( DList_Top( parser->lookupTables ), & tok->string, i ); DList_Append( routine->body->defLocals, tok ); } res = res && DaoParser_ParseRoutine( parser ); DaoParser_Delete( parser ); if( res == false ){ DaoRoutine_Delete( routine ); return false; } if( (process->stackSize - process->stackTop) < (routine->body->regCount + DAO_MAX_PARAM) ){ DaoProcess_PushFrame( process, routine->body->regCount ); DaoProcess_PopFrame( process ); } DaoType **regTypes = routine->body->regType->items.pType; DaoValue **newValues = process->activeValues; DaoValue **oldValues = (DaoValue**)calloc( oldrout->body->regCount, sizeof(DaoValue*) ); memcpy( oldValues, newValues, oldrout->body->regCount * sizeof(DaoValue*) ); memset( newValues, 0, oldrout->body->regCount * sizeof(DaoValue*) ); DaoProcess_InitTopFrame( process, routine, process->activeObject ); #if 0 DaoStream *stream = DaoStream_New(); DaoRoutine_PrintCode( oldrout, stream ); DaoRoutine_PrintCode( routine, stream ); #endif regmap.clear(); for(i=0; i<oldrout->parCount; i++) regmap[i] = i; DaoVmCode *oldVMC = oldrout->body->vmCodes->data.codes; DaoVmCode *newVMC = routine->body->vmCodes->data.codes; DaoVmCodeX **oldAnnot = oldrout->body->annotCodes->items.pVmc; DaoVmCodeX **newAnnot = routine->body->annotCodes->items.pVmc; int M = oldrout->body->vmCodes->size; int N = routine->body->vmCodes->size; j = k = 0; for(i=0; i<lineMap.size(); i++){ QList<DaoVmCode> oldLineCodes; QList<DaoVmCode> newLineCodes; if( lineMap[i] <0 ) continue; int old = lineMap[i] + oldrout->body->codeStart + 1; int niu = i + routine->body->codeStart + 1; //printf( "%3i %3i: %3i %3i; %3i %3i\n", j, k, i, niu, lineMap[i], old ); while( j<M && oldAnnot[j]->line < old ) ++j; while( k<N && newAnnot[k]->line < niu ) ++k; while( j<M && oldAnnot[j]->line == old ){ oldLineCodes.append( oldVMC[j] ); ++j; } while( k<N && newAnnot[k]->line == niu ){ newLineCodes.append( newVMC[k] ); ++k; } Matching( oldLineCodes, newLineCodes ); } QMap<int,int>::iterator it, end = regmap.end(); for(it=regmap.begin(); it != end; ++it){ j = it.key(); i = it.value(); DaoValue_Move( oldValues[j], & newValues[i], regTypes[i] ); } int offset = 0; if( newEntryLine <0 ){ DaoVmCodeX **annotCodes = oldrout->body->annotCodes->items.pVmc; int entry = (process->activeCode - process->topFrame->codes) + 1; int entryline = oldrout->body->annotCodes->items.pVmc[entry]->line; /* if the entry line is NOT modified, use it */ entryline -= oldrout->body->codeStart + 1; for(i=0; i<lineMap.size(); i++) if( lineMap[i] == entryline ) break; int newEntryLine = i < lineMap.size() ? i : -1; if( newEntryLine >=0 ){ entryline += oldrout->body->codeStart + 1; while( (--entry) >=0 && annotCodes[entry]->line == entryline ) offset ++; } /* if the entry line IS modified, set the entry line to the first modified line */ if( newEntryLine <0 ){ for(i=0; i<lineMap.size(); i++) if( lineMap[i] <0 ) break; newEntryLine = i; } /* if the entry line is manually set: */ newEntryLine += routine->body->codeStart + 1; } //XXX GC_ShiftRC( routine, oldrout ); GC_IncRC( routine ); oldrout->body->revised = routine; process->activeRoutine = routine; process->activeTypes = regTypes; process->topFrame->codes = routine->body->vmCodes->data.codes; ResetExecution( process, newEntryLine, offset ); i = newCodes.size() - routCodes.size(); DaoNS_UpdateLineInfo( routine->nameSpace, routine->body->codeStart, i ); return true; }
void DString_Add( DString *self, DString *left, DString *right ) { DString_Assign( self, left ); DString_Append( self, right ); }
DString* DString_Copy( DString *self ) { DString *str = DString_New(); DString_Assign( str, self ); return str; }
int DaoValue_Move5( DaoValue *S, DaoValue **D, DaoType *T, DaoType *C, DMap *defs ) { DaoValue *D2 = *D; if( S == D2 && (S == NULL || DaoValue_FastMatchTo( S, T )) ) return 1; if( S == NULL ){ GC_DecRC( *D ); *D = NULL; return 0; } if( T == NULL ){ DaoValue_CopyX( S, D, C ); return 1; } if( T->valtype ){ if( DaoValue_Compare( S, T->value ) !=0 ) return 0; DaoValue_CopyX( S, D, C ); return 1; } switch( T->tid ){ case DAO_UDT : DaoValue_CopyX( S, D, C ); return 1; case DAO_THT : if( T->aux ) return DaoValue_Move5( S, D, (DaoType*) T->aux, C, defs ); DaoValue_CopyX( S, D, C ); return 1; case DAO_ANY : DaoValue_CopyX( S, D, C ); DaoValue_SetType( *D, T ); return 1; case DAO_VARIANT : return DaoValue_MoveVariant( S, D, T, C ); default : break; } if( S->type >= DAO_OBJECT || !(S->xBase.trait & DAO_VALUE_CONST) || T->invar ){ if( DaoValue_FastMatchTo( S, T ) ){ if( S->type == DAO_CDATA && S->xCdata.data == NULL ){ if( ! DaoType_IsNullable( T ) ) return 0; } if( S->type == DAO_CSTRUCT || S->type == DAO_CDATA ){ DaoValue_MoveCstruct( S, D, C != NULL && C->invar != 0 ); }else if( S->type == DAO_CINVALUE ){ DaoValue_MoveCinValue( (DaoCinValue*) S, D ); }else{ GC_Assign( D, S ); } return 1; } } if( S->type == DAO_CINVALUE ){ if( S->xCinValue.cintype->target == T ){ S = S->xCinValue.value; }else if( DaoType_MatchTo( S->xCinValue.cintype->target, T, NULL ) >= DAO_MT_EQ ){ S = S->xCinValue.value; } } if( D2 && D2->xBase.refCount > 1 ){ GC_DecRC( D2 ); *D = D2 = NULL; } #if 0 if( D2 && S->type == D2->type && S->type == T->tid && S->type <= DAO_ENUM ){ switch( S->type ){ case DAO_ENUM : DaoEnum_SetType( & D2->xEnum, T->subtid == DAO_ENUM_ANY ? S->xEnum.etype : T ); return DaoEnum_SetValue( & D2->xEnum, & S->xEnum ); case DAO_BOOLEAN : case DAO_INTEGER : D2->xInteger.value = S->xInteger.value; break; case DAO_FLOAT : D2->xFloat.value = S->xFloat.value; break; case DAO_COMPLEX : D2->xComplex.value = S->xComplex.value; break; case DAO_STRING : DString_Assign( D2->xString.value, S->xString.value ); break; } return 1; } #endif if( D2 == NULL || D2->type != T->tid ) return DaoValue_Move4( S, D, T, C, defs ); switch( (S->type << 8) | T->tid ){ case (DAO_STRING<<8)|DAO_STRING : DString_Assign( D2->xString.value, S->xString.value ); break; case (DAO_ENUM<<8)|DAO_ENUM : DaoEnum_SetType( & D2->xEnum, T->subtid == DAO_ENUM_ANY ? S->xEnum.etype : T ); DaoEnum_SetValue( & D2->xEnum, & S->xEnum ); break; case (DAO_CINVALUE<<8)|DAO_CINVALUE : if( S->xCinValue.cintype->vatype != T ) return DaoValue_Move4( S, D, T, C, defs ); DaoValue_MoveCinValue( (DaoCinValue*) S, D ); break; case (DAO_BOOLEAN<<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xBoolean.value; break; case (DAO_BOOLEAN<<8)|DAO_INTEGER : D2->xInteger.value = S->xBoolean.value; break; case (DAO_BOOLEAN<<8)|DAO_FLOAT : D2->xFloat.value = S->xBoolean.value; break; case (DAO_INTEGER<<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xInteger.value; break; case (DAO_INTEGER<<8)|DAO_INTEGER : D2->xInteger.value = S->xInteger.value; break; case (DAO_INTEGER<<8)|DAO_FLOAT : D2->xFloat.value = S->xInteger.value; break; case (DAO_FLOAT <<8)|DAO_BOOLEAN : D2->xBoolean.value = S->xFloat.value; break; case (DAO_FLOAT <<8)|DAO_INTEGER : D2->xInteger.value = S->xFloat.value; break; case (DAO_FLOAT <<8)|DAO_FLOAT : D2->xFloat.value = S->xFloat.value; break; case (DAO_COMPLEX<<8)|DAO_COMPLEX : D2->xComplex.value = S->xComplex.value; break; default : return DaoValue_Move4( S, D, T, C, defs ); } return 1; }
/* 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 ); }
int DaoValue_Move5( DaoValue *S, DaoValue **D, DaoType *T, DMap *defs, DaoDataCache *cache ) { DaoValue *D2 = *D; if( S == D2 ) return 1; if( S == NULL ){ GC_DecRC( *D ); *D = NULL; return 0; } if( T == NULL ){ DaoValue_CopyX( S, D, cache ); return 1; } switch( T->tid ){ case DAO_UDT : DaoValue_CopyX( S, D, cache ); return 1; case DAO_THT : if( T->aux ) return DaoValue_Move4( S, D, (DaoType*) T->aux, defs, cache ); DaoValue_CopyX( S, D, cache ); return 1; case DAO_ANY : DaoValue_CopyX( S, D, cache ); DaoValue_SetType( *D, T ); return 1; case DAO_VALTYPE : if( DaoValue_Compare( S, T->aux ) !=0 ) return 0; DaoValue_CopyX( S, D, cache ); return 1; case DAO_VARIANT : return DaoValue_MoveVariant( S, D, T ); default : break; } if( D2 && D2->xBase.refCount >1 ){ GC_DecRC( D2 ); *D = D2 = NULL; } if( D2 == NULL || D2->type != T->tid ) return DaoValue_Move4( S, D, T, defs, cache ); switch( (S->type << 8) | T->tid ){ case (DAO_STRING<<8)|DAO_STRING : DString_Assign( D2->xString.data, S->xString.data ); break; case (DAO_ENUM<<8)|DAO_ENUM : DaoEnum_SetType( & D2->xEnum, T ); DaoEnum_SetValue( & D2->xEnum, & S->xEnum, NULL ); break; case (DAO_INTEGER<<8)|DAO_INTEGER : D2->xInteger.value = S->xInteger.value; break; case (DAO_INTEGER<<8)|DAO_FLOAT : D2->xFloat.value = S->xInteger.value; break; case (DAO_INTEGER<<8)|DAO_DOUBLE : D2->xDouble.value = S->xInteger.value; break; case (DAO_FLOAT <<8)|DAO_INTEGER : D2->xInteger.value = S->xFloat.value; break; case (DAO_FLOAT <<8)|DAO_FLOAT : D2->xFloat.value = S->xFloat.value; break; case (DAO_FLOAT <<8)|DAO_DOUBLE : D2->xDouble.value = S->xFloat.value; break; case (DAO_DOUBLE <<8)|DAO_INTEGER : D2->xInteger.value = S->xDouble.value; break; case (DAO_DOUBLE <<8)|DAO_FLOAT : D2->xFloat.value = S->xDouble.value; break; case (DAO_DOUBLE <<8)|DAO_DOUBLE : D2->xDouble.value = S->xDouble.value; break; case (DAO_COMPLEX<<8)|DAO_COMPLEX : D2->xComplex.value = S->xComplex.value; break; #ifdef DAO_WITH_LONGINT case (DAO_LONG <<8)|DAO_LONG : DLong_Move( D2->xLong.value, S->xLong.value ); break; #endif default : return DaoValue_Move4( S, D, T, defs, cache ); } return 1; }
/* // Assumming the value "self" is compatible to the type "tp", if it is not null. */ DaoValue* DaoValue_SimpleCopyWithTypeX( DaoValue *self, DaoType *tp, DaoDataCache *cache ) { DaoEnum *e; daoint i, n; if( self == NULL ) return dao_none_value; if( (tp == NULL || tp->tid == self->type) && self->type < DAO_ENUM ){ if( cache ){ DaoValue *value = DaoDataCache_MakeValue( cache, self->type ); switch( self->type ){ case DAO_NONE : return self; case DAO_INTEGER : value->xInteger.value = self->xInteger.value; break; case DAO_FLOAT : value->xFloat.value = self->xFloat.value; break; case DAO_DOUBLE : value->xDouble.value = self->xDouble.value; break; case DAO_COMPLEX : value->xComplex.value = self->xComplex.value; break; #ifdef DAO_WITH_LONGINT case DAO_LONG : DLong_Move( value->xLong.value, self->xLong.value ); break; #endif case DAO_STRING : DString_Assign( value->xString.data, self->xString.data ); break; } return value; }else{ switch( self->type ){ case DAO_NONE : return self; case DAO_INTEGER : return (DaoValue*) DaoInteger_New( self->xInteger.value ); case DAO_FLOAT : return (DaoValue*) DaoFloat_New( self->xFloat.value ); case DAO_DOUBLE : return (DaoValue*) DaoDouble_New( self->xDouble.value ); case DAO_COMPLEX : return (DaoValue*) DaoComplex_New( self->xComplex.value ); case DAO_LONG : return (DaoValue*) DaoLong_Copy( & self->xLong ); case DAO_STRING : return (DaoValue*) DaoString_Copy( & self->xString ); } } return self; /* unreachable; */ }else if( self->type == DAO_ENUM ){ return (DaoValue*) DaoEnum_Copy( & self->xEnum, tp ); }else if( tp && tp->tid >= DAO_INTEGER && tp->tid <= DAO_DOUBLE ){ DaoValue *value = cache ? DaoDataCache_MakeValue( cache, tp->tid ) : NULL; switch( value == NULL ? tp->tid : 0 ){ case DAO_INTEGER : value = (DaoValue*) DaoInteger_New(0); break; case DAO_FLOAT : value = (DaoValue*) DaoFloat_New(0); break; case DAO_DOUBLE : value = (DaoValue*) DaoDouble_New(0); break; } switch( tp->tid ){ case DAO_INTEGER : value->xInteger.value = DaoValue_GetInteger( self ); break; case DAO_FLOAT : value->xFloat.value = DaoValue_GetFloat( self ); break; case DAO_DOUBLE : value->xDouble.value = DaoValue_GetDouble( self ); break; } return value; } #ifdef DAO_WITH_NUMARRAY if( self->type == DAO_ARRAY && self->xArray.original ){ DaoArray_Sliced( (DaoArray*)self ); return self; }else #endif if( self->type == DAO_CSTRUCT || self->type == DAO_CDATA ){ FuncPtrSliced sliced = self->xCstruct.ctype->kernel->Sliced; if( sliced ) (*sliced)( self ); return self; } if( self->xBase.trait & DAO_VALUE_NOCOPY ) return self; if( (self->xBase.trait & DAO_VALUE_CONST) == 0 ) return self; switch( self->type ){ case DAO_LIST : return (DaoValue*) DaoList_Copy( (DaoList*) self, tp ); case DAO_MAP : return (DaoValue*) DaoMap_Copy( (DaoMap*) self, tp ); case DAO_TUPLE : return (DaoValue*) DaoTuple_Copy( (DaoTuple*) self, tp ); #ifdef DAO_WITH_NUMARRAY case DAO_ARRAY : return (DaoValue*) DaoArray_CopyX( (DaoArray*) self, tp ); #endif default : break; } return self; }
static void DaoIO_Name( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; DString *res = DaoProcess_PutMBString( proc, "" ); DString_Assign( res, self->fname ); }