Exemplo n.º 1
0
DaoClass* DaoClass_New()
{
	DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) );
	DaoValue_Init( self, DAO_CLASS );
	self->trait |= DAO_VALUE_DELAYGC;
	self->className = DString_New(1);

	self->lookupTable = DHash_New(D_STRING,0);
	self->ovldRoutMap = DHash_New(D_STRING,0);
	self->abstypes    = DMap_New(D_STRING,D_VALUE);
	self->constants   = DArray_New(D_VALUE);
	self->variables   = DArray_New(D_VALUE);
	self->instvars    = DArray_New(D_VALUE);
	self->objDataName = DArray_New(D_STRING);
	self->cstDataName = DArray_New(D_STRING);
	self->glbDataName = DArray_New(D_STRING);
	self->parent = NULL;
	self->mixinBases = DArray_New(0);  /* refcount handled in ::allBases; */
	self->allBases   = DArray_New(D_VALUE);
	self->mixins  = DArray_New(0);
	self->ranges  = DVector_New(sizeof(ushort_t));
	self->offsets = DVector_New(sizeof(ushort_t));
	self->references  = DArray_New(D_VALUE);
	self->inter = NULL;

	self->cstMixinStart = self->cstMixinEnd = self->cstMixinEnd2 = 0;
	self->glbMixinStart = self->glbMixinEnd = self->glbMixinEnd2 = 0;
	self->objMixinStart = self->objMixinEnd = self->objMixinEnd2 = 0;
	self->cstParentStart = self->cstParentEnd = 0;
	self->glbParentStart = self->glbParentEnd = 0;
	return self;
}
Exemplo n.º 2
0
int DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds )
{
	DNode *it;
	DMap *newbinds = NULL;
	DList *methods;
	void *pvoid[2];
	daoint i, n, bl;

	/* XXX locking */
	if( type->interfaces == NULL ) type->interfaces = DHash_New( DAO_DATA_VALUE, 0 );

	pvoid[0] = type;
	pvoid[1] = self->abtype;
	if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pVoid != NULL;
	if( binds && DMap_Find( binds, pvoid ) ) return 1;
	if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 );
	DaoInterface_TempBind( self, type, binds );
	methods = DList_New(0);
	DMap_SortMethods( self->methods, methods );
	bl = DaoInterface_CheckBind( methods, type, binds );
	DList_Delete( methods );
	if( newbinds ) DMap_Delete( newbinds );
	DMap_Insert( type->interfaces, self, bl ? self : NULL );
	if( bl == 0 ) return 0;
	for(i=0,n=self->supers->size; i<n; i++){
		DaoInterface *super = (DaoInterface*) self->supers->items.pValue[i];
		if( DMap_Find( type->interfaces, super ) ) continue;
		DMap_Insert( type->interfaces, super, super );
	}
	return 1;
}
Exemplo n.º 3
0
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms )
{
	DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}};
	DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) );
	DMutex_Init( & self->mutex );
	DCondVar_Init( & self->condv );
	DCondVar_Init( & self->condv2 );
	DThread_Init( & self->timer );
	self->finishing = 0;
	self->timing = 0;
	self->total = 0;
	self->idle = 0;
	self->stopped = 0;
	self->threads = DArray_New(0);
	self->functions = DArray_New(0);
	self->parameters = DArray_New(0);
	self->events = DArray_New(0);
	self->events2 = DArray_New(0);
	self->waitings = DMap_New(D_VALUE,0);
	self->pending = DHash_New(0,0);
	self->active = DHash_New(0,0);
	self->caches = DArray_New(0);
	self->vmspace = vms;
	self->timestamp = com;
	return self;
}
Exemplo n.º 4
0
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms )
{
	DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) );
	DMutex_Init( & self->mutex );
	DCondVar_Init( & self->condv );
	DCondVar_Init( & self->condv2 );
	DThread_Init( & self->timer );
	self->finishing = 0;
	self->timing = 0;
	self->total = 0;
	self->vacant = 0;
	self->idle = 0;
	self->stopped = 0;
	self->threads = DList_New(0);
	self->functions = DList_New(0);
	self->parameters = DList_New(0);
	self->owners = DList_New(0);
	self->events = DList_New(0);
	self->events2 = DList_New(0);
	self->waitings = DMap_New( DAO_DATA_COMPLEX, 0 );
	self->pending = DHash_New(0,0);
	self->active = DHash_New(0,0);
	self->caches = DList_New(0);
	self->vmspace = vms;
	self->timestamp.real = 0.0;
	self->timestamp.imag = 0.0;
	return self;
}
Exemplo n.º 5
0
DaoxProfiler* DaoxProfiler_New()
{
	DaoxProfiler *self = (DaoxProfiler*) dao_calloc(1,sizeof(DaoxProfiler));
	self->profile = DHash_New( 0, DAO_DATA_MAP );
	self->one = DHash_New( 0, DAO_DATA_VALUE );
	self->base.EnterFrame = DaoProfiler_EnterFrame;
	self->base.LeaveFrame = DaoProfiler_LeaveFrame;
	self->base.Report = DaoProfiler_Report;
	self->base.Reset = DaoProfiler_Reset;
	DMutex_Init( & self->mutex );
	return self;
}
Exemplo n.º 6
0
static void DaoMT_Critical( DaoProcess *proc, DaoValue *p[], int n )
{
	void *key;
	DNode *it;
	DMap *cache = (DMap*) DaoProcess_GetAuxData( proc, DaoMT_ProcMutexCache );
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 );
	DaoRoutine *routine = proc->activeRoutine;

	if( sect == NULL ) return;

	/* Get the original routine, if this one is a specialized copy: */
	while( routine->original ) routine = routine->original;

	/*
	// Use "routine + sect->c" instead of "sect" as the key for mutex,
	// as "sect" may be different for different copy of specialized routine.
	// But "sect->c" won't change after being set during compiling.
	*/
	key = routine + sect->c;

	if( cache == NULL ){
		cache = DHash_New(0,0); /* Local cache is used to avoid extra locking; */
		DaoProcess_SetAuxData( proc, DaoMT_ProcMutexCache, cache );
	}
	it = DMap_Find( cache, key ); /* Check local cache first; */
	if( it == NULL ) it = DMap_Insert( cache, key, DaoMT_GetMutex( routine, key ) );
	DMutex_Lock( (DMutex*) it->value.pVoid );
	DaoProcess_Execute( proc );
	DMutex_Unlock( (DMutex*) it->value.pVoid );
	DaoProcess_PopFrame( proc );
}
Exemplo n.º 7
0
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target )
{
	DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) );
	DaoValue_Init( self, DAO_CINTYPE );
	self->trait |= DAO_VALUE_DELAYGC;
	self->derived = 0;
	self->supers = DList_New( DAO_DATA_VALUE );
	self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->citype = DaoType_New( "interface<", DAO_CINTYPE, (DaoValue*)self, NULL );
	self->vatype = DaoType_New( inter->abtype->name->chars, DAO_CINVALUE, (DaoValue*)self, NULL );
	self->abstract = inter;
	self->target = target;
	GC_IncRC( self->citype );
	GC_IncRC( self->vatype );
	GC_IncRC( self->abstract );
	GC_IncRC( self->target );

	self->citype->nested = DList_New( DAO_DATA_VALUE );
	self->vatype->nested = DList_New( DAO_DATA_VALUE );
	DList_Append( self->citype->nested, target );
	DList_Append( self->vatype->nested, target );

	DString_AppendChar( self->vatype->name, '<' );
	DString_Append( self->vatype->name, target->name );
	DString_AppendChar( self->vatype->name, '>' );

	DString_Append( self->citype->name, self->vatype->name );
	DString_AppendChar( self->citype->name, '>' );

#ifdef DAO_USE_GC_LOGGER
	DaoObjectLogger_LogNew( (DaoValue*) self );
#endif
	return self;
}
Exemplo n.º 8
0
static void DaoIO_Writeln0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N )
{
	DaoValue *params[DAO_MAX_PARAM];
	DMap *cycmap = NULL;
	int i;
	if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return;
	for(i=0; i<N; i++){
		if( p[i]->type > DAO_ARRAY ){
			cycmap = DHash_New(0,0);
			break;
		}
	}
	/*
	// DaoValue_Print() may call user defined function and change the stack
	// and invalidate the parameter array:
	*/
	memmove( params, p, N*sizeof(DaoValue*) );
	for(i=0; i<N; i++){
		if( params[i]->type > DAO_ARRAY ) DMap_Reset( cycmap );
		DaoValue_Print( params[i], self, cycmap, proc );
		if( i+1<N ) DaoStream_WriteChars( self, " ");
	}
	DaoStream_WriteChars( self, "\n");
	if( cycmap ) DMap_Delete( cycmap );
}
Exemplo n.º 9
0
static DMap* DaoProcess_GetTimeMap( DaoProcess *self )
{
	DMap *mapTime = (DMap*) DaoProcess_GetAuxData( self, DMap_DeleteTimeMap );
	if( mapTime ) return mapTime;
	mapTime = DHash_New( 0, DAO_DATA_VALUE );
	DaoProcess_SetAuxData( self, DMap_DeleteTimeMap, mapTime );
	return mapTime;
}
Exemplo n.º 10
0
DaoXmlNode* DaoXmlNode_New()
{
	DaoXmlNode *self = (DaoXmlNode*) dao_calloc( 1, sizeof(DaoXmlNode) );
	self->parent = NULL;
	self->children = DList_New(0);
	self->name = DString_New();
	self->content = DString_New();
	self->attributes = DHash_New( DAO_DATA_STRING, DAO_DATA_STRING );
	return self;
}
Exemplo n.º 11
0
void DaoxDataFrame_AddLabelGroup( DaoxDataFrame *self, int dim )
{
	if( dim >=0 && dim < 3 ){
		DMap *labmap = DHash_New(D_STRING,0);
		DArray *labels = self->labels[dim];
		self->groups[dim] = labels->size;
		DArray_Append( labels, labmap );
		DMap_Delete( labmap );
	}
}
Exemplo n.º 12
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 );
}
Exemplo n.º 13
0
int DaoValue_CompareExt( DaoValue *left, DaoValue *right, DMap *cycmap )
{
	DMap *input = cycmap;
	void *pters[2];
	int res = 0;

	if( left == right ) return 0;
	if( left == NULL || right == NULL ) return left < right ? -100 : 100;
	if( left->type != right->type ){
		double L, R;
		res = left->type < right->type ? -100 : 100;
		if( left->type < DAO_BOOLEAN || left->type > DAO_FLOAT ) return res;
		if( right->type < DAO_BOOLEAN || right->type > DAO_FLOAT ) return res;
		L = DaoValue_GetFloat( left );
		R = DaoValue_GetFloat( right );
		return L == R ? 0 : (L < R ? -1 : 1);
	}
	switch( left->type ){
	case DAO_TUPLE   :
	case DAO_LIST    :
	case DAO_OBJECT  :
	case DAO_CDATA   :
	case DAO_CSTRUCT :
		pters[0] = left;
		pters[1] = right;
		if( cycmap != NULL ){
			DNode *it = DMap_Find( cycmap, pters );
			if( it != NULL ) return left < right ? -100 : 100;
		}
		if( cycmap == NULL ) cycmap = DHash_New(DAO_DATA_VOID2,0);
		DMap_Insert( cycmap, pters, NULL );
		break;
	}
	switch( left->type ){
	case DAO_NONE : break;
	case DAO_BOOLEAN : res = number_compare( left->xBoolean.value, right->xBoolean.value ); break;
	case DAO_INTEGER : res = number_compare( left->xInteger.value, right->xInteger.value ); break;
	case DAO_FLOAT   : res = number_compare( left->xFloat.value, right->xFloat.value ); break;
	case DAO_COMPLEX : res = DaoComplex_Compare( (DaoComplex*) left, (DaoComplex*) right ); break;
	case DAO_STRING  : res = DString_CompareUTF8( left->xString.value, right->xString.value ); break;
	case DAO_ENUM    : res = DaoEnum_Compare( (DaoEnum*) left, (DaoEnum*) right ); break;
	case DAO_TUPLE   : res = DaoTuple_Compare( (DaoTuple*) left, (DaoTuple*) right, cycmap ); break;
	case DAO_LIST    : res = DaoList_Compare( (DaoList*) left, (DaoList*) right, cycmap ); break;
	case DAO_OBJECT  : res = DaoObject_Compare( (DaoObject*)left, (DaoObject*)right, cycmap ); break;
	case DAO_CDATA   :
	case DAO_CSTRUCT : res = DaoCstruct_Compare( (DaoCstruct*)left, (DaoCstruct*)right, cycmap ); break;
	case DAO_TYPE    : res = DaoType_Compare( (DaoType*) left, (DaoType*) right ); break;
#ifdef DAO_WITH_NUMARRAY
	case DAO_ARRAY   : res = DaoArray_Compare( (DaoArray*) left, (DaoArray*) right ); break;
#endif
	default: res = left < right ? -100 : 100; break; /* Needed for map; */
	}
	if( cycmap != input ) DMap_Delete( cycmap );
	return res;
}
Exemplo n.º 14
0
DaoxResource* DaoxResource_New( DaoVmSpace *vms )
{
	DaoxResource *self = (DaoxResource*) dao_calloc( 1, sizeof(DaoxResource) );
	DaoCstruct_Init( (DaoCstruct*) self, daox_type_resource );
	self->scenes     = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->lights     = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->cameras    = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->images     = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->textures   = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->effects    = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->materials  = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->geometries = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->terrains   = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->vmSpace = vms;
	return self;
}
Exemplo n.º 15
0
DaoClass* DaoClass_New()
{
	DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) );
	DaoValue_Init( self, DAO_CLASS );
	self->trait |= DAO_VALUE_DELAYGC;
	self->className = DString_New(1);

	self->lookupTable = DHash_New(D_STRING,0);
	self->ovldRoutMap = DHash_New(D_STRING,0);
	self->abstypes    = DMap_New(D_STRING,D_VALUE);
	self->constants   = DArray_New(D_VALUE);
	self->variables   = DArray_New(D_VALUE);
	self->instvars    = DArray_New(D_VALUE);
	self->objDataName = DArray_New(D_STRING);
	self->cstDataName = DArray_New(D_STRING);
	self->glbDataName = DArray_New(D_STRING);
	self->superClass  = DArray_New(D_VALUE);
	self->references  = DArray_New(D_VALUE);
	return self;
}
Exemplo n.º 16
0
static void DaoClass_AddConst3( DaoClass *self, DString *name, DaoValue *data )
{
	DaoConstant *cst = DaoConstant_New( data );
	DArray_Append( self->cstDataName, (void*)name );
	DArray_Append( self->constants, cst );
	DaoValue_MarkConst( cst->value );
	if( data->type == DAO_ROUTINE && data->xRoutine.routHost != self->objType ){
		if( data->xRoutine.attribs & DAO_ROUT_VIRTUAL ){ /* data->xRoutine.overloads == NULL */
			if( self->vtable == NULL ) self->vtable = DHash_New(0,0);
			MAP_Insert( self->vtable, data, data );
		}
	}
}
Exemplo n.º 17
0
DaoRoutine* DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds )
{
	DNode *it;
	DMap *newbinds = NULL;
	DList *methods;
	DaoRoutine *incompatible;
	void *pvoid[2];
	daoint i, n;

	if( self->abtype->kernel->SetupMethods ){
		DaoTypeKernel *kernel = self->abtype->kernel;
		kernel->SetupMethods( kernel->nspace, self->abtype->core );
	}

	/* XXX locking */
	if( type->interfaces == NULL ){
		type->interfaces = DHash_New( DAO_DATA_VALUE, DAO_DATA_VALUE );
	}

	pvoid[0] = type;
	pvoid[1] = self->abtype;
	if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pRoutine;
	if( binds && DMap_Find( binds, pvoid ) ) return NULL;
	if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 );
	DaoInterface_TempBind( self, type, binds );
	methods = DList_New(0);
	DMap_SortMethods( self->methods, methods );
	incompatible = DaoInterface_CheckBind( methods, type, binds );
	DList_Delete( methods );
	if( newbinds ) DMap_Delete( newbinds );
	DMap_Insert( type->interfaces, self, incompatible );
	if( incompatible ) return incompatible;
	for(i=0,n=self->bases->size; i<n; i++){
		DaoInterface *base = (DaoInterface*) self->bases->items.pValue[i];
		if( DMap_Find( type->interfaces, base ) ) continue;
		DMap_Insert( type->interfaces, base, NULL );
	}
	return NULL;
}
Exemplo n.º 18
0
DaoInterface* DaoInterface_New( const char *name )
{
	DaoInterface *self = (DaoInterface*) dao_calloc( 1, sizeof(DaoInterface) );
	DaoValue_Init( self, DAO_INTERFACE );
	self->trait |= DAO_VALUE_DELAYGC;
	self->derived = 0;
	self->supers = DList_New( DAO_DATA_VALUE );
	self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->abtype = DaoType_New( name, DAO_INTERFACE, (DaoValue*)self, NULL );
	GC_IncRC( self->abtype );
#ifdef DAO_USE_GC_LOGGER
	DaoObjectLogger_LogNew( (DaoValue*) self );
#endif
	return self;
}
Exemplo n.º 19
0
static void DaoIO_Write0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N )
{
	DMap *cycmap = NULL;
	int i;

	for(i=0; i<N; i++){
		if( p[i]->type > DAO_ARRAY ){
			cycmap = DHash_New(0,0);
			break;
		}
	}
	for(i=0; i<N; i++){
		if( p[i]->type > DAO_ARRAY ) DMap_Reset( cycmap );
		DaoValue_Print( p[i], self, cycmap, proc );
	}
	if( cycmap ) DMap_Delete( cycmap );
}
Exemplo n.º 20
0
void DaoObject_Print( DaoValue *self, DaoStream *stream, DMap *cycmap, DaoProcess *proc )
{
	int ec = 0;
	char buf[50];
	DMap *inmap = cycmap;
	DaoObject *object = (DaoObject*) self;
	DaoValue *params[2];
	DaoRoutine *meth;

	sprintf( buf, "[%p]", object );
	if( self == object->defClass->objType->value ){
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, "[null]" );
		return;
	}
	if( cycmap != NULL && DMap_Find( cycmap, object ) != NULL ){
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, buf );
		return;
	}
	if( cycmap == NULL ) cycmap = DHash_New(0,0);
	DMap_Insert( cycmap, self, self );

	DaoValue_Clear( & proc->stackValues[0] );

	params[0] = (DaoValue*) dao_type_string;
	params[1] = (DaoValue*) stream;
	meth = DaoClass_FindMethod( object->defClass, "(string)", NULL );
	if( meth ){
		ec = DaoProcess_Call( proc, meth, self, params, 2 );
		if( ec ) ec = DaoProcess_Call( proc, meth, self, params, 1 );
	}else{
		meth = DaoClass_FindMethod( object->defClass, "serialize", NULL );
		if( meth ) ec = DaoProcess_Call( proc, meth, self, NULL, 0 );
	}
	if( ec ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL );
	}else if( meth && proc->stackValues[0] ){
		DaoValue_Print( proc->stackValues[0], stream, cycmap, proc );
	}else{
		DaoStream_WriteString( stream, object->defClass->className );
		DaoStream_WriteChars( stream, buf );
	}
	if( inmap == NULL ) DMap_Delete( cycmap );
}
Exemplo n.º 21
0
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target )
{
	DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) );
	DaoNamespace *ns = inter->nameSpace;
	DString *name = inter->abtype->name;

	DaoValue_Init( self, DAO_CINTYPE );
	self->trait |= DAO_VALUE_DELAYGC;
	self->derived = 0;
	self->bases = DList_New( DAO_DATA_VALUE );
	self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE );
	self->citype = DaoType_New( ns, "interface<", DAO_CINTYPE, (DaoValue*)self, NULL );
	self->vatype = DaoType_New( ns, name->chars, DAO_CINVALUE, (DaoValue*)self, NULL );
	self->abstract = inter;
	self->target = target;
	self->citype->core = & daoCinTypeCore;
	self->vatype->core = & daoCinValueCore;
	GC_IncRC( self->citype );
	GC_IncRC( self->vatype );
	GC_IncRC( self->abstract );
	GC_IncRC( self->target );

	self->vatype->kernel = DaoTypeKernel_New( NULL );
	self->vatype->kernel->abtype = self->vatype;
	GC_IncRC( self->vatype->kernel );
	GC_IncRC( self->vatype );

	self->citype->args = DList_New( DAO_DATA_VALUE );
	self->vatype->args = DList_New( DAO_DATA_VALUE );
	DList_Append( self->citype->args, target );
	DList_Append( self->vatype->args, target );

	DString_AppendChar( self->vatype->name, '<' );
	DString_Append( self->vatype->name, target->name );
	DString_AppendChar( self->vatype->name, '>' );

	DString_Append( self->citype->name, self->vatype->name );
	DString_AppendChar( self->citype->name, '>' );

#ifdef DAO_USE_GC_LOGGER
	DaoObjectLogger_LogNew( (DaoValue*) self );
#endif
	return self;
}
Exemplo n.º 22
0
static void DaoCinValue_Print( DaoValue *self, DaoStream *stream, DMap *cycmap, DaoProcess *proc )
{
	int ec = 0;
	char buf[50];
	DaoRoutine *meth;
	DaoValue *args[2];
	DaoType *type = self->xCinValue.cintype->vatype;
	DMap *inmap = cycmap;

	if( cycmap != NULL && DMap_Find( cycmap, self ) != NULL ){
		sprintf( buf, "[%p]", self );
		DaoStream_WriteString( stream, type->name );
		DaoStream_WriteChars( stream, buf );
		return;
	}

	if( cycmap == NULL ) cycmap = DHash_New(0,0);
	DMap_Insert( cycmap, self, self );

	args[0] = (DaoValue*) proc->vmSpace->typeString;
	args[1] = (DaoValue*) stream;
	meth = DaoType_FindFunctionChars( type, "(string)" );
	if( meth ){
		ec = DaoProcess_Call( proc, meth, self, args, 2 );
		if( ec ) ec = DaoProcess_Call( proc, meth, self, args, 1 );
	}else{
		meth = DaoType_FindFunctionChars( type, "serialize" );
		if( meth ) ec = DaoProcess_Call( proc, meth, self, NULL, 0 );
	}
	if( meth == NULL ){
		DaoValue_Print( self->xCinValue.value, stream, cycmap, proc );
	}else if( ec ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL );
	}else if( meth && proc->stackValues[0] ){
		DaoValue_Print( proc->stackValues[0], stream, cycmap, proc );
	}else{
		DaoStream_WriteString( stream, type->name );
		DaoStream_WriteChars( stream, buf );
	}
	if( inmap == NULL ) DMap_Delete( cycmap );
}
Exemplo n.º 23
0
static DMutex* DaoMT_GetMutex( DaoRoutine *routine, void *key )
{
	DNode *it;
	DMap *mutexes;
	DMutex *mutex = NULL;

	DMutex_Lock( & mainVmSpace->miscMutex );
	it = DMap_Find( routine->body->aux, DaoMT_RoutMutexSet );
	if( it == NULL ) it = DMap_Insert( routine->body->aux, DaoMT_RoutMutexSet, DHash_New(0,0) );
	mutexes = (DMap*) it->value.pVoid;
	it = DMap_Find( mutexes, key );
	if( it == NULL ){
		mutex = (DMutex*) dao_calloc(1,sizeof(DMutex));
		DMutex_Init( mutex );
		DMap_Insert( mutexes, key, mutex );
	}else{
		mutex = (DMutex*) it->value.pVoid;
	}
	DMutex_Unlock( & mainVmSpace->miscMutex );
	return mutex;
}
Exemplo n.º 24
0
DaoXmlParser* DaoXmlParser_New()
{
	DaoXmlParser *self = (DaoXmlParser*) dao_calloc( 1, sizeof(DaoXmlParser) );
	self->key = DString_New();
	self->value = DString_New();
	self->escape = DString_New();
	self->escapes = DHash_New( DAO_DATA_STRING, DAO_DATA_STRING );
	DString_SetChars( self->key, "lt" );
	DString_SetChars( self->value, "<" );
	DMap_Insert( self->escapes, self->key, self->value );
	DString_SetChars( self->key, "gt" );
	DString_SetChars( self->value, ">" );
	DMap_Insert( self->escapes, self->key, self->value );
	DString_SetChars( self->key, "amp" );
	DString_SetChars( self->value, "&" );
	DMap_Insert( self->escapes, self->key, self->value );
	DString_SetChars( self->key, "apos" );
	DString_SetChars( self->value, "'" );
	DMap_Insert( self->escapes, self->key, self->value );
	DString_SetChars( self->key, "quot" );
	DString_SetChars( self->value, "\"" );
	DMap_Insert( self->escapes, self->key, self->value );
	return self;
}
Exemplo n.º 25
0
/*
// C printf format: %[parameter][flags][width][.precision][length]type
//
// Dao writef format: %[flags][width][.precision]type[color]
//
// Where 'flags', 'width' and 'precision' will conform to the C format,
// but 'type' can only be:
//   d, i, o, u, x/X : for integer;
//   e/E, f/F, g/G : for float and double;
//   c/C : for character, C for local encoding;
//   s/S : for string, S for local encoding;
//   p : for any type, write address;
//   a : automatic, for any type, write in the default format;
// Namely the standard ones except 'n', and plus 'a'.
//
// Optional 'color' format will be in form of: [foreground:background], [foreground]
// or [:background]. The supported color name format will depend on the color printing
// handle. Mininum requirement is the support of the following 8 color names:
// black, white, red, green, blue, yellow, magenta, cyan.
*/
static void DaoIO_Writef0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N )
{
	DaoValue *value;
	DString *fmt2;
	DString *fgcolor = NULL;
	DString *bgcolor = NULL;
	DMap *cycmap = NULL;
	const char *convs = "asSpcCdiouxXfFeEgG";
	char F, *s, *end, *fg, *bg, *fmt, message[100];
	int i, k, id = 0;

	if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return;

	fmt2 = DString_New();
	for(i=0; i<N; i++){
		if( p[i]->type > DAO_ARRAY ){
			cycmap = DHash_New(0,0);
			break;
		}
	}

	s = p[0]->xString.value->chars;
	end = s + p[0]->xString.value->size;
	for(; s<end; s++){
		if( *s != '%' ){
			DaoStream_WriteChar( self, *s );
			continue;
		}

		fmt = s;
		s += 1;
		if( *s =='%' || *s == '[' ){
			DaoStream_WriteChar( self, *s );
			continue;
		}

		if( ++id >= N || p[id] == NULL ) goto NullParameter;
		value = p[id];

		/* flags: */
		while( *s == '+' || *s == '-' || *s == '#' || *s == '0' || *s == ' ' ) s += 1;
		while( isdigit( *s ) ) s += 1; /* width; */
		if( *s == '.' ){ /* precision: */
			s += 1;
			while( isdigit( *s ) ) s += 1;
		}
		DString_SetBytes( fmt2, fmt, s - fmt + 1 );
		if( strchr( convs, *s ) == NULL ){
			DaoProcess_RaiseWarning( proc, NULL, "invalid format conversion" );
			continue;
		}
		F = *s;
		s += 1;
		fg = bg = NULL;
		if( *s == '[' ){
			s += 1;
			fmt = s;
			while( isalnum( *s ) ) s += 1;
			if( fgcolor == NULL ) fgcolor = DString_New();
			DString_SetBytes( fgcolor, fmt, s - fmt );
			if( fgcolor->size ) fg = fgcolor->chars;
			if( *s == ':' ){
				s += 1;
				fmt = s;
				while( isalnum( *s ) ) s += 1;
				if( bgcolor == NULL ) bgcolor = DString_New();
				DString_SetBytes( bgcolor, fmt, s - fmt );
				if( bgcolor->size ) bg = bgcolor->chars;
			}
			if( *s != ']' ) goto WrongColor;
		}else{
			s -= 1;
		}
		if( fg || bg ){
			if( DaoStream_SetColor( self, fg, bg ) == 0 ) goto WrongColor;
		}
		self->format = fmt2->chars;
		if( F == 'c' || F == 'C' ){
			if( value->type != DAO_INTEGER ) goto WrongParameter;
			DString_Reset( fmt2, 0 );
			DString_AppendWChar( fmt2, value->xInteger.value );
			self->format = "%s";
			if( F == 'C' ) DString_ToLocal( fmt2 );
			DaoStream_WriteString( self, fmt2 );
		}else if( F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){
			if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter;
			DString_InsertChars( fmt2, "ll", fmt2->size-1, 0, 2 );
			self->format = fmt2->chars;
			DaoStream_WriteInt( self, DaoValue_GetInteger( value ) );
		}else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){
			if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter;
			DaoStream_WriteFloat( self, DaoValue_GetFloat( value ) );
		}else if( F == 's' && value->type == DAO_STRING ){
			DaoStream_WriteString( self, value->xString.value );
		}else if( F == 'S' && value->type == DAO_STRING ){
			DaoStream_WriteLocalString( self, value->xString.value );
		}else if( F == 'p' ){
			DaoStream_WritePointer( self, value );
		}else if( F == 'a' ){
			self->format = NULL;
			if( value->type > DAO_ARRAY ) DMap_Reset( cycmap );
			DaoValue_Print( value, self, cycmap, proc );
		}else{
			goto WrongParameter;
		}
		self->format = NULL;
		if( fg || bg ) DaoStream_SetColor( self, NULL, NULL );
		continue;
NullParameter:
		sprintf( message, "%i-th parameter is null!", id );
		DaoProcess_RaiseWarning( proc, NULL, message );
		continue;
WrongColor:
		sprintf( message, "%i-th parameter has wrong color format!", id );
		DaoProcess_RaiseWarning( proc, NULL, message );
		continue;
WrongParameter:
		self->format = NULL;
		if( fg || bg ) DaoStream_SetColor( self, NULL, NULL );
		sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", id, fmt2->chars );
		DaoProcess_RaiseWarning( proc, NULL, message );
	}
	if( cycmap ) DMap_Delete( cycmap );
	if( fgcolor ) DString_Delete( fgcolor );
	if( bgcolor ) DString_Delete( bgcolor );
	DString_Delete( fmt2 );
}
Exemplo n.º 26
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 );
}
Exemplo n.º 27
0
/*
// 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;
}