Пример #1
0
DaoXmlNode* DaoXmlNode_GetAncestor( DaoXmlNode *self, DString *name, int level )
{
	DaoXmlNode *node = self;
	for(; level > 0 && node != NULL; --level) node = node->parent;
	if( node && DString_EQ( node->name, name ) ) return node;
	return NULL;
}
Пример #2
0
int DaoXmlParser_ParseNode( DaoXmlParser *self, DaoXmlDOM *dom, DaoXmlNode *node )
{
	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	if( self->source >= self->end ) return 1;
	if( *self->source != '<' ) return 1;
	self->source += 1;

	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	if( DaoXmlParser_ParseIdentifier( self, node->name ) ) return 1;

	if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	while( self->source < self->end && isalpha( *self->source ) ){
		DaoXmlParser_ParseAttribute( self, self->key, self->value );
		DMap_Insert( node->attributes, self->key, self->value );
		if( DaoXmlParser_SkipWhiteSpaces( self ) ) return 1;
	}
	if( self->source >= self->end ) return 1;
	if( *self->source == '/' ){
		self->source += 1;
		if( self->source >= self->end ) return 1;
		if( *self->source != '>' ) return 1;
		self->source += 1;
		return 0;
	}
	if( *self->source != '>' ) return 1;
	self->source += 1;

	if( DaoXmlParser_ParseNodeContent( self, dom, node ) ) return 1;
	if( DaoXmlParser_ParseChar( self, '<' ) ) return 1;
	if( DaoXmlParser_ParseChar( self, '/' ) ) return 1;
	if( DaoXmlParser_ParseIdentifier( self, self->value ) ) return 1;
	if( DString_EQ( node->name, self->value ) == 0 ) return 1;
	if( DaoXmlParser_ParseChar( self, '>' ) ) return 1;
	return 0;
}
Пример #3
0
DaoXmlNode* DaoXmlNode_GetChild( DaoXmlNode *self, DString *name )
{
	daoint i;
	for(i=0; i<self->children->size; ++i){
		DaoXmlNode *child = (DaoXmlNode*) self->children->items.pVoid[i];
		if( DString_EQ( child->name, name ) ) return child;
	}
	return NULL;
}
Пример #4
0
DaoXmlNode* DaoXmlNode_GetChildByAttribute( DaoXmlNode *self, DString *key, DString *value )
{
	daoint i;
	for(i=0; i<self->children->size; ++i){
		DaoXmlNode *child = (DaoXmlNode*) self->children->items.pVoid[i];
		DString *att = DaoXmlNode_GetAttribute(  child, key );
		if( att && DString_EQ( att, value ) ) return child;
	}
	return NULL;
}
Пример #5
0
void DaoRoutine_MakeName( DaoRoutine *self, DString *name, int max1, int max2, int max3 )
{
	DString *hostName = self->routHost ? self->routHost->name : NULL;
	DaoType *routType = self->routType;
	int M = (routType->attrib & DAO_TYPE_SELF) != 0;
	int N = routType->nested->size;
	int i;

	DString_Reset( name, 0 );

	/* For builtin containers, whose methods may have no routHost set: */
	if( hostName == NULL && M ) hostName = routType->nested->items.pType[0]->aux->xType.name;

	/*
	// Mixin classes have methods converted from constructors of component classes.
	// These methods still have the DAO_ROUT_INITOR flag. So checking the names is
	// the better way to use here.
	*/
	if( hostName && ! DString_EQ( self->routName, hostName ) ){
		if( hostName->size + self->routName->size < (max1-2) ){
			DString_Append( name, hostName );
			DString_AppendChars( name, "::" );
			DString_Append( name, self->routName );
		}else{
			DString_PartialAppend( name, hostName, max1/2-1 );
			DString_AppendChars( name, "::" );
			DString_PartialAppend( name, self->routName, max1/2-1 );
		}
	}else{
		DString_PartialAppend( name, self->routName, max1 );
	}
	if( max3 == 0 ){
		DString_AppendChars( name, "()" );
		return;
	}
	DString_AppendChars( name, "( " );
	if( N == M+1 ){
		DaoType *type = routType->nested->items.pType[M];
		DString_PartialAppend( name, type->name, 2*max2 );
	}else{
		for(i=M; i<N; ++i){
			DaoType *type = routType->nested->items.pType[i];
			if( i > M ) DString_AppendChars( name, ", " );
			if( i < M + max3 ){
				DString_PartialAppend( name, type->name, max2 );
			}else{
				DString_AppendChars( name, "~~" );
				break;
			}
		}
	}
	DString_AppendChars( name, " )" );
}
Пример #6
0
static int DaoRoutine_GetFieldIndex( DaoRoutine *self, DString *name )
{
	DString none = DString_WrapMBS( "" );
	DaoString str = {DAO_STRING,0,0,0,0,NULL};
	DaoString *s = & str;
	daoint i;
	if( name == NULL ) name = & none;
	for(i=0; i<self->routConsts->items.size; ++i){
		DaoValue *item = DaoList_GetItem( self->routConsts, i );
		DString *field = DaoValue_TryGetString( item );
		if( field == NULL ) continue;
		if( DString_EQ( field, name ) ) return i;
	}
	str.data = name;
	return DaoRoutine_AddConstant( self, (DaoValue*) s );
}
Пример #7
0
int DArray_MatchAffix( DArray *self, DString *name )
{
	daoint i, pos;
	if( self == NULL ) return 0;
	for(i=0; i<self->size; ++i){
		DString tmp, *pat = self->items.pString[i];
		daoint pos = DString_FindChar( pat, '~', 0 );
		if( pos < 0 ){
			if( DString_EQ( pat, name ) ) return 1;
			continue;
		}
		if( pos ){
			tmp = *pat;
			tmp.size = pos;
			if( DString_Find( name, & tmp, 0 ) != 0 ) continue;
		}
		if( pos < pat->size-1 ){
			tmp = DString_WrapMBS( pat->mbs + pos + 1 );
			if( DString_RFind( name, & tmp, -1 ) != (name->size - 1) ) continue;
		}
		return 1;
	}
	return 0;
}
Пример #8
0
static int DaoToken_EQ( DaoToken *self, DaoToken *other )
{
	if( self->name != other->name ) return 0;
	if( self->name <= DTOK_WCS ) return DString_EQ( & self->string, & other->string );
	return 1;
}
Пример #9
0
int DaoParser_ParseMacro( DaoParser *self, int start )
{
	int rb1, rb2, i = start, N = self->tokens->size;
	DaoToken **toks = self->tokens->items.pToken;
	DaoMacro *macro;
	DString *lang = NULL;
	DArray  *stops;
	DMap  *markers;

	if( start + 5 >= N ) return -1;
	if( toks[start+1]->type != DTOK_LCB ){
		lang = & toks[start+1]->string;
		if( toks[start+1]->type != DTOK_IDENTIFIER ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		if( lang->size == 3 && strcmp( lang->mbs, "dao" ) == 0 ){
			DaoParser_Error( self, DAO_TOKEN_NEED_NAME, lang );
			return -1;
		}
		start += 1;
	}
	if( toks[start+1]->name != DTOK_LCB ) return -1;

	self->curLine = toks[start]->line;
	rb1 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, -1 );
	if( rb1 <0 || rb1 +3 >= N ) return -1;
	if( toks[rb1+1]->name != DKEY_AS || toks[rb1+2]->name != DTOK_LCB ){
		DaoParser_Error( self, DAO_CTW_INV_MAC_DEFINE, NULL );
		return -1;
	}
	rb2 = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, rb1 + 1, -1 );
	if( rb2 <0 ) return -1;

	/*
	   for( i=start; i<rb2; i++ ) printf( "%s  ", toks[i]->string.mbs ); printf("\n");
	 */

	macro = DaoMacro_New();

	if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1 ) ==0 ){
		DaoMacro_Delete( macro );
		return -1;
	}
	if( macro->macroMatch->units->size >0 ){
		DMacroUnit *unit = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0];
		if( unit->type != DMACRO_TOK )
			DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string );
	}
	if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos;
	if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2 ) ==0 ){
		DaoMacro_Delete( macro );
		return -1;
	}
	markers = DMap_New(D_STRING,0);

	for(i=start+2; i<rb1; i++){
		if( toks[i]->string.mbs[0] == '$' ){
			if( MAP_Find( markers, & toks[i]->string ) != NULL ){
				self->curLine = toks[i]->line;
				DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, & toks[i]->string );
				return 0;
			}
			MAP_Insert( markers, & toks[i]->string, 0 );
		}
	}
	DMap_Clear( markers );
	i = rb1+3;
	if( DString_EQ( & toks[start+2]->string, & toks[rb1+3]->string ) ) i ++;
	while( i < rb2 ){
		char ch = toks[i]->string.mbs[0];
		if( ch != '$' && ch != '\\' && ch != '\'' ){
			if( MAP_Find( markers, & toks[i]->string ) == NULL ){
				DArray_Append( macro->keyListApply, & toks[i]->string );
				MAP_Insert( markers, & toks[i]->string, 0 );
			}
		}
		i ++;
	}

	stops = DArray_New(D_TOKEN);
	DMacroGroup_SetStop( macro->macroMatch, stops );
	DMacroGroup_FindVariables( macro->macroMatch );
	DArray_Clear( stops );
	DMacroGroup_SetStop( macro->macroApply, stops );
	DaoNamespace_AddMacro( self->nameSpace, lang, & toks[start+2]->string, macro );
	DArray_Delete( stops );
	DMap_Delete( markers );
	return rb2;
}
Пример #10
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 );
}