Exemple #1
0
/* assumed to be called after parsing class body */
void DaoClass_DeriveObjectData( DaoClass *self )
{
	DaoType *type;
	DaoValue *value;
	DArray *parents, *offsets;
	DString *mbs;
	DNode *search;
	daoint i, id, perm, index, offset = 0;

	self->objDefCount = self->objDataName->size;
	offset = self->objDataName->size;
	mbs = DString_New(1);

	parents = DArray_New(0);
	offsets = DArray_New(0);
	DaoClass_Parents( self, parents, offsets );
	for( i=0; i<self->superClass->size; i++){
		if( self->superClass->items.pValue[i]->type == DAO_CLASS ){
			DaoClass *klass = self->superClass->items.pClass[i];

			/* for properly arrangement object data: */
			for( id=0; id<klass->objDataName->size; id ++ ){
				DString *name = klass->objDataName->items.pString[id];
				DaoVariable *var = klass->instvars->items.pVar[id];
				var = DaoVariable_New( var->value, var->dtype );
				DArray_Append( self->objDataName, name );
				DArray_Append( self->instvars, var );
				DaoValue_MarkConst( (DaoValue*) var->value );
			}
			offset += klass->objDataName->size;
		}
	}
	for(i=1; i<parents->size; i++){
		DaoClass *klass = parents->items.pClass[i];
		offset = offsets->items.pInt[i]; /* plus self */
		if( klass->type == DAO_CLASS ){
			/* For object data: */
			for( id=0; id<klass->objDataName->size; id ++ ){
				DString *name = klass->objDataName->items.pString[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 );
				if( search == NULL ){ /* To not overide data and routine: */
					index = LOOKUP_BIND( DAO_OBJECT_VARIABLE, perm, i, (offset+id) );
					MAP_Insert( self->lookupTable, name, index );
				}
			}
		}
	}
	self->derived = 1;
	DString_Delete( mbs );
	DArray_Delete( parents );
	DArray_Delete( offsets );
	DaoObject_Init( & self->objType->value->xObject, NULL, 0 );
	self->objType->value->xObject.trait &= ~DAO_VALUE_CONST;
	DaoValue_MarkConst( self->objType->value );
	DaoValue_MarkConst( self->constants->items.pConst[1]->value ); /* ::default */
}
Exemple #2
0
static void DaoObject_Print( DaoValue *self0, DaoProcess *proc, DaoStream *stream, DMap *cycData )
{
	int ec;
	char buf[50];
	DaoObject *self = & self0->xObject;
	sprintf( buf, "[%p]", self );
	if( self0 == self->defClass->objType->value ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, "[null]" );
		return;
	}
	if( cycData != NULL && DMap_Find( cycData, self ) != NULL ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
		return;
	}
	if( cycData ) MAP_Insert( cycData, self, self );

	DString_SetChars( proc->mbstring, "serialize" );
	DaoValue_Clear( & proc->stackValues[0] );
	ec = DaoObject_InvokeMethod( self, proc->activeObject, proc, proc->mbstring, NULL,0,1,1 );
	if( ec && ec != DAO_ERROR_FIELD_NOTEXIST ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->mbstring->chars, NULL );
	}else if( ec == DAO_ERROR_FIELD_NOTEXIST || proc->stackValues[0] == NULL ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
	}else{
		DaoValue_Print( proc->stackValues[0], proc, stream, cycData );
	}
}
Exemple #3
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 );
		}
	}
}
Exemple #4
0
int DaoClass_AddGlobalVar( DaoClass *self, DString *name, DaoValue *data, DaoType *t, int s )
{
	int size = self->variables->size;
	int id = LOOKUP_BIND( DAO_CLASS_VARIABLE, s, 0, size );
	DNode *node = MAP_Find( self->lookupTable, name );
	if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED;
	if( data == NULL && t ) data = t->value;
	MAP_Insert( self->lookupTable, name, id );
	DArray_Append( self->variables, DaoVariable_New( NULL, t ) );
	DArray_Append( self->glbDataName, (void*)name );
	if( data && DaoValue_Move( data, & self->variables->items.pVar[size]->value, t ) ==0 )
		return -DAO_CTW_TYPE_NOMATCH;
	return id;
}
Exemple #5
0
static int DaoClass_AddConst2( DaoClass *self, DString *name, DaoValue *data, int s )
{
	int id = LOOKUP_BIND( DAO_CLASS_CONSTANT, s, 0, self->constants->size );
	DaoNamespace *ns = self->classRoutine->nameSpace;
	if( data->type == DAO_ROUTINE && data->xRoutine.routHost != self->objType ){
		if( data->xRoutine.overloads ){
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, (DaoRoutine*) data );
			data = (DaoValue*) routs;
		}
	}
	MAP_Insert( self->lookupTable, name, id );
	DaoClass_AddConst3( self, name, data );
	return id;
}
Exemple #6
0
int DaoClass_AddObjectVar( DaoClass *self, DString *name, DaoValue *deft, DaoType *t, int s )
{
	int id;
	DNode *node = MAP_Find( self->lookupTable, name );
	if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED;
	if( deft == NULL && t ) deft = t->value;

	id = self->objDataName->size;
	MAP_Insert( self->lookupTable, name, LOOKUP_BIND( DAO_OBJECT_VARIABLE, s, 0, id ) );
	DArray_Append( self->objDataName, (void*)name );
	DArray_Append( self->instvars, DaoVariable_New( deft, t ) );
	DaoValue_MarkConst( self->instvars->items.pVar[ id ]->value );
	return id;
}
Exemple #7
0
static void DaoObject_Print( DaoValue *self0, DaoProcess *proc, DaoStream *stream, DMap *cycData )
{
	int ec = 0;
	char buf[50];
	DaoObject *self = & self0->xObject;
	DaoValue *params[2];
	DaoRoutine *meth;

	sprintf( buf, "[%p]", self );
	if( self0 == self->defClass->objType->value ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, "[null]" );
		return;
	}
	if( cycData != NULL && DMap_Find( cycData, self ) != NULL ){
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
		return;
	}
	if( cycData ) MAP_Insert( cycData, self, self );

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

	params[0] = (DaoValue*) dao_type_string;
	params[1] = (DaoValue*) stream;
	meth = DaoClass_FindMethod( self->defClass, "(string)", NULL );
	if( meth ){
		ec = DaoProcess_Call( proc, meth, self0, params, 2 );
		if( ec ) ec = DaoProcess_Call( proc, meth, self0, params, 1 );
	}else{
		meth = DaoClass_FindMethod( self->defClass, "serialize", NULL );
		if( meth ) ec = DaoProcess_Call( proc, meth, self0, NULL, 0 );
	}
	if( ec ){
		DaoProcess_RaiseException( proc, daoExceptionNames[ec], proc->string->chars, NULL );
	}else if( meth && proc->stackValues[0] ){
		DaoValue_Print( proc->stackValues[0], proc, stream, cycData );
	}else{
		DaoStream_WriteString( stream, self->defClass->className );
		DaoStream_WriteChars( stream, buf );
	}
}
Exemple #8
0
/* get new element, old face list and create the element faces => return the new face list */
static FACE* create_faces (MEM *facmem, MEM *mapmem, MAP **faces, ELEMENT *ele, FACE *list)
{
  FACE *fac, tmp;
  int n, m;

  m = neighs (ele->type); 
      
  for (n = 0; n < m; n ++)
  {
    /* set up temporary face for to
     * be used as the map search key */
    setup_face (ele, n, &tmp, 1); /* nodes sorted for map key comparisons */
    fac = static_cast<FACE*>(MAP_Find (*faces, &tmp, face_compare));  /* is it there ? */

    if (fac) /* was mapped already */
    {
      /* set up element adjacency */
      ele->adj [ele->neighs] = fac->ele;
      fac->ele->adj [fac->ele->neighs] = ele;
      fac->ele->neighs ++;
      ele->neighs ++;

      fac->ele = NULL; /* mark as the inner face (***) */
    }
    else
    {
      fac = static_cast<FACE*>(MEM_Alloc (facmem));
      fac->ele = ele;
      setup_face (ele, n, fac, 1);
      fac->index = n; /* local index */
      MAP_Insert (mapmem, faces, fac, /* map by the type/nodes key */
	fac, face_compare);
      fac->next = list;
      list = fac;
    }
  }

  return list;
}
Exemple #9
0
/* create mesh from a vector of nodes, element list in format =>
 * {nuber of nodes, node0, node1, ..., material}, {REPEAT}, ..., 0 (end of list); and surface colors in format =>
 * global surface, {number of nodes, node0, node1, ..., surface}, {REPEAT}, ..., 0 (end of list); */
MESH_DATA* MESH_Create (REAL (*nodes) [3], int *elements, int *surfaces)
{
  int maximal_node,
      minimal_node,
      elements_count,
      faces_count,
      temp, *eleptr, n;
  REAL (*node) [3];
  MEM *elemem,
      facmem,
      mapmem;
  ELEMENT *ele, *enx, *elist;
  FACE *fac, *cac, *gac, *flist;
  MAP *faces, *smap;
  MESH_DATA *msh;
  
  maximal_node = 0;
  minimal_node = INT_MAX;
  elements_count = 0;
  faces_count = 0;

  /* create mesh storage */
  ERRMEM (msh = static_cast<MESH_DATA*>(MEM_CALLOC (sizeof (MESH_DATA))));
  elemem = &msh->elemem;
 
  /* calculate elements */ 
  for (eleptr = elements; eleptr [0]; eleptr += (eleptr [0]+2)) elements_count ++;

  MEM_Init (elemem, sizeof (ELEMENT), elements_count);
  MEM_Init (&facmem, sizeof (FACE), MEMCHUNK);
  MEM_Init (&mapmem, sizeof (MAP), MEMCHUNK);
  MEM_Init (&msh->mapmem, sizeof (MAP), MIN (elements_count, MEMCHUNK));

  elist = NULL;
  flist = NULL;
  faces = NULL;

  /* create elements list & face adjacency map */
  for (eleptr = elements; eleptr [0]; eleptr += (eleptr [0]+2))
  {
    ASSERT (
      eleptr [0] == 4 || /* tetrahedron */
      eleptr [0] == 5 || /* pyramid */
      eleptr [0] == 6 || /* wedge */
      eleptr [0] == 8,   /* hexahedron */
      "ERROR: unsupported element type");

    ele = create_element (elemem, eleptr);
    flist = create_faces (&facmem, &mapmem, &faces, ele, flist);
    ele->next = elist;
    elist = ele;

    /* node number extrema */
    temp = maximal (eleptr);
    if (temp > maximal_node)
      maximal_node = temp;
    temp = minimal (eleptr);
    if (temp < minimal_node)
      minimal_node = temp;
  }

  /* calculate faces */
  for (fac = flist; fac; fac = fac->next)
    if (fac->ele) faces_count ++;

  /* alocate additional storage */
  MEM_Init (&msh->facmem, sizeof (FACE), faces_count);
  msh->nodes_count = (maximal_node - minimal_node + 1);
  ERRMEM (msh->nodes = static_cast<REAL(*)[3]>(malloc (sizeof (REAL [3]) * (msh->nodes_count))));
  msh->surfeles_count = msh->bulkeles_count = 0;
  msh->surfeles = msh->bulkeles = NULL;

  /* set up elements */
  for (ele = elist; ele; ele = enx)
  {
    enx = ele->next;

    if (minimal_node > 0) /* impose 0-based indexing */
    {
      for (temp = 0; temp < ele->type; temp ++)
	ele->nodes [temp] -= minimal_node;
    }

    ele->prev = NULL;
   
    if (ele->neighs < neighs (ele->type)) /* surface element */
    {
      msh->surfeles_count ++;
      ele->next = msh->surfeles;
      if (msh->surfeles) msh->surfeles->prev = ele;
      msh->surfeles = ele;
    }
    else /* bulk element */
    {
      msh->bulkeles_count ++;
      ele->next = msh->bulkeles;
      if (msh->bulkeles) msh->bulkeles->prev = ele;
      msh->bulkeles = ele;
    }
  }

  /* create surfaces map => skip first element of 'surfaces' == the global surface kind */
  for (eleptr = (surfaces + 1), smap = NULL, temp = 0;
    eleptr [0]; eleptr += (eleptr [0]+2), temp ++)
  {
    fac = static_cast<FACE*>(MEM_Alloc (&facmem));
    
    ASSERT (
      eleptr [0] == 3 || /* triangle */
      eleptr [0] == 4,   /* quad */
      "ERROR: unsupported face type");

    fac->type = eleptr [0];
    for (n = 0; n < eleptr [0]; n ++)
      fac->nodes [n] = eleptr [n+1];
    sort (fac->nodes, fac->nodes+fac->type-1);

    fac->color = eleptr [eleptr [0] + 1];
    MAP_Insert (&mapmem, &smap, fac, /* map by the type/nodes key */
      fac, face_compare);
  }

  /* set up nodes */
  for (temp = minimal_node,
       node = msh->nodes;
       temp <= maximal_node;
       temp ++, node ++)
  {
    COPY (nodes [temp], *node);
  }

  /* set up faces */
  for (fac = flist; fac; fac = fac->next)
  {
    if (fac->ele) /* see (***) */
    {
      ele = fac->ele;

      cac = static_cast<FACE*>(MEM_Alloc (&msh->facmem));
      setup_face (ele, fac->index, cac, 0); /* setup face nodes without sorting them */
      cac->index = fac->index;
      cac->ele = fac->ele;
      setup_normal (msh->nodes, cac); /* calculate outer spatial normal */
      cac->next = ele->faces; /* append element face list */
      ele->faces = cac;

      /* set the mapped surface kind if possible => otherwise the global one */
      gac = static_cast<FACE*>(MAP_Find (smap, fac, face_compare));
      cac->color = (gac ? gac->color : surfaces [0]);
    }
  }

  /* create mesh face list */
  for (ele = msh->surfeles; ele; ele = ele->next)
  {
    for (fac = ele->faces; fac; fac = fac->next)
    {
      fac->n = msh->faces;
      msh->faces = fac;
    }
  }

  /* clean up */
  MEM_Release (&facmem);
  MEM_Release (&mapmem);

  return msh;
}
Exemple #10
0
/* Matching a macro to source tokens.
 * For each macro variable such as $EXP and $VAR etc.
 * the matched tokens are stored in a tree, in which the leaves
 * are corresponding to the matched tokens and the branches
 * corresponding to the repetition of the matchings.
 *
 * For example,
 * key1 { \( key2 ( \( key3 $EXPR , \) \+ ) ; \) \* }
 * key1 { key2 ( key3 A+1 , key3 B-2, ); key2 ( key3 C*3, key3 D/4, key3 E+5, ); }
 *
 * the matching will generate such tree:
 *
 * key1:                                |
 *                                      |
 * \( key2 ... \) :           __________|______________
 *                           |                         |
 *                           |                         |
 * \( key3 ... \) :      ____|____            _________|_________
 *                      |         |          |         |         |
 *                      |         |          |         |         |
 *                      |         |          |         |         |
 * $EXPR:            {A,+,1}   {B,-,2}    {C,*,3}   {D,/,4}   {E,+,5}
 */
static int DaoParser_MacroMatch( DaoParser *self, int start, int end,
		DMacroGroup *group, DMap *tokMap, int level, DArray *all, int indent[10] )
{
	DMacroUnit **units = (DMacroUnit**) group->units->items.pVoid;
	DMacroUnit  *unit;
	DMacroGroup *grp;
	DaoToken **toks = self->tokens->items.pToken;
	DNode  *kwnode;
	DMacroNode *node, *prev;
	int M, N = group->units->size;
	int i, j=0, k=0, m, min, from = start;
	int idt, gid = -1;

	/*
	   printf( "MacroMatch\n" );
	   printf( "from = %i\n", from );
	 */

	if( group->repeat != DMACRO_AUTO ){
		level ++;
		for(j=0,M=group->variables->size; j<M; j++){
			kwnode = MAP_Find( tokMap, & group->variables->items.pToken[j]->string );
			prev = (DMacroNode*)( kwnode ? kwnode->value.pVoid : NULL );
			node = DMacroNode_New( level==1, level );
			node->group = group;
			DArray_Append( all, node );
			MAP_Insert( tokMap, & group->variables->items.pToken[j]->string, node );
			while( prev && prev->group != group->parent ) prev = prev->parent;
			if( prev ){
				node->parent = prev;
				prev->isLeaf = 0;
				DArray_Append( prev->nodes, (void*) node );
			}
		}
	}

	for(i=0; i<N; i++){
		unit = units[i];
		idt = unit->indent;
#if 0
		printf( "match unit %i (%i), type %i, from %i,  end %i\n", i, N, unit->type, from, end );
		if( unit->type < DMACRO_GRP ) printf( "marker: %s\n", unit->marker->string.mbs );
#endif
		if( from <0 ) return -100;
		if( from < end && idt && indent[idt] >=0 && toks[from]->cpos != indent[idt] ) return -22;
		if( from < end && idt && indent[idt] < 0 ) indent[idt] = toks[from]->cpos;
		switch( unit->type ){
		case DMACRO_TOK :
			if( from >= end ) return -100;
			if( ! DaoToken_EQ( toks[from], unit->marker ) ) return -23;
			switch( toks[from]->name ){
			case DTOK_LB :
				k = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, from, end );
				break;
			case DTOK_LSB :
				k = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, from, end );
				break;
			case DTOK_LCB :
				k = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, from, end );
				break;
			default : break;
			}
			switch( toks[from]->name ){
			case DTOK_LB :
			case DTOK_LCB :
			case DTOK_LSB :
				if( k <0 ) return -3;
				grp = (DMacroGroup*) units[i+1];
				j = DaoParser_MacroMatch( self, from+1, k, grp, tokMap, level, all, indent );
				if( j > k ) return -4;
				from = k;
				i ++;
				break;
			default : from ++; break;
			}
			break;
		case DMACRO_BR :
			if( from >= end ) return -100;
			if( ! DaoToken_EQ( toks[from], unit->marker ) ) return -24;
			from ++;
			break;
		case DMACRO_EXP :
		case DMACRO_ID :
		case DMACRO_OP :
		case DMACRO_BL :
		case DMACRO_IBL :
			if( from >= end ) return -100;
			switch( unit->type ){
			case DMACRO_EXP :
				self->curToken = from;
				j = DaoParser_ParseExpression( self, 0 );
				if( j < 0 ) return -100;
				j += 1;
				min = j + unit->stops->size;
				for(k=0,M=unit->stops->size; k<M; k++){
					DaoToken *stop = unit->stops->items.pToken[k];
					m = DaoParser_FindOpenToken2( self, stop, from, end );
#if 0
					//printf( "searching: %i %s %i\n", j, stop->mbs, end );
#endif
					if( min >= m && m >=0 ) min = m;
				}
				/* if there is extra tokens between expr and the first stop marker */
				if( j < 0 || min > j+1 ) return -5;
				if( min < j ) j = min;
				break;
			case DMACRO_ID :
				if( toks[from]->type != DTOK_IDENTIFIER ) return -1;
				j = from +1;
				break;
			case DMACRO_OP :
				if( toks[from]->name < DTOK_ADD || toks[from]->name > DTOK_DECR )
					return -1;
				j = from +1;
				break;
			case DMACRO_BL :
				j = end;
				min = j + unit->stops->size;
				for(k=0,M=unit->stops->size; k<M; k++){
					DaoToken *stop = unit->stops->items.pToken[k];
					m = DaoParser_FindOpenToken2( self, stop, from, end );
					/* printf( "searching: %i %s %i\n", j, stop->mbs, tokPos[j] ); */
					if( m < min && m >=0 ) min = m;
				}
				/* printf( "j = %i min = %i\n", j, min ); */
				if( min > j ) return -5;
				j = min;
				break;
			case DMACRO_IBL :
				k = toks[from]->line;
				m = toks[from]->cpos;
				j = from;
				while( j > start && (int)toks[j-1]->line == k ) j -= 1;
				if( j < from ) m = toks[j]->cpos + 1;
				j = from + 1;
				while( j < end && toks[j]->cpos >= m ) j += 1;
				/*
				   printf( "end = %i, j = %i\n", end, j );
				 */
				break;
			}

			/* key1 { \( key2 ( \( key3 $EXPR , \) \+ ) ; \) \* }
			 * key1 { key2 ( key3 A , key3 B, ) ; key2 ( key3 C, key3 D, ) ; }
			 * { level_1: { level_2, isLeaf: { A, B } }, { level_2, isLeaf: { C, D } } }
			 */
			kwnode = MAP_Find( tokMap, & unit->marker->string );
			prev = (DMacroNode*) kwnode->value.pVoid;
			while( prev && prev->group != group ) prev = prev->parent;
			node = DMacroNode_New( 1, level+1 );
			node->group = group;
			DArray_Append( all, node );
			MAP_Insert( tokMap, & unit->marker->string, node );
			node->parent = prev;
			if( prev ) DArray_Append( prev->nodes, node );
			for(k=from; k<j; k++) DArray_Append( node->leaves, toks[k] );

			/*
			   DMacroNode_Print( node );
			   kwnode = DMap_Find( tokMap, (void*)unit->marker );
			   node = (DMacroNode*) kwnode->value.pVoid;
			   while( node->parent ) node = node->parent;
			   printf( "\n" );
			 */
			from = j;
			break;
		case DMACRO_GRP :
		case DMACRO_ALT :
			grp = (DMacroGroup*) unit;
			j = DaoParser_MacroMatch( self, from, end, grp, tokMap, level, all, indent );
			switch( grp->repeat ){
			case DMACRO_AUTO :
			case DMACRO_ONE :
				if( from >= end ) return -100;
				if( j <0 && group->type != DMACRO_ALT ) return -6;
				if( j >=0 ){
					from = j;
					gid = i;
				}
				break;
			case DMACRO_ZERO :
				if( j >=0 && group->type != DMACRO_ALT ) return -7;
				if( j <0 ) gid = i;
				break;
			case DMACRO_ZERO_OR_ONE :
				if( j >=0 && group->type != DMACRO_ALT ) from = j;
				gid = i;
				break;
			case DMACRO_ZERO_OR_MORE :
				gid = i;
				while( j >=0 ){
					from = j;
					j = DaoParser_MacroMatch( self, from, end, grp, tokMap, level, all, indent );
				}
				break;
			case DMACRO_ONE_OR_MORE :
				if( from >= end ) return -100;
				if( j <0 && group->type != DMACRO_ALT ) return -8;
				while( j >=0 ){
					gid = i;
					from = j;
					j = DaoParser_MacroMatch( self, from, end, grp, tokMap, level, all, indent );
				}
				break;
			}
			break;
		default : return -9;
		}
#if 0
		printf( "end = %i, j = %i,   %i   %i\n", end, from, unit->type, DMACRO_IBL );
		//if( unit->type == DMACRO_IBL && from >= end ) break;
#endif
		if( group->type == DMACRO_ALT && gid >=0 ) break;
	}
	if( group->repeat != DMACRO_AUTO ) level --;
	if( group->type == DMACRO_ALT && gid <0 ) return -1;
	return from;
}
Exemple #11
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;
}
Exemple #12
0
/*
// The layout of mixins in a host class:
// 1. Each mixin occupies a continuous segment in the data arrays of the host.
//    The ranges of the segments are stored in DaoClass::ranges;
// 2. If the mixin contains other mixins, those mixins occupy segments preceding
//    the segment for this mixin;
// 3. The segments for the direct mixins of the host are arranged in the same
//    order as the mixins;
//
// For example, there are the following mixins:
//    class AA { var x = 1 }
//    class BB { var x = 1 }
//    class CC ( AA, BB ) { var x = 1 }
//    class DD ( CC, AA ) { var x = 1 }
// The mixin layout for CC:
//    CC_Header, AA_Header, AA_Data, BB_Header, BB_Data, CC_Data
// The mixin layout for DD:
//    DD_Header, AA_Header, AA_Data, BB_Header, BB_Data, CC_Header, CC_Data, DD_Data
//
// Where XX_Header are the data fields that are always placed at the header
// of the data array. For example, XX_Header for class constants contains
// two fields: one for the class itself, the other for the class constructor(s);
// XX_Header for class static variables is empty; and XX_Header for class
// instance variables contains only the field for the "self" variable.
// And XX_Data constains the mixin's own data which are not from its
// component mixins or from its paraent classes (actually only classes
// without parent classes can be used as mixins).
//
//
// To mix a mixin in the host class, the mixin (and its component mixins if any)
// are properly arranged in the host class with layouts described above.
// The non-trivial part is the update of variable types and the methods
// that are added to the host class from the mixin. To update the types,
// the type for the mixin are all replaced with the type for the host class.
//
// The update of methods involves three major steps:
// 1. Update the routine signature type, local variable types and the static
//    variable types;
// 2. Update the lookup table of the host class for the data from the mixins,
//    which is done by mapping the indices for the mixin data arrays to the
//    indices for the host data arrays;
// 3. Update the method code (VM instructions) such that operands involving
//    class or class instance data are properly mapped from the indices for
//    the mixin data arrays to the indices for the host data arrays.
*/
static int DaoClass_MixIn( DaoClass *self, DaoClass *mixin, DMap *mixed, DaoMethodFields *mf )
{
	daoint i, j, k, id, bl = 1;
	DaoNamespace *ns = self->classRoutine->nameSpace;
	DArray *routines;
	DMap *deftypes;
	DMap *routmap;
	DMap *idmap;
	DNode *it;

	if( mixin->parent != NULL ) return 0;
	if( DMap_Find( mixed, mixin ) != NULL ) return 1;

	/* Mix the component mixins first: */
	for(i=0; i<mixin->mixinBases->size; ++i){
		DaoClass *mx = mixin->mixinBases->items.pClass[i];
		bl = bl && DaoClass_MixIn( self, mx, mixed, mf );
	}
	if( bl == 0 ) return 0;

	idmap = DMap_New(0,0);
	routmap = DMap_New(0,0);
	deftypes = DMap_New(0,0);
	routines = DArray_New(0);
	DMap_Insert( mixed, mixin, idmap );
	DMap_Delete( idmap );
	idmap = DMap_Find( mixed, mixin )->value.pMap;

	/* Add this mixin to the mixin list for both direct and indirect mixins: */
	DArray_Append( self->mixins, mixin );
	/* Save the starts of the ranges for this mixin in the host class: */
	DVector_PushUshort( self->ranges, self->constants->size );
	DVector_PushUshort( self->ranges, self->variables->size );
	DVector_PushUshort( self->ranges, self->instvars->size );

	/* For updating the types for the mixin to the types for the host class: */
	DMap_Insert( deftypes, mixin->clsType, self->clsType );
	DMap_Insert( deftypes, mixin->objType, self->objType );

#if 0
	printf( "MixIn: %s %p %i\n", mixin->className->mbs, mixin, mixin->cstDataName->size );
#endif

	/* Add the own constants of the mixin to the host class: */
	for(i=0; i<mixin->cstDataName->size; ++i){
		daoint src = LOOKUP_BIND( DAO_CLASS_CONSTANT, 0, 0, i );
		daoint des = LOOKUP_BIND( DAO_CLASS_CONSTANT, 0, 0, self->constants->size );
		DString *name = mixin->cstDataName->items.pString[i];
		DaoValue *value = mixin->constants->items.pConst[i]->value;
		DaoRoutine *rout = (DaoRoutine*) value;

		if( i >= mixin->cstMixinStart && i < mixin->cstMixinEnd2 ) continue;

		MAP_Insert( idmap, src, des );  /* Setup index mapping; */
		DArray_Append( self->cstDataName, (void*) name );
		if( value->type != DAO_ROUTINE || rout->routHost != mixin->objType ){
			DaoConstant *cst = DaoConstant_New( value );
			DArray_Append( self->constants, cst );
			continue;
		}
		if( rout->overloads == NULL ){
			DaoRoutine *old = rout;
			rout = DaoRoutine_Copy( rout, 1, 1, 1 );
			bl = bl && DaoRoutine_Finalize( rout, self->objType, deftypes );
#if 0
			printf( "%2i:  %s  %s\n", i, rout->routName->mbs, rout->routType->name->mbs );
#endif

			/*
			// Do not use DaoClass_AddConst() here, so that the original
			// method overloading structures will be mantained, without
			// interference from methods of other mixin component classes
			// or of the host class.
			*/
			it = DMap_Find( routmap, old );
			if( it ) DRoutines_Add( it->value.pRoutine->overloads, rout );
			DArray_Append( self->constants, DaoConstant_New( (DaoValue*) rout ) );
			DArray_Append( routines, rout );
			if( bl == 0 ) goto Finalize;
		}else{
			/* No need to added the overloaded routines now; */
			/* Each of them has an entry in constants, and will be handled later: */
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, NULL );
			routs->trait |= DAO_VALUE_CONST;
			DArray_Append( self->constants, DaoConstant_New( (DaoValue*) routs ) );
			for(j=0; j<rout->overloads->routines->size; ++j){
				DaoRoutine *R = rout->overloads->routines->items.pRoutine[j];
				DMap_Insert( routmap, R, routs );
			}
		}
	}
	for(i=mixin->glbMixinEnd2; i<mixin->glbDataName->size; ++i){
		daoint src = LOOKUP_BIND( DAO_CLASS_VARIABLE, 0, 0, i );
		daoint des = LOOKUP_BIND( DAO_CLASS_VARIABLE, 0, 0, self->variables->size );
		DString *name = mixin->glbDataName->items.pString[i];
		DaoValue *var = mixin->variables->items.pVar[i]->value;
		DaoType *type = mixin->variables->items.pVar[i]->dtype;

		type = DaoType_DefineTypes( type, ns, deftypes );

		MAP_Insert( idmap, src, des );
		DArray_Append( self->glbDataName, (void*) name );
		DArray_Append( self->variables, DaoVariable_New( var, type ) );
	}
	for(i=mixin->objMixinEnd2; i<mixin->objDataName->size; ++i){
		daoint src = LOOKUP_BIND( DAO_OBJECT_VARIABLE, 0, 0, i );
		daoint des = LOOKUP_BIND( DAO_OBJECT_VARIABLE, 0, 0, self->instvars->size );
		DString *name = mixin->objDataName->items.pString[i];
		DaoValue *var = mixin->instvars->items.pVar[i]->value;
		DaoType *type = mixin->instvars->items.pVar[i]->dtype;

		type = DaoType_DefineTypes( type, ns, deftypes );

		MAP_Insert( idmap, src, des );
		DArray_Append( self->objDataName, (void*) name );
		DArray_Append( self->instvars, DaoVariable_New( var, type ) );
	}

	/* Find the ends of own data of this mixin: */
	DVector_PushUshort( self->ranges, self->constants->size );
	DVector_PushUshort( self->ranges, self->variables->size );
	DVector_PushUshort( self->ranges, self->instvars->size );

	/* Update the lookup table: */
	for(it=DMap_First(mixin->lookupTable); it; it=DMap_Next(mixin->lookupTable,it)){
		int pm = LOOKUP_PM( it->value.pInt );
		int st = LOOKUP_ST( it->value.pInt );
		int up = LOOKUP_UP( it->value.pInt );
		int id = LOOKUP_ID( it->value.pInt );
		DaoValue *cst;
		/* Skip names from component mixins (because they have been handled): */
		switch( st ){
		case DAO_CLASS_CONSTANT :
			if( id >= mixin->cstMixinStart && id < mixin->cstMixinEnd2 ) continue;
			break;
		case DAO_CLASS_VARIABLE :
			if( id >= mixin->glbMixinStart && id < mixin->glbMixinEnd2 ) continue;
			break;
		case DAO_OBJECT_VARIABLE :
			if( id >= mixin->objMixinStart && id < mixin->objMixinEnd2 ) continue;
			break;
		}
		if( st != DAO_OBJECT_VARIABLE || id != 0 ){ /* not a "self": */
			DNode *it2 = MAP_Find( idmap, LOOKUP_BIND( st, 0, 0, id ) );
			if( it2 ) id = LOOKUP_ID( it2->value.pInt ); /* map index; */
		}
		MAP_Insert( self->lookupTable, it->key.pString, LOOKUP_BIND( st, pm, up, id ) );
		if( st != DAO_CLASS_CONSTANT ) continue;
		cst = self->constants->items.pConst[id]->value;
		if( cst->type != DAO_ROUTINE ) continue;
		DArray_Append( mf->names, it->key.pString );
		DArray_Append( mf->perms, IntToPointer( pm ) );
		DArray_Append( mf->routines, cst );
	}

	for(i=0; i<routines->size; i++){
		DaoRoutine *rout = routines->items.pRoutine[i];
		DaoType **types;
		if( rout->body == NULL ) continue;
		//DaoRoutine_PrintCode( rout, rout->nameSpace->vmSpace->stdioStream );
		types = rout->body->regType->items.pType;
		for(j=0; j<rout->body->annotCodes->size; ++j){
			DaoVmCodeX *vmc = rout->body->annotCodes->items.pVmc[j];
			DaoClass *klass;
			DString *name;
			switch( vmc->code ){
			case DVM_GETCK:
			case DVM_GETCK_I: case DVM_GETCK_F:
			case DVM_GETCK_D: case DVM_GETCK_C:
				vmc->b = DaoClass_MapIndex( mixin, DAO_CLASS_CONSTANT, vmc->b, mixed );
				break;
			case DVM_GETVK:
			case DVM_GETVK_I: case DVM_GETVK_F:
			case DVM_GETVK_D: case DVM_GETVK_C:
			case DVM_SETVK:
			case DVM_SETVK_II: case DVM_SETVK_FF:
			case DVM_SETVK_DD: case DVM_SETVK_CC:
				vmc->b = DaoClass_MapIndex( mixin, DAO_CLASS_VARIABLE, vmc->b, mixed );
				break;
			case DVM_GETVO:
			case DVM_GETVO_I: case DVM_GETVO_F:
			case DVM_GETVO_D: case DVM_GETVO_C:
			case DVM_SETVO:
			case DVM_SETVO_II: case DVM_SETVO_FF:
			case DVM_SETVO_DD: case DVM_SETVO_CC:
				vmc->b = DaoClass_MapIndex( mixin, DAO_OBJECT_VARIABLE, vmc->b, mixed );
				break;
			case DVM_GETF_KC:
			case DVM_GETF_KCI: case DVM_GETF_KCF:
			case DVM_GETF_KCD: case DVM_GETF_KCC:
			case DVM_GETF_OC:
			case DVM_GETF_OCI: case DVM_GETF_OCF:
			case DVM_GETF_OCD: case DVM_GETF_OCC:
				klass = (DaoClass*) types[ vmc->a ]->aux;
				name  = DaoClass_GetDataName( klass, DAO_CLASS_CONSTANT, vmc->b );
				vmc->b = DaoRoutine_GetFieldIndex( rout, name );
				vmc->code = DVM_GETF;
				break;
			case DVM_GETF_KG:
			case DVM_GETF_KGI: case DVM_GETF_KGF:
			case DVM_GETF_KGD: case DVM_GETF_KGC:
			case DVM_GETF_OG:
			case DVM_GETF_OGI: case DVM_GETF_OGF:
			case DVM_GETF_OGD: case DVM_GETF_OGC:
				klass = (DaoClass*) types[ vmc->a ]->aux;
				name  = DaoClass_GetDataName( klass, DAO_CLASS_VARIABLE, vmc->b );
				vmc->b = DaoRoutine_GetFieldIndex( rout, name );
				vmc->code = DVM_GETF;
				break;
			case DVM_GETF_OV:
			case DVM_GETF_OVI: case DVM_GETF_OVF:
			case DVM_GETF_OVD: case DVM_GETF_OVC:
				klass = (DaoClass*) types[ vmc->a ]->aux;
				name  = DaoClass_GetDataName( klass, DAO_OBJECT_VARIABLE, vmc->b );
				vmc->b = DaoRoutine_GetFieldIndex( rout, name );
				vmc->code = DVM_GETF;
				break;
			case DVM_SETF_KG:
			case DVM_SETF_KGII: case DVM_SETF_KGFF:
			case DVM_SETF_KGDD: case DVM_SETF_KGCC:
			case DVM_SETF_OG:
			case DVM_SETF_OGII: case DVM_SETF_OGFF:
			case DVM_SETF_OGDD: case DVM_SETF_OGCC:
				klass = (DaoClass*) types[ vmc->c ]->aux;
				name  = DaoClass_GetDataName( klass, DAO_CLASS_VARIABLE, vmc->b );
				vmc->b = DaoRoutine_GetFieldIndex( rout, name );
				vmc->code = DVM_SETF;
				break;
			case DVM_SETF_OV:
			case DVM_SETF_OVII: case DVM_SETF_OVFF:
			case DVM_SETF_OVDD: case DVM_SETF_OVCC:
				klass = (DaoClass*) types[ vmc->c ]->aux;
				name  = DaoClass_GetDataName( klass, DAO_OBJECT_VARIABLE, vmc->b );
				vmc->b = DaoRoutine_GetFieldIndex( rout, name );
				vmc->code = DVM_SETF;
				break;
			}
		}
		//DaoRoutine_PrintCode( rout, rout->nameSpace->vmSpace->stdioStream );
		bl = bl && DaoRoutine_DoTypeInference( rout, 0 );
		if( bl == 0 ) goto Finalize;
	}
Finalize:
	DArray_Delete( routines );
	DMap_Delete( routmap );
	DMap_Delete( deftypes );
	return bl;
}
Exemple #13
0
/* communicate objects using point to point communication */
int COMOBJS (MPI_Comm comm, int tag,
	     OBJ_Pack pack,
	     void *data,
	     OBJ_Unpack unpack,
             COMOBJ *send, int nsend,
	     COMOBJ **recv, int *nrecv) /* recv is contiguous => free (*recv) releases all memory */
{
  COMDATA *send_data,
	  *recv_data,
	  *cd, *cc;
  int recv_count,
      i, n,
      ret;
  COMOBJ *co;
  MAP *map;
  MEM mem;

  ERRMEM (send_data = malloc (nsend * sizeof (COMDATA)));
  MEM_Init (&mem, sizeof (MAP), MAX (nsend, 64));

  /* pack objects */
  for (i = 0, cd = send_data, co = send, map = NULL; i < nsend; i ++, cd ++, co ++)
  {
    int isize = 0,
	dsize = 0;

    cd->rank = co->rank;

    if ((cc = MAP_Find (map, co->o, NULL))) /* same object was already packed */
    {
      cd->ints = cc->ints;
      cd->doubles = cc->doubles;
      cd->i = cc->i;
      cd->d = cc->d;
    }
    else
    {
      cd->ints = 0;
      cd->doubles = 0;
      cd->i = NULL;
      cd->d = NULL;

      pack (co->o, &dsize, &cd->d, &cd->doubles, &isize, &cd->i, &cd->ints);

      MAP_Insert (&mem, &map, co->o, cd, NULL);
    }
  }

  /* send and receive packed data */
  if (tag == INT_MIN) ret = COMALL (comm, send_data, nsend, &recv_data, &recv_count); /* all to all */
  else ret = COM (comm, tag, send_data, nsend, &recv_data, &recv_count); /* point to point */

#if PARDEBUG
  {
    int debug_send_count, *ip, *jp, ii [2], jj [2];
    COMDATA *debug_send_data;
    double *qq, *pp;

    /* send backwards */
    if (tag == INT_MIN) COMALL (comm, recv_data, recv_count, &debug_send_data, &debug_send_count);
    else COM (comm, tag, recv_data, recv_count, &debug_send_data, &debug_send_count);

    ii[0] = 0, ii[1] = 0;
    jj[0] = 0, jj[1] = 0;
    do
    {
      ip = next_int (send_data, nsend, ii);
      jp = next_int (debug_send_data, debug_send_count, jj);
      if (ip && jp)
      {
	ASSERT_DEBUG (*ip == *jp, "Integer values mismatch");
      }
      else
      {
	ASSERT_DEBUG (!ip && !jp, "Integer count mismatch");
      }
    }
    while (ip && jp);

    ii[0] = 0, ii[1] = 0;
    jj[0] = 0, jj[1] = 0;
    do
    {
      qq = next_double (send_data, nsend, ii);
      pp = next_double (debug_send_data, debug_send_count, jj);
      if (qq && pp)
      {
	ASSERT_DEBUG (*qq == *pp, "Double values mismatch");
      }
      else
      {
	ASSERT_DEBUG (!qq && !pp, "Double count mismatch");
      }
    }
    while (qq && pp);

    free (debug_send_data);
  }
#endif

  if (recv_count)
  {
    *nrecv = recv_count;
    ERRMEM (*recv = malloc ((*nrecv) * sizeof (COMOBJ)));

    /* unpack received objects */
    for (n = i = 0, cd = recv_data, co = *recv; i < recv_count; i ++, cd ++)
    {
      int ipos = 0,
	  dpos = 0;

      do
      {
	if (n == *nrecv)
	{
	  *nrecv *= 2; /* resize the receive buffer */
	  ERRMEM (*recv = realloc (*recv, (*nrecv) * sizeof (COMOBJ)));
	  co = *recv + n; /* and reset the current pointer */
	}

	co->rank = cd->rank;
	co->o = unpack (data, &dpos, cd->d, cd->doubles, &ipos, cd->i, cd->ints);

	co ++;
	n ++;

      } while (ipos < cd->ints || dpos < cd->doubles); /* while something is left to unpack */
    }

    /* truncate output */
    if (n) ERRMEM (*recv = realloc (*recv, n * sizeof (COMOBJ)));
    *nrecv = n;
  }
  else
  {
    *recv = NULL;
    *nrecv = 0;
  }

  /* cleanup */
  for (MAP *item = MAP_First (map); item; item = MAP_Next (item))
  { cd = item->data; free (cd->i); free (cd->d); }
  MEM_Release (&mem);
  free (send_data);
  free (recv_data); /* contiguous */

  return ret;
}
Exemple #14
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 );
}
Exemple #15
0
DaoClass* DaoClass_Instantiate( DaoClass *self, DArray *types )
{
	DaoClass *klass = NULL;
	DaoType *type;
	DString *name;
	DNode *node;
	DMap *deftypes;
	daoint lt = DString_FindChar( self->className, '<', 0 );
	daoint i, holders = 0;
	if( self->typeHolders == NULL || self->typeHolders->size ==0 ) return self;
	while( types->size < self->typeHolders->size ){
		type = self->typeDefaults->items.pType[ types->size ];
		if( type == NULL ) type = self->typeHolders->items.pType[ types->size ];
		DArray_Append( types, type );
	}
	name = DString_New(1);
	DString_Append( name, self->className );
	if( lt != MAXSIZE ) DString_Erase( name, lt, MAXSIZE );
	DString_AppendChar( name, '<' );
	for(i=0; i<types->size; i++){
		type = types->items.pType[i];
		holders += type->tid == DAO_THT;
		if( i ) DString_AppendChar( name, ',' );
		DString_Append( name, type->name );
	}
	DString_AppendChar( name, '>' );
	while( self->templateClass ) self = self->templateClass;
	node = DMap_Find( self->instanceClasses, name );
	if( node ){
		klass = node->value.pClass;
	}else{
		deftypes = DMap_New(0,0);
		klass = DaoClass_New();
		if( holders ) klass->templateClass = self;
		DMap_Insert( self->instanceClasses, name, klass );
		DaoClass_AddReference( self, klass ); /* No need for cleanup of klass; */
		DaoClass_SetName( klass, name, self->classRoutine->nameSpace );
		for(i=0; i<types->size; i++){
			type = types->items.pType[i];
			if( DaoType_MatchTo( type, self->typeHolders->items.pType[i], deftypes ) ==0 ){
				DString_Delete( name );
				return NULL;
			}
			MAP_Insert( deftypes, self->typeHolders->items.pVoid[i], type );
		}
		klass->objType->nested = DArray_New(D_VALUE);
		DArray_Assign( klass->objType->nested, types );
		if( DaoClass_CopyField( klass, self, deftypes ) == 0 ){
			DString_Delete( name );
			return NULL;
		}
		DaoClass_DeriveClassData( klass );
		DaoClass_DeriveObjectData( klass );
		DaoClass_ResetAttributes( klass );
		DMap_Delete( deftypes );
		if( holders ){
			klass->typeHolders = DArray_New(0);
			klass->typeDefaults = DArray_New(0);
			klass->instanceClasses = DMap_New(D_STRING,0);
			DMap_Insert( klass->instanceClasses, klass->className, klass );
			for(i=0; i<types->size; i++){
				DArray_Append( klass->typeHolders, types->items.pType[i] );
				DArray_Append( klass->typeDefaults, NULL );
			}
			for(i=0; i<klass->typeHolders->size; i++){
				DaoClass_AddReference( klass, klass->typeHolders->items.pType[i] );
				DaoClass_AddReference( klass, klass->typeDefaults->items.pType[i] );
			}
		}
	}
	DString_Delete( name );
	return klass;
}
Exemple #16
0
/* read new bodies data */
static void read_new_bodies (DOM *dom, PBF *bf)
{
#if HDF5
  double time, start, end;

  PBF_Time (bf, &time); /* back up time frame from outside of this function */
  PBF_Limits (bf, &start, &end);
  PBF_Seek (bf, start);

  do
  {
    for (PBF *f = bf; f; f = f->next)
    {
      int ipos = 0, ints;
      int dpos = 0, doubles;
      double *d;
      int *i;
      int k, n;
      BODY *bod;

      if (PBF_Has_Group (f, "NEWBOD") == 0) continue; /* don't try to read if there are no new bodies stored */

      PBF_Push (f, "NEWBOD");

      PBF_Int2 (f, "count", &n, 1);
      PBF_Int2 (f, "ints", &ints, 1);
      ERRMEM (i = malloc (sizeof (int [ints])));
      PBF_Int2 (f, "i", i, ints);
      PBF_Int2 (f, "doubles", &doubles, 1);
      ERRMEM (d = malloc (sizeof (double [doubles])));
      PBF_Double2 (f, "d", d, doubles);

      for (k = 0; k < n; k ++)
      {
	bod = BODY_Unpack (dom->solfec, &dpos, d, doubles, &ipos, i, ints);

	if (!MAP_Find (dom->allbodies, (void*) (long) bod->id, NULL))
	{
	  MAP_Insert (&dom->mapmem, &dom->allbodies, (void*) (long) bod->id, bod, NULL); /* all bodies from all times */
	}
	else BODY_Destroy (bod); /* FIXME: bodies created in input files at time > 0;
				    FIXME: perhaps there is no need of moving GLV to the fist lng_RUN call,
				    FIXME: but rather bodies created in Python should not be put into the 'dom->newb' set;
				    FIXME: this way, as now, all Python created bodies will be anyway read at time 0 */
      }

      free (d);
      free (i);

      PBF_Pop (f);
    }
  } while (PBF_Forward (bf, 1));

  dom->allbodiesread = 1; /* mark as read */

  PBF_Seek (bf, time); /* seek to the backed up time again */
#else
  char *path, *ext;
  FILE *file;
  int m, n;
  XDR xdr;

  if (dom->solfec->verbose)
    printf ("Reading all bodies ...\n");

  dom->allbodiesread = 1; /* mark as read */

  path = SOLFEC_Alloc_File_Name (dom->solfec, 16);
  ext = path + strlen (path);
  
  for (m = 0; bf; bf = bf->next) m ++; /* count input files */

  for (n = 0; n < m; n ++)
  {
    if (n || m > 1)
    {
      sprintf (ext, ".bod.%d", n);
      if (!(file = fopen (path, "r"))) continue; /* no new bodies for this rank */
    }
    else /* n == 0 && m == 1 */
    {
      sprintf (ext, ".bod.%d", n);
      if (!(file = fopen (path, "r"))) /* either prallel with "mpirun -np 1" */
      {
	sprintf (ext, ".bod");
	if (!(file = fopen (path, "r"))) continue; /* or serial */
      }
    }

    xdrstdio_create (&xdr, file, XDR_DECODE);

    int ipos, ints, *i, dpos, doubles;
    double *d;
    BODY *bod;

    for (;;)
    {
      if (xdr_int (&xdr, &doubles))
      {
	ERRMEM (d = malloc (sizeof (double [doubles])));
	if (xdr_vector (&xdr, (char*)d, doubles, sizeof (double), (xdrproc_t)xdr_double))
	{
	  if (xdr_int (&xdr, &ints))
	  {
	    ERRMEM (i = malloc (sizeof (int [ints])));
	    if (xdr_vector (&xdr, (char*)i, ints, sizeof (int), (xdrproc_t)xdr_int))
	    {
	      ipos = dpos = 0;

	      bod = BODY_Unpack (dom->solfec, &dpos, d, doubles, &ipos, i, ints);

	      if (!MAP_Find (dom->allbodies, (void*) (long) bod->id, NULL))
	      {
	        MAP_Insert (&dom->mapmem, &dom->allbodies, (void*) (long) bod->id, bod, NULL);
	      }
	      else BODY_Destroy (bod); /* FIXME: bodies created in input files at time > 0;
					  FIXME: perhaps there is no need of moving GLV to the fist lng_RUN call,
					  FIXME: but rather bodies created in Python should not be put into the 'dom->newb' set;
					  FIXME: this way, as now, all Python created bodies will be anyway read at time 0 */
	      free (d);
	      free (i);
	    }
	    else
	    {
	      free (d);
	      free (i);
	      break;
	    }
	  }
	  else
	  {
	    free (d);
	    break;
	  }
	}
	else
	{
	  free (d);
	  break;
	}
      }
      else break;
    }

    xdr_destroy (&xdr);
    fclose (file);
  }

  free (path);
#endif
}
Exemple #17
0
/* read domain state */
void dom_read_state (DOM *dom, PBF *bf)
{
  BODY *bod, *next;
  int ncon;

  /* clear contacts */
  MAP_Free (&dom->mapmem, &dom->idc);
  MEM_Release (&dom->conmem);
  dom->con = NULL;
  dom->ncon = 0;

  /* read all bodies if needed */
  if (!dom->allbodiesread) read_new_bodies (dom, bf);

  /* mark all bodies as absent */
  for (bod = dom->bod; bod; bod = bod->next) bod->flags |= BODY_ABSENT;

  SET *usedlabel = NULL;

  for (; bf; bf = bf->next)
  {
    if (PBF_Label (bf, "DOM"))
    {
      /* read iover */

      int iover = 2;

      if (PBF_Label (bf, "IOVER"))
      {
	PBF_Int (bf, &iover, 1);
      }

      /* read time step */

      ASSERT (PBF_Label (bf, "STEP"), ERR_FILE_FORMAT);

      PBF_Double (bf, &dom->step, 1);

      /* read constraints merit */

      ASSERT (PBF_Label (bf, "MERIT"), ERR_FILE_FORMAT);

      PBF_Double (bf, &dom->merit, 1);

      /* read body states */

      ASSERT (PBF_Label (bf, "BODS"), ERR_FILE_FORMAT);

      int nbod;

      PBF_Int (bf, &nbod, 1);

      for (int n = 0; n < nbod; n ++)
      {
	unsigned int id;

	PBF_Uint (bf, &id, 1);
	bod = MAP_Find (dom->idb, (void*) (long) id, NULL);

	if (bod == NULL) /* pick from all bodies set */
	{
	  ASSERT_DEBUG_EXT (bod = MAP_Find (dom->allbodies, (void*) (long) id, NULL), "Body id invalid");

	  if (bod->label)
	  {
	    MAP *node = MAP_Find_Node (dom->lab, bod->label, (MAP_Compare)strcmp);
	    if (node)
	    {
	      node->data = bod; /* body fregments can inherit labels */
	      SET_Insert (NULL, &usedlabel, bod->label, (SET_Compare)strcmp);
	    }
	    else MAP_Insert (&dom->mapmem, &dom->lab, bod->label, bod, (MAP_Compare) strcmp);
	  }
	  MAP_Insert (&dom->mapmem, &dom->idb, (void*) (long) bod->id, bod, NULL);
	  bod->next = dom->bod;
	  if (dom->bod) dom->bod->prev = bod;
	  dom->bod = bod;
	  bod->dom = dom;
	  dom->nbod ++;
	}

	BODY_Read_State (bod, bf, iover);
	bod->flags &= ~BODY_ABSENT;
      }

      /* read constraints */

      ASSERT (PBF_Label (bf, "CONS"), ERR_FILE_FORMAT);
    
      PBF_Int (bf, &ncon, 1);

      for (int n = 0; n < ncon; n ++)
      {
	CON *con;
	
	con = read_constraint (dom, iover, bf);
	MAP_Insert (&dom->mapmem, &dom->idc, (void*) (long) con->id, con, NULL);
	con->next = dom->con;
	if (dom->con) dom->con->prev = con;
	dom->con = con;
      }

      dom->ncon += ncon;
    }
  }

  /* remove absent bodies */
  for (bod = dom->bod; bod; bod = next)
  {
    next = bod->next;

    if (bod->flags & BODY_ABSENT)
    {
      if (bod->label && !SET_Contains (usedlabel, bod->label, (SET_Compare)strcmp))
	MAP_Delete (&dom->mapmem, &dom->lab, bod->label, (MAP_Compare) strcmp);
      MAP_Delete (&dom->mapmem, &dom->idb, (void*) (long) bod->id, NULL);
      if (bod->next) bod->next->prev = bod->prev;
      if (bod->prev) bod->prev->next = bod->next;
      else dom->bod = bod->next;
      dom->nbod --;
    }
  }

  SET_Free (NULL, &usedlabel);

  /* attach constraints to bodies */
  dom_attach_constraints (dom);
}
Exemple #18
0
int DaoClass_AddType( DaoClass *self, DString *name, DaoType *tp )
{
	DNode *node = MAP_Find( self->abstypes, name );
	if( node == NULL ) MAP_Insert( self->abstypes, name, tp );
	return 1;
}
Exemple #19
0
bool DaoxDebugger::EditContinue ( DaoProcess *process, int newEntryLine, QList<int> & lineMap, QStringList & newCodes, QStringList & routCodes )
{
	DaoRoutine *oldrout = process->activeRoutine;
	int i, j, k, dest = 0;
	//printf( "=======%s\n", routCodes.join("\n").toLocal8Bit().data() );
	//printf( "=======%s\n", newCodes.join("\n").toLocal8Bit().data() );
	if( routCodes.size() == newCodes.size() ){
		DaoLexer *lexer = DaoLexer_New();
		bool eq = true;
		for(i=0; i<routCodes.size(); i++){
			QString s1 = NormalizeCodes( routCodes[i], lexer );
			QString s2 = NormalizeCodes( newCodes[i], lexer );
			if( s1 != s2 ){
				eq = false;
				break;
			}
		}
		DaoLexer_Delete( lexer );
		if( eq ) return true;
	}
	QString codes = newCodes.join( "\n" );
	DaoParser *parser = DaoParser_New();
	DaoRoutine *routine = DaoRoutine_New( oldrout->nameSpace, oldrout->routHost, 1 );
	routine->routType = oldrout->routType;
	routine->parCount = oldrout->parCount;
	routine->attribs = oldrout->attribs;
	routine->defLine = oldrout->defLine;
	parser->routine = routine;
	parser->nameSpace = routine->nameSpace = oldrout->nameSpace;
	parser->vmSpace = oldrout->nameSpace->vmSpace;
	DString_Assign( parser->fileName, oldrout->nameSpace->name );
	routine->body->codeStart = oldrout->body->codeStart;
	routine->body->codeEnd = oldrout->body->codeStart + newCodes.size() + 1;
	parser->regCount = routine->parCount;
	parser->levelBase = oldrout->defLine != 0;
	bool res = DaoParser_LexCode( parser, codes.toLocal8Bit().data(), 1 );
	for(i=0; i<(int)parser->tokens->size; i++){
		parser->tokens->items.pToken[i]->line += routine->body->codeStart;
	}
	for(i=0; i<(int)oldrout->body->defLocals->size; i++){
		DaoToken *tok = oldrout->body->defLocals->items.pToken[i];
		if( tok->index >= oldrout->parCount || tok->type ==0 ) break;
		MAP_Insert( DList_Top( parser->lookupTables ), & tok->string, i );
		DList_Append( routine->body->defLocals, tok );
	}
	res = res && DaoParser_ParseRoutine( parser );
	DaoParser_Delete( parser );
	if( res == false ){
		DaoRoutine_Delete( routine );
		return false;
	}
	if( (process->stackSize - process->stackTop) < (routine->body->regCount + DAO_MAX_PARAM) ){
		DaoProcess_PushFrame( process, routine->body->regCount );
		DaoProcess_PopFrame( process );
	}
	DaoType **regTypes = routine->body->regType->items.pType;
	DaoValue **newValues = process->activeValues;
	DaoValue **oldValues = (DaoValue**)calloc( oldrout->body->regCount, sizeof(DaoValue*) );

	memcpy( oldValues, newValues, oldrout->body->regCount * sizeof(DaoValue*) );
	memset( newValues, 0, oldrout->body->regCount * sizeof(DaoValue*) );
	DaoProcess_InitTopFrame( process, routine, process->activeObject );

#if 0
	DaoStream *stream = DaoStream_New();
	DaoRoutine_PrintCode( oldrout, stream );
	DaoRoutine_PrintCode( routine, stream );
#endif

	regmap.clear();
	for(i=0; i<oldrout->parCount; i++) regmap[i] = i;

	DaoVmCode   *oldVMC = oldrout->body->vmCodes->data.codes;
	DaoVmCode   *newVMC = routine->body->vmCodes->data.codes;
	DaoVmCodeX **oldAnnot = oldrout->body->annotCodes->items.pVmc;
	DaoVmCodeX **newAnnot = routine->body->annotCodes->items.pVmc;
	int M = oldrout->body->vmCodes->size;
	int N = routine->body->vmCodes->size;
	j = k = 0;
	for(i=0; i<lineMap.size(); i++){
		QList<DaoVmCode> oldLineCodes;
		QList<DaoVmCode> newLineCodes;
		if( lineMap[i] <0 ) continue;
		int old = lineMap[i] + oldrout->body->codeStart + 1;
		int niu = i + routine->body->codeStart + 1;
		//printf( "%3i  %3i: %3i  %3i;  %3i  %3i\n", j, k, i, niu, lineMap[i], old );
		while( j<M && oldAnnot[j]->line < old ) ++j;
		while( k<N && newAnnot[k]->line < niu ) ++k;
		while( j<M && oldAnnot[j]->line == old ){
			oldLineCodes.append( oldVMC[j] );
			++j;
		}
		while( k<N && newAnnot[k]->line == niu ){
			newLineCodes.append( newVMC[k] );
			++k;
		}
		Matching( oldLineCodes, newLineCodes );
	}
	QMap<int,int>::iterator it, end = regmap.end();
	for(it=regmap.begin(); it != end; ++it){
		j = it.key();
		i = it.value();
		DaoValue_Move( oldValues[j], & newValues[i], regTypes[i] );
	}

	int offset = 0;
	if( newEntryLine <0 ){
		DaoVmCodeX **annotCodes = oldrout->body->annotCodes->items.pVmc;
		int entry = (process->activeCode - process->topFrame->codes) + 1;
		int entryline = oldrout->body->annotCodes->items.pVmc[entry]->line;
		/* if the entry line is NOT modified, use it */
		entryline -= oldrout->body->codeStart + 1;
		for(i=0; i<lineMap.size(); i++) if( lineMap[i] == entryline ) break;
		int newEntryLine = i < lineMap.size() ? i : -1;
		if( newEntryLine >=0 ){
			entryline += oldrout->body->codeStart + 1;
			while( (--entry) >=0 && annotCodes[entry]->line == entryline ) offset ++;
		}
		/* if the entry line IS modified, set the entry line to the first modified line */
		if( newEntryLine <0 ){
			for(i=0; i<lineMap.size(); i++) if( lineMap[i] <0 ) break;
			newEntryLine = i;
		}
		/* if the entry line is manually set: */
		newEntryLine += routine->body->codeStart + 1;
	}

	//XXX GC_ShiftRC( routine, oldrout );
	GC_IncRC( routine );
	oldrout->body->revised = routine;
	process->activeRoutine = routine;
	process->activeTypes = regTypes;
	process->topFrame->codes = routine->body->vmCodes->data.codes;

	ResetExecution( process, newEntryLine, offset );

	i = newCodes.size() - routCodes.size();
	DaoNS_UpdateLineInfo( routine->nameSpace, routine->body->codeStart, i );
	return true;
}
Exemple #20
0
void DaoClass_AddOverloadedRoutine( DaoClass *self, DString *signature, DaoRoutine *rout )
{
	MAP_Insert( self->ovldRoutMap, signature, rout );
}