Beispiel #1
0
/* breadth-first search */
void DaoClass_Parents( DaoClass *self, DArray *parents, DArray *offsets )
{
	DaoValue *dbase;
	DaoClass *klass;
	DaoCdata *cdata;
	DaoTypeBase *typer;
	daoint i, j, offset;
	DArray_Clear( parents );
	DArray_Clear( offsets );
	DArray_Append( parents, self );
	DArray_Append( offsets, self->objDataName->size );
	for(i=0; i<parents->size; i++){
		dbase = parents->items.pValue[i];
		offset = offsets->items.pInt[i];
		if( dbase->type == DAO_CLASS ){
			klass = (DaoClass*) dbase;
			if( klass->parent ){
				DaoClass *cls = (DaoClass*) klass->parent;
				DArray_Append( parents, klass->parent );
				DArray_Append( offsets, (daoint) offset );
				offset += (cls->type == DAO_CLASS) ? cls->objDataName->size : 0;
			}
		}else if( dbase->type == DAO_CTYPE ){
			cdata = (DaoCdata*) dbase;
			typer = cdata->ctype->kernel->typer;
			for(j=0; j<DAO_MAX_CDATA_SUPER; j++){
				if( typer->supers[j] == NULL ) break;
				DArray_Append( parents, typer->supers[j]->core->kernel->abtype->aux );
				DArray_Append( offsets, (daoint) offset );
			}
		}
	}
}
Beispiel #2
0
/* Backward traverse the macro units and set stopping tokens for each unit.
 * A stopping token is defined as the content of a macro unit of type DMACRO_TOK.
 * XXX, also define stopping token by DMACRO_BR units?
 */
static void DMacroGroup_SetStop( DMacroGroup *self, DArray *stops )
{
	DMacroGroup *group;
	daoint i, j;
	/*
	   printf( "stop : %i\n", stops->size );
	 */

	for(i=self->units->size-1; i>=0; i--){
		DMacroUnit *unit = (DMacroUnit*) self->units->items.pVoid[i];
		if( unit->type == DMACRO_GRP || unit->type == DMACRO_ALT ){
			group = (DMacroGroup*) unit;
			/* self->stops as temporary array: */
			DArray_Assign( self->stops, stops );
			/* recursive set stopping tokens for macro groups: */
			DMacroGroup_SetStop( group, self->stops );
			/* if the group has to be presented at least once,
			 * no propagating the stopping tokens to the previous macro units. */
			if( group->repeat > DMACRO_ZERO_OR_MORE ) DArray_Clear( stops );
			/* add stopping token, why only one ? XXX */
			if( group->stops->size >0) DArray_PushFront( stops, group->stops->items.pString[0] );
		}else if( unit->type == DMACRO_TOK ){
			/*
			   printf( "%s", unit->marker->mbs );
			 */
			DArray_Clear( stops );
			/* define a stopping token */
			DArray_Append( stops, unit->marker );
			DArray_Append( unit->stops, unit->marker );
		}else{
			/*
			   printf( "%s", unit->marker->mbs );
			 */
			for(j=0; j<stops->size; j++) DArray_Append( unit->stops, stops->items.pString[j] );
		}
		/*
		   printf( " : %i;  ", unit->stops->size );
		 */
	}
	if( self->repeat == DMACRO_ZERO_OR_MORE || self->repeat == DMACRO_ONE_OR_MORE ){
		/* this is fine for DMACRO_GRP unit, what about DMACRO_ALT unit? XXX */
		if( self->units->size >1 ){
			DMacroUnit *first = (DMacroUnit*) self->units->items.pVoid[0];
			DMacroGroup_AddStop( self, first->stops );
		}
	}
	DArray_Assign( self->stops, stops );
	/*
	   printf( "group : %i\n", self->stops->size );
	 */
}
Beispiel #3
0
void DaoxDataFrame_Reset( DaoxDataFrame *self )
{
	daoint i;
	for(i=0; i<self->columns->size; ++i){
		DArray_Append( self->caches, self->columns->items.pVoid[i] );
	}
	for(i=0; i<3; ++i){
		self->dims[i] = 0;
		self->groups[i] = 0;
		DArray_Clear( self->labels[i] );
	}
	GC_DecRC( self->original );
	self->original = NULL;
	DArray_Clear( self->columns );
}
Beispiel #4
0
void DArray_Delete( DArray *self )
{
#ifdef DAO_GC_PROF
	daoCountArray --;
#endif
	DArray_Clear( self );
	dao_free( self );
}
Beispiel #5
0
void DArray_Delete( DArray *self )
{
#ifdef DAO_USE_GC_LOGGER
	daoCountArray --;
#endif
	DArray_Clear( self );
	dao_free( self );
}
Beispiel #6
0
void DaoxDataFrame_Clear( DaoxDataFrame *self )
{
	daoint i;
	DaoxDataFrame_Reset( self );
	for(i=0; i<self->caches->size; ++i){
		DaoxDataColumn_Delete( (DaoxDataColumn*) self->caches->items.pVoid[i] );
	}
	DArray_Clear( self->caches );
}
Beispiel #7
0
void DaoProcess_PopValues( DaoProcess *self, int N )
{
	if( N < 0 ) return;
	if( N >= (int)self->factory->size ){
		DArray_Clear( self->factory );
	}else{
		DArray_Erase( self->factory, self->factory->size - N, N );
	}
}
Beispiel #8
0
void DArray_Assign( DArray *left, DArray *right )
{
	daoint i;
	assert( left->type == right->type || (left->type == DAO_DATA_VALUE && right->type == 0) );

	if( left == right ) return;
	if( right->size == 0 ){
		DArray_Clear( left );
		return;
	}
	if( left->type ){
		DArray_Clear( left);
		for( i=0; i<right->size; i++ ) DArray_Append( left, right->items.pVoid[i] );
	}else{
		DArray_Resize( left, right->size, NULL );
		for( i=0; i<right->size; i++ ) left->items.pVoid[i] = right->items.pVoid[i];
	}
}
Beispiel #9
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 );
}
Beispiel #10
0
void DCondVar_BroadCast( DCondVar *self )
{
	DThread *thread;
	int i;
	DMutex_Lock( & self->thdMutex );
	for( i=0; i<self->thdWaiting->size; i++ ){
		thread = (DThread*) self->thdWaiting->items.pVoid[i];
		SetEvent( thread->condv.myCondVar );
	}
	DArray_Clear( self->thdWaiting );
	DMutex_Unlock( & self->thdMutex );
}
Beispiel #11
0
static void DaoxDataFrame_MakeFullSlice( DaoxDataFrame *self, DArray *slices )
{
	DVector *tmp = DVector_New( sizeof(daoint) );
	daoint i, D = 3;

	/* slices: DArray<DVector<int> > */
	DArray_Clear( slices );
	DVector_Resize( tmp, 3 );
	tmp->data.daoints[0] = SLICE_RANGE;
	tmp->data.daoints[2] = 0;
	for(i=0; i<D; ++i){
		tmp->data.daoints[1] = self->dims[i];
		DArray_Append( slices, tmp );
	}
	DVector_Delete( tmp );
}
Beispiel #12
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;
}
Beispiel #13
0
static void DaoMT_Functional( DaoProcess *proc, DaoValue *P[], int N, int F )
{
	DMutex mutex;
	DCondVar condv;
	DaoTaskData *tasks;
	DaoValue *param = P[0];
	DaoValue *result = NULL;
	DaoList *list = NULL;
	DaoArray *array = NULL;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	int i, entry, threads = P[1]->xInteger.value;
	daoint index = -1, status = 0, joined = 0;
	DNode *node = NULL;

	switch( F ){
	case DVM_FUNCT_MAP :
		if( param->type == DAO_ARRAY ){
			array = DaoProcess_PutArray( proc );
			result = (DaoValue*) array;
		}else{
			list = DaoProcess_PutList( proc );
			result = (DaoValue*) list;
		}
		break;
	case DVM_FUNCT_APPLY : DaoProcess_PutValue( proc, param ); break;
	case DVM_FUNCT_FIND : DaoProcess_PutValue( proc, dao_none_value ); break;
	}
	if( threads <= 0 ) threads = 2;
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	if( list ){
		DArray_Clear( & list->items );
		if( param->type == DAO_LIST ) DArray_Resize( & list->items, param->xList.items.size, NULL );
		if( param->type == DAO_MAP ) DArray_Resize( & list->items, param->xMap.items->size, NULL );
#ifdef DAO_WITH_NUMARRAY
	}else if( array && F == DVM_FUNCT_MAP ){
		DaoArray_GetSliceShape( (DaoArray*) param, & array->dims, & array->ndim );
		DaoArray_ResizeArray( array, array->dims, array->ndim );
#endif
	}

	DMutex_Init( & mutex );
	DCondVar_Init( & condv );
	entry = proc->topFrame->entry;
	tasks = (DaoTaskData*) dao_calloc( threads, sizeof(DaoTaskData) );
	DaoProcess_PopFrame( proc );
	for(i=0; i<threads; i++){
		DaoTaskData *task = tasks + i;
		task->param = param;
		task->result = result;
		task->proto = proc;
		task->sect = sect;
		task->funct = F;
		task->entry = entry;
		task->first = i;
		task->step = threads;
		task->index = & index;
		task->node = & node;
		task->joined = & joined;
		task->condv = & condv;
		task->mutex = & mutex;
		task->clone = DaoVmSpace_AcquireProcess( proc->vmSpace );
		task->clone->mutex = & mutex;
		if( i ) DaoCallServer_AddTask( DaoMT_RunFunctional, task, 1 );
	}
	DaoMT_RunFunctional( tasks );

	DMutex_Lock( & mutex );
	while( joined < threads ) DCondVar_TimedWait( & condv, & mutex, 0.01 );
	DMutex_Unlock( & mutex );

	for(i=0; i<threads; i++){
		DaoTaskData *task = tasks + i;
		DaoVmSpace_ReleaseProcess( proc->vmSpace, task->clone );
		status |= task->status;
	}
	if( F == DVM_FUNCT_FIND ){
		DaoTuple *tuple = DaoProcess_PutTuple( proc, 0 );
		if( param->type == DAO_LIST && index != -1 ){
			DaoValue **items = param->xList.items.items.pValue;
			GC_ShiftRC( items[index], tuple->items[1] );
			tuple->items[1] = items[index];
			tuple->items[0]->xInteger.value = index;
		}else if( param->type == DAO_MAP && node ){
			GC_ShiftRC( node->key.pValue, tuple->items[0] );
			GC_ShiftRC( node->value.pValue, tuple->items[1] );
			tuple->items[0] = node->key.pValue;
			tuple->items[1] = node->value.pValue;
		}
	}
	if( status ) DaoProcess_RaiseException( proc, DAO_ERROR, "code section execution failed!" );
	DMutex_Destroy( & mutex );
	DCondVar_Destroy( & condv );
	dao_free( tasks );
}
Beispiel #14
0
void DaoNamespace_Restore( DaoNamespace *self, DaoProcess *proc, FILE *fin )
{
	DaoParser *parser = DaoParser_New();
	DString *line = DString_New(1);
	DArray *types = DArray_New(0);
	DArray *tokens = parser->tokens;
	DMap *omap = DMap_New(0,0);
	DString *name;
	DNode *node;

	parser->nameSpace = self;
	parser->vmSpace = self->vmSpace;
	while( DaoFile_ReadLine( fin, line ) ){
		DaoValue *value = NULL;
		int st = DAO_GLOBAL_VARIABLE;
		int pm = DAO_DATA_PRIVATE;
		int i, n, start = 0;
		char *mbs;

		DaoParser_LexCode( parser, line->mbs, 0 );
		if( tokens->size == 0 ) continue;
		name = & tokens->items.pToken[start]->string;
		if( name->size == 6 && strcmp( name->mbs, "inputs" ) == 0 ){
			if( tokens->size < 3 ) continue;
			DString_Clear( line );
			n = tokens->items.pToken[start+2]->string.size;
			mbs = tokens->items.pToken[start+2]->string.mbs;
			for(i=0; i<n; i++){
				char c1 = mbs[i];
				char c2 = mbs[i+1];
				if( c1 < 'A' || c1 > 'P' ) continue;
				DString_AppendChar( line, (char)((c1-'A')*16 + (c2-'A')) );
				i += 1;
			}
			/* printf( "%s\n", line->mbs ); */
			DaoProcess_Eval( proc, self, line->mbs );
			continue;
		}
		switch( tokens->items.pToken[start]->name ){
		case DKEY_PRIVATE   : pm = DAO_DATA_PRIVATE;   start += 1; break;
		case DKEY_PROTECTED : pm = DAO_DATA_PROTECTED; start += 1; break;
		case DKEY_PUBLIC    : pm = DAO_DATA_PUBLIC;    start += 1; break;
		}
		if( start >= tokens->size ) continue;
		switch( tokens->items.pToken[start]->name ){
		case DKEY_CONST : st = DAO_GLOBAL_CONSTANT; start += 1; break;
		case DKEY_VAR   : st = DAO_GLOBAL_VARIABLE; start += 1; break;
		}
		if( tokens->items.pToken[start]->name != DTOK_IDENTIFIER ) continue;
		name = & tokens->items.pToken[start]->string;
		start += 1;
		if( start + 3 >= tokens->size ) continue;
		if( tokens->items.pToken[start]->name != DTOK_ASSN ) continue;
		start += 1;

		DArray_Clear( parser->errors );
		DArray_Clear( types );
		DArray_PushFront( types, NULL );
		DaoParser_Deserialize( parser, start, tokens->size-1, &value, types, self, proc, omap );
		if( value == NULL ) continue;
		node = DMap_Find( self->lookupTable, name );
		if( node ) continue;
		if( st == DAO_GLOBAL_CONSTANT ){
			DaoNamespace_AddConst( self, name, value, pm );
		}else{
			DaoNamespace_AddVariable( self, name, value, NULL, pm );
		}
	}
	DMap_Delete( omap );
	DString_Delete( line );
	DArray_Delete( types );
	DaoParser_Delete( parser );
}
Beispiel #15
0
static int DaoParser_MacroApply( DaoParser *self, DArray *tokens,
		DMacroGroup *group, DMap *tokMap, DMap *used,
		int level, DString *tag, int pos0, int adjust )
{
	DMacroUnit **units = (DMacroUnit**) group->units->items.pVoid;
	DMacroUnit  *unit;
	DMacroGroup *grp;
	DMacroNode *node, *node2;
	DArray *toks = DArray_New(D_TOKEN);
	DaoToken *tk = DaoToken_New();
	DaoToken *tt = NULL;
	DNode  *kwnode = NULL;
	DMap *check = NULL;
	DMap one = { NULL, 0, 0, 0 };
	int M, N = group->units->size;
	int i, j, gid = -1;
	int repeated = 0;
	int start_mbs = -1;
	int start_wcs = -1;
	int squote, dquote;

	if( group->repeat != DMACRO_AUTO ) level ++;

	for( i=0; i<N; i++ ){
		unit = units[i];
		if( tokens->size >0 ) pos0 = tokens->items.pToken[ tokens->size -1 ]->line;
		self->curLine = pos0;
		/*
		   printf( "apply unit %i: %i\n", i, unit->type );
		 */
		switch( unit->type ){
		case DMACRO_TOK :
			squote = unit->marker->type == DTOK_ESC_SQUO;
			dquote = unit->marker->type == DTOK_ESC_DQUO;
			if( (squote && start_mbs >=0) || (dquote && start_wcs >=0) ){
				int qstart = squote ? start_mbs : start_wcs;
				tt = tokens->items.pToken[ qstart ];
				for(j=qstart+1,M=tokens->size; j<M; j++){
					DaoToken *jtok = tokens->items.pToken[j];
					int t = j ? tokens->items.pToken[j-1]->type : 0;
					if( t == DTOK_IDENTIFIER && jtok->type == t )
						DString_AppendChar( & tt->string, ' ' );
					DString_Append( & tt->string, & jtok->string );
				}
				if( squote ){
					DString_AppendChar( & tt->string, '\'' );
					DArray_Erase( tokens, start_mbs+1, tokens->size );
				}else{
					DString_AppendChar( & tt->string, '\"' );
					DArray_Erase( tokens, start_wcs+1, tokens->size );
				}
				start_mbs = -1;
				break;
			}else if( squote ){
				start_mbs = tokens->size;
				DArray_Append( tokens, unit->marker );
				tt = tokens->items.pToken[ start_mbs ];
				tt->type = tt->name = DTOK_MBS;
				DString_SetMBS( & tt->string, "\'" );
				break;
			}else if( dquote ){
				start_wcs = tokens->size;
				DArray_Append( tokens, unit->marker );
				tt = tokens->items.pToken[ start_wcs ];
				tt->type = tt->name = DTOK_WCS;
				DString_SetMBS( & tt->string, "\"" );
				break;
			}
			DArray_Append( tokens, unit->marker );
			tokens->items.pToken[ tokens->size-1 ]->cpos += adjust;
			break;
		case DMACRO_VAR :
			DaoToken_Assign( tk, unit->marker );
			DString_Append( & tk->string, tag );
			DArray_Append( tokens, tk );
			break;
		case DMACRO_EXP :
		case DMACRO_ID :
		case DMACRO_OP :
		case DMACRO_BL :
		case DMACRO_IBL :

			kwnode = MAP_Find( tokMap, & unit->marker->string );
			if( kwnode ==NULL ){
				DaoParser_Error( self, DAO_CTW_UNDEF_MAC_MARKER, & unit->marker->string );
				goto Failed;
			}
			node = (DMacroNode*) kwnode->value.pVoid;
			kwnode = MAP_Find( used, unit );
			if( kwnode == NULL ){
				DMap_Insert( used, unit, & one );
				kwnode = MAP_Find( used, unit );
			}
			check = (DMap*) kwnode->value.pVoid;
			repeated = 1;

			/*
			   printf( ">>>\n%s level %i: \n", unit->marker->string.mbs, level );
			   DMacroNode_Print( node );
			   printf( "\n" );
			 */
			/* search a leaf */
			node2 = DMacroNode_FindLeaf( node, check, level );
			if( node2 ){
				/*
				   printf( "appending tokens\n" );
				   DMacroNode_Print( node2 );
				   printf( "\n" );
				 */
				DArray_InsertArray( tokens, tokens->size, node2->leaves, 0, -1 );
				DMap_Insert( check, node2, NULL );
				/* DArray_Clear( node2->leaves ); */
			}else{
				DMacroNode_RemoveEmptyLeftBranch( node, level );
				goto Failed;
			}
			break;
		case DMACRO_GRP :
		case DMACRO_ALT :
			grp = (DMacroGroup*) unit;
			DArray_Clear( toks );
			j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
			switch( grp->repeat ){
			case DMACRO_AUTO :
			case DMACRO_ONE :
				if( j <0 && group->type != DMACRO_ALT ) goto Failed;
				repeated = (j>0);
				if( j >=0 ){
					gid = i;
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				break;
			case DMACRO_ZERO_OR_ONE :
				gid = i;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				break;
			case DMACRO_ZERO_OR_MORE :
				gid = i;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				while( j >0 ){
					DArray_Clear( toks );
					j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
					if( j >0 ){
						DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
					}
				}
				break;
			case DMACRO_ONE_OR_MORE :
				if( j <0 && group->type != DMACRO_ALT ) goto Failed;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}

				while( j >0 ){
					gid = i;
					DArray_Clear( toks );
					j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
					if( j >0 ){
						DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
					}
				}
				break;
			}
			break;
		default : goto Failed;
		}
		if( group->type == DMACRO_ALT && gid >=0 ) break;
	}
	if( group->repeat != DMACRO_AUTO ) level --;
	if( group->type == DMACRO_ALT && gid <0 ) goto Failed;
	DaoToken_Delete( tk );
	DArray_Delete( toks );
	return repeated;
Failed :
	DaoToken_Delete( tk );
	DArray_Delete( toks );
	return -1;
}
Beispiel #16
0
int DaoParser_ParseMacro( DaoParser *self, int start )
{
	int rb1, rb2, i = start, N = self->tokens->size;
	DaoToken **toks = self->tokens->items.pToken;
	DMacroUnit *first;
	DaoMacro *macro;
	DString *lang = NULL;
	DArray  *stops;
	DMap  *markers;
	DNode *it;

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

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

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

	macro = DaoMacro_New();
	markers = DMap_New(D_STRING,0);

	if( DaoParser_MakeMacroGroup( self, macro->macroMatch, macro->macroMatch, start+2, rb1, markers, NULL ) ==0 ){
		goto Error;
	}
	if( macro->macroMatch->units->size == 0 ) goto Error;
	first = (DMacroUnit*) macro->macroMatch->units->items.pVoid[0];
	if( first->type != DMACRO_TOK ){
		DaoParser_Error( self, DAO_CTW_INV_MAC_FIRSTOK, & toks[i]->string );
		goto Error;
	}
	for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){
		if( it->value.pInt > 1 ){
			DaoParser_Error( self, DAO_CTW_REDEF_MAC_MARKER, it->key.pString );
			goto Error;
		}
	}

	DMap_Clear( markers );
	if( toks[rb1+3]->line != toks[rb1+2]->line ) macro->macroApply->cpos = toks[rb1+3]->cpos;
	if( DaoParser_MakeMacroGroup( self, macro->macroApply, macro->macroApply, rb1+3, rb2, NULL, markers ) ==0 ){
		goto Error;
	}
	for(it=DMap_First(markers); it; it=DMap_Next(markers,it)){
		DArray_Append( macro->keyListApply, it->key.pString );
	}

	stops = DArray_New(D_TOKEN);
	DMacroGroup_SetStop( macro->macroMatch, stops );
	DMacroGroup_FindVariables( macro->macroMatch );
	DArray_Clear( stops );
	DMacroGroup_SetStop( macro->macroApply, stops );
	DaoNamespace_AddMacro( self->nameSpace, lang, & first->marker->string, macro );
	DArray_Delete( stops );
	DMap_Delete( markers );
	return rb2;
Error:
	DaoMacro_Delete( macro );
	DMap_Delete( markers );
	return -1;
}
Beispiel #17
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 );
}
Beispiel #18
0
/* assumed to be called before parsing class body */
int DaoClass_DeriveClassData( DaoClass *self )
{
	DaoType *type;
	DaoValue *value;
	DString *mbs;
	DNode *it, *search;
	DaoMethodFields *mf;
	daoint i, j, k, id;

	if( DaoCass_DeriveMixinData( self ) == 0 ) return 0;

	mbs = DString_New(1);
	mf = DaoMethodFields_New();

	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 );

	self->cstParentStart = self->constants->size;
	self->glbParentStart = self->variables->size;

	DVector_PushUshort( self->offsets, self->constants->size );
	DVector_PushUshort( self->offsets, self->variables->size );
	if( self->parent && self->parent->type == DAO_CLASS ){
		DaoClass *klass = (DaoClass*) self->parent;
		DArray_Append( self->clsType->bases, klass->clsType );
		DArray_Append( self->objType->bases, klass->objType );
		DArray_AppendArray( self->cstDataName, klass->cstDataName );
		DArray_AppendArray( self->glbDataName, klass->glbDataName );
		for(j=0; j<klass->constants->size; ++j){
			DaoValue *cst = klass->constants->items.pConst[j]->value;
			DArray_Append( self->constants, klass->constants->items.pVoid[j] );
		}
		for(j=0; j<klass->variables->size; ++j){
			DArray_Append( self->variables, klass->variables->items.pVoid[j] );
		}
		for(it=DMap_First(klass->lookupTable); it; it=DMap_Next(klass->lookupTable,it)){
			daoint pm = LOOKUP_PM( it->value.pInt );
			daoint st = LOOKUP_ST( it->value.pInt );
			daoint up = LOOKUP_UP( it->value.pInt );
			daoint id = LOOKUP_ID( it->value.pInt );
			DaoValue *cst;
			if( st == DAO_CLASS_CONSTANT ){
				id = LOOKUP_ID( it->value.pInt );
				cst = klass->constants->items.pConst[id]->value;
				if( cst->type == DAO_ROUTINE ){
					DArray_Append( mf->names, it->key.pString );
					DArray_Append( mf->perms, IntToPointer( pm ) );
					DArray_Append( mf->routines, cst );
				}
			}
			if( st == DAO_OBJECT_VARIABLE ) continue;
			if( pm == DAO_DATA_PRIVATE ) continue;
			if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
			switch( st ){
			case DAO_CLASS_CONSTANT : id += self->cstParentStart; break;
			case DAO_CLASS_VARIABLE : id += self->glbParentStart; break;
			case DAO_OBJECT_VARIABLE : continue;
			}
			id = LOOKUP_BIND( st, pm, up+1, id );
			DMap_Insert( self->lookupTable, it->key.pString, (void*)id );
		}
	}else if( self->parent && self->parent->type == DAO_CTYPE ){
		DaoCtype *cdata = (DaoCtype*) self->parent;
		DaoTypeKernel *kernel = cdata->ctype->kernel;
		DaoTypeBase *typer = kernel->typer;
		DMap *methods = kernel->methods;
		DMap *values = kernel->values;

		DArray_Append( self->clsType->bases, cdata->ctype );
		DArray_Append( self->objType->bases, cdata->cdtype );
		DaoClass_AddConst( self, cdata->ctype->name, (DaoValue*)cdata, DAO_DATA_PUBLIC );

		if( kernel->SetupValues ) kernel->SetupValues( kernel->nspace, kernel->typer );
		if( kernel->SetupMethods ) kernel->SetupMethods( kernel->nspace, kernel->typer );

		DaoCdataType_SpecializeMethods( cdata->ctype );
		kernel = cdata->ctype->kernel;
		values = kernel->values;
		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 == NULL ) continue;
				if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
				id = self->constants->size;
				id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id );
				DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) );
				DArray_Append( self->cstDataName, it->key.pString );
				DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) );
			}
		}
		for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){
			if( DMap_Find( self->lookupTable, it->key.pString ) ) continue;
			id = self->constants->size;
			id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id );
			DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) );
			DArray_Append( self->cstDataName, it->key.pString );
			DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) );

			DArray_Append( mf->names, it->key.pString );
			DArray_Append( mf->perms, IntToPointer( DAO_DATA_PUBLIC ) );
			DArray_Append( mf->routines, it->value.pValue );
		}
	}
	DaoClass_SetupMethodFields( self, mf );
	DaoMethodFields_Delete( mf );

	self->cstParentEnd = self->constants->size;
	self->glbParentEnd = self->variables->size;

#if 0
	for(j=0; j<self->constants->size; ++j){
		DaoValue *value = self->constants->items.pConst[j]->value;
		DaoRoutine *routine = (DaoRoutine*) value;
		printf( "%3i: %3i %s\n", j, value->type, self->cstDataName->items.pString[j]->mbs );
		if( value->type != DAO_ROUTINE ) continue;
		printf( "%3i: %3i %s\n", j, value->type, routine->routName->mbs );
		if( routine->overloads ){
			DArray *routs = routine->overloads->routines;
			for(k=0; k<routs->size; ++k){
				DaoRoutine *rout = routs->items.pRoutine[k];
			}
		}else{
			if( routine->attribs & DAO_ROUT_PRIVATE ) continue;
		}
	}
	for(it=DMap_First(self->lookupTable); it; it=DMap_Next(self->lookupTable,it)){
		printf( "%s %i\n", it->key.pString->mbs, it->value.pInt );
		if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue;
		DaoValue *value = DaoClass_GetConst( self, it->value.pInt );
		printf( "%i\n", value->type );
	}
#endif

	DString_Delete( mbs );
	return 1;
}