Пример #1
0
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 );
}
Пример #2
0
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 );
}
Пример #3
0
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 );
}
Пример #4
0
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;
	}
}
Пример #5
0
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 );
}
Пример #6
0
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 );
}
Пример #7
0
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;
}
Пример #8
0
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 );
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
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 );
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
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 );
}
Пример #16
0
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;
	}
}
Пример #17
0
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 );
}
Пример #18
0
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;
}
Пример #19
0
void DString_Add( DString *self, DString *left, DString *right )
{
	DString_Assign( self, left );
	DString_Append( self, right );
}
Пример #20
0
DString* DString_Copy( DString *self )
{
	DString *str = DString_New();
	DString_Assign( str, self );
	return str;
}
Пример #21
0
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;
}
Пример #22
0
/* 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 );
}
Пример #23
0
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;
}
Пример #24
0
/*
// 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;
}
Пример #25
0
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 );
}