Ejemplo n.º 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 */
}
Ejemplo n.º 2
0
int DaoClass_GetData( DaoClass *self, DString *name, DaoValue **value, DaoClass *thisClass )
{
	DaoValue *p = NULL;
	DNode *node = MAP_Find( self->lookupTable, name );
	int child = thisClass && DaoClass_ChildOf( thisClass, (DaoValue*)self );
	int sto, perm, up, id;

	*value = NULL;
	if( ! node ) return DAO_ERROR_FIELD_NOTEXIST;
	perm = LOOKUP_PM( node->value.pInt );
	sto = LOOKUP_ST( node->value.pInt );
	up = LOOKUP_UP( node->value.pInt );
	id = LOOKUP_ID( node->value.pInt );
	if( self == thisClass || perm == DAO_DATA_PUBLIC || (child && perm >= DAO_DATA_PROTECTED) ){
		switch( sto ){
		case DAO_CLASS_VARIABLE : p = self->variables->items.pVar[id]->value; break;
		case DAO_CLASS_CONSTANT : p = self->constants->items.pConst[id]->value; break;
		default : return DAO_ERROR_FIELD;
		}
		if( p ) *value = p;
	}else{
		return DAO_ERROR_FIELD_NOTPERMIT;
	}
	return 0;
}
Ejemplo n.º 3
0
static int DaoClass_MapIndex( DaoClass *mixin, int st, int id, DMap *mixed )
{
	int offset = 0;
	DaoClass *mx = DaoClass_FindMixin( mixin, st, id, & offset );
	DNode *it = DMap_Find( mixed, mx );
	if( it != NULL ) it = MAP_Find( it->value.pMap, LOOKUP_BIND( st, 0, 0, id-offset ) );
	if( it != NULL ) return LOOKUP_ID( it->value.pInt );
	return id;
}
Ejemplo n.º 4
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 );
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 7
0
/* receive reactions updated by middle nodes */
static void receive_middle_reactions (DOM *dom, COMDATA *recv, int nrecv, MEM *setmem, SET **midupd)
{
  COMDATA *ptr;
  int i, j, *k;
  CON *con;

  for (i = 0, ptr = recv; i < nrecv; i ++, ptr ++)
  {
    for (j = 0, k = ptr->i; j < ptr->ints; j ++, k ++)
    {
      ASSERT_DEBUG_EXT (con = MAP_Find (dom->conext, (void*) (long) (*k), NULL), "Invalid constraint id");
      SET_Insert (setmem, midupd, con, NULL);
    }
  }
}
Ejemplo n.º 8
0
/* receive external reactions */
static void receive_reactions (DOM *dom, COMDATA *recv, int nrecv)
{
  COMDATA *ptr;
  int i, j, *k;
  double *R;
  CON *con;

  for (i = 0, ptr = recv; i < nrecv; i ++, ptr ++)
  {
    for (j = 0, k = ptr->i, R = ptr->d; j < ptr->ints; j ++, k ++, R += 3)
    {
      ASSERT_DEBUG_EXT (con = MAP_Find (dom->conext, (void*) (long) (*k), NULL), "Invalid constraint id");
      COPY (R, con->R);
      con->state |= CON_DONE;
    }
  }
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
int DaoClass_AddConst( DaoClass *self, DString *name, DaoValue *data, int s )
{
	int sto, pm, up, id;
	DNode *node = MAP_Find( self->lookupTable, name );
	DaoNamespace *ns = self->classRoutine->nameSpace;
	DaoConstant *dest;
	DaoValue *value;

	assert( data != NULL );
	if( node && LOOKUP_UP( node->value.pInt ) ){ /* inherited field: */
		sto = LOOKUP_ST( node->value.pInt );
		pm = LOOKUP_PM( node->value.pInt );
		id = LOOKUP_ID( node->value.pInt );
		if( sto != DAO_CLASS_CONSTANT ){ /* override inherited variable: */
			DMap_EraseNode( self->lookupTable, node );
			return DaoClass_AddConst( self, name, data, s );
		}
		node->value.pInt = LOOKUP_BIND( sto, pm, 0, id );
		dest = self->constants->items.pConst[id];
		if( dest->value->type == DAO_ROUTINE && data->type == DAO_ROUTINE ){
			/* Add the inherited routine(s) for overloading: */
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, (DaoRoutine*) dest->value );
			DaoConstant *cst = DaoConstant_New( (DaoValue*) routs );
			GC_ShiftRC( cst, dest );
			self->constants->items.pConst[id] = cst;
			return DaoClass_AddConst( self, name, data, s );
		}else{
			/* Add the new constant: */
			DaoConstant *cst = DaoConstant_New( data );
			GC_ShiftRC( cst, dest );
			self->constants->items.pConst[id] = cst;
			return node->value.pInt;
		}
	}else if( node ){
		sto = LOOKUP_ST( node->value.pInt );
		pm = LOOKUP_PM( node->value.pInt );
		id = LOOKUP_ID( node->value.pInt );
		if( sto != DAO_CLASS_CONSTANT ) return -DAO_CTW_WAS_DEFINED;
		dest = self->constants->items.pConst[id];
		value = dest->value;
		if( value->type != DAO_ROUTINE || data->type != DAO_ROUTINE ) return -DAO_CTW_WAS_DEFINED;
		if( s > pm ) node->value.pInt = LOOKUP_BIND( sto, s, 0, id );
		if( value->xRoutine.overloads == NULL || value->xRoutine.routHost != self->objType ){
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, (DaoRoutine*) value );
			routs->trait |= DAO_VALUE_CONST;
			/* Add individual entry for the existing function: */
			if( value->xRoutine.routHost == self->objType ) DaoClass_AddConst3( self, name, value );
			GC_ShiftRC( routs, dest->value );
			dest->value = (DaoValue*) routs;
		}
		if( data->xRoutine.overloads ){
			DaoRoutines_Import( (DaoRoutine*) dest->value, data->xRoutine.overloads );
		}else{
			DaoRoutine *rout = (DaoRoutine*) data;
			DRoutines_Add( dest->value->xRoutine.overloads, rout );
			if( self->vtable ) DaoRoutine_UpdateVtable( (DaoRoutine*)dest->value, rout, self->vtable );
			/* Add individual entry for the new function: */
			if( data->xRoutine.routHost == self->objType ) DaoClass_AddConst3( self, name, data );
		}
		return node->value.pInt;
	}

	node = MAP_Find( self->lookupTable, name );
	if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED;
	return DaoClass_AddConst2( self, name, data, s );
}
Ejemplo n.º 15
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
}
Ejemplo n.º 16
0
/* read constraint state */
static CON* read_constraint (DOM *dom, int iover, PBF *bf)
{
  SOLFEC_MODE mode = dom->solfec->mode;
  unsigned int id;
  CON *con;
  int kind;

  ERRMEM (con = MEM_Alloc (&dom->conmem));

  PBF_Uint (bf, &con->id, 1);
  PBF_Int (bf, &kind, 1);
  con->kind = kind;

  PBF_Double (bf, con->R, 3);
  PBF_Double (bf, con->U, 3);
  if (iover > 1 && kind == CONTACT)
  {
    PBF_Double (bf, con->V, 3);
  }
  PBF_Double (bf, con->point, 3);
  PBF_Double (bf, con->base, 9);
  PBF_Double (bf, &con->merit, 1);

  PBF_Uint (bf, &id, 1);
  ASSERT_DEBUG_EXT (con->master = MAP_Find (dom->allbodies, (void*) (long) id, NULL), "Invalid master id");
  PBF_Uint (bf, &id, 1);
  if (id) ASSERT_DEBUG_EXT (con->slave = MAP_Find (dom->allbodies, (void*) (long) id, NULL), "Invalid slave id");

  if (kind == CONTACT)
  {
    con->state |= SURFACE_MATERIAL_Read_State (dom->sps, &con->mat, bf);
    PBF_Double (bf, &con->area, 1);
    PBF_Double (bf, &con->gap, 1);
    PBF_Int (bf, con->spair, 2);
  }

  if (iover < 4)
  {
    if (kind == RIGLNK ||
        kind == VELODIR) PBF_Double (bf, con->Z, DOM_Z_SIZE);
  }
  else
  {
    if (kind == RIGLNK ||
        kind == VELODIR ||
	kind == SPRING) PBF_Double (bf, con->Z, DOM_Z_SIZE);
  }

  if (bf->parallel == PBF_ON)
  {
    if (mode == SOLFEC_READ)
    {
      PBF_Int (bf, &con->rank, 1);
    }
    else /* fake it => ranks are actually used in WRITE mode */
    {
      int rank;
      PBF_Int (bf, &rank, 1);
    }
  }

  return con;
}
Ejemplo n.º 17
0
DaoRoutine* DaoClass_GetOverloadedRoutine( DaoClass *self, DString *signature )
{
	DNode *node = MAP_Find( self->ovldRoutMap, signature );
	if( node ) return (DaoRoutine*) node->value.pValue;
	return NULL;
}
Ejemplo n.º 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;
}
Ejemplo n.º 19
0
int DaoClass_AddConst( DaoClass *self, DString *name, DaoValue *data, int s )
{
	int fromMixin = 0;
	int fromParent = 0;
	int sto, pm, up, id;
	DNode *node = MAP_Find( self->lookupTable, name );
	DaoNamespace *ns = self->classRoutine->nameSpace;
	DaoConstant *dest;
	DaoValue *value;

	if( node ){
		id = LOOKUP_ID( node->value.pInt );
		fromParent = LOOKUP_UP( node->value.pInt ); /* From parent classes; */
		switch( LOOKUP_ST( node->value.pInt ) ){ /* Check if it is from mixins; */
		case DAO_CLASS_CONSTANT :
			fromMixin = id >= self->cstMixinStart && id < self->cstMixinEnd;
			break;
		case DAO_CLASS_VARIABLE :
			fromMixin = id >= self->glbMixinStart && id < self->glbMixinEnd;
			break;
		case DAO_OBJECT_VARIABLE :
			fromMixin = id >= self->objMixinStart && id < self->objMixinEnd;
			break;
		}
	}

	assert( data != NULL );
	if( fromParent || fromMixin ){ /* inherited field: */
		sto = LOOKUP_ST( node->value.pInt );
		pm = LOOKUP_PM( node->value.pInt );
		id = LOOKUP_ID( node->value.pInt );
		if( sto != DAO_CLASS_CONSTANT ){ /* override inherited variable: */
			DMap_EraseNode( self->lookupTable, node );
			return DaoClass_AddConst( self, name, data, s );
		}
		node->value.pInt = LOOKUP_BIND( sto, pm, 0, id );
		dest = self->constants->items.pConst[id];
		if( dest->value->type == DAO_ROUTINE && data->type == DAO_ROUTINE ){
			/* Add the inherited routine(s) for overloading: */
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, (DaoRoutine*)dest->value );
			DaoConstant *cst = DaoConstant_New( (DaoValue*) routs );
			routs->trait |= DAO_VALUE_CONST;
			node->value.pInt = LOOKUP_BIND( sto, pm, 0, self->constants->size );
			DArray_Append( self->cstDataName, (void*) name );
			DArray_Append( self->constants, cst );
			return DaoClass_AddConst( self, name, data, s );
		}else{
			/* Add the new constant: */
			DaoConstant *cst = DaoConstant_New( data );
			node->value.pInt = LOOKUP_BIND( sto, pm, 0, self->constants->size );
			DArray_Append( self->cstDataName, (void*) name );
			DArray_Append( self->constants, cst );
			return node->value.pInt;
		}
	}else if( node ){
		sto = LOOKUP_ST( node->value.pInt );
		pm = LOOKUP_PM( node->value.pInt );
		id = LOOKUP_ID( node->value.pInt );
		if( sto != DAO_CLASS_CONSTANT ) return -DAO_CTW_WAS_DEFINED;
		dest = self->constants->items.pConst[id];
		value = dest->value;
		if( value->type != DAO_ROUTINE || data->type != DAO_ROUTINE ) return -DAO_CTW_WAS_DEFINED;
		if( s > pm ) node->value.pInt = LOOKUP_BIND( sto, s, 0, id );
		if( value->xRoutine.overloads == NULL || value->xRoutine.routHost != self->objType ){
			DaoRoutine *routs = DaoRoutines_New( ns, self->objType, (DaoRoutine*) value );
			routs->trait |= DAO_VALUE_CONST;
			/* Add individual entry for the existing function: */
			if( value->xRoutine.routHost == self->objType ) DaoClass_AddConst3( self, name, value );
			GC_ShiftRC( routs, dest->value );
			dest->value = (DaoValue*) routs;
		}
		if( data->xRoutine.overloads ){
			DaoRoutines_Import( (DaoRoutine*) dest->value, data->xRoutine.overloads );
		}else{
			DaoRoutine *rout = (DaoRoutine*) data;
			DRoutines_Add( dest->value->xRoutine.overloads, rout );
			/* Add individual entry for the new function: */
			if( data->xRoutine.routHost == self->objType ) DaoClass_AddConst3( self, name, data );
		}
		return node->value.pInt;
	}

	node = MAP_Find( self->lookupTable, name );
	if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED;
	return DaoClass_AddConst2( self, name, data, s );
}
Ejemplo n.º 20
0
int DaoClass_GetDataIndex( DaoClass *self, DString *name )
{
	DNode *node = MAP_Find( self->lookupTable, name );
	if( ! node ) return -1;
	return node->value.pInt;
}
Ejemplo n.º 21
0
/* initialize domain state */
int dom_init_state (DOM *dom, PBF *bf, SET *subset)
{
  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);
      }
 
      ASSERT_TEXT (iover >= 3, "Output files are too old for INITIALISE_STATE to work");

      /* read body states */

      if (subset)
      {
#if POSIX
	for (SET *item = SET_First (subset); item; item = SET_Next (item))
	{
	  regex_t xp;
	  char *pattern = item->data;
	  int error = regcomp (&xp, pattern, 0);

	  if (error != 0)
	  {
	    char *message = get_regerror (error, &xp);
	    fprintf (stderr, "-->\n");
	    fprintf (stderr, "Regular expression ERROR --> %s\n", message);
	    fprintf (stderr, "<--\n");
	    regfree (&xp);
	    free (message);
	    return 0;
	  }

	  for (BODY *bod = dom->bod; bod; bod = bod->next)
	  {
	    if (bod->label && regexec (&xp, bod->label, 0, NULL, 0) == 0)
	    {
	      if (PBF_Label (bf, bod->label))
	      {
	        BODY_Read_State (bod, bf, iover);
	      }
	    }
	  }

	  regfree (&xp);
	}
#else
	ASSERT_TEXT (0, "Regular expressions require POSIX support --> recompile Solfec with POSIX=yes");
	return 0;
#endif
      }
      else
      {
	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;
	  BODY *bod;

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

	  if (bod) /* update state of existing bodies only */
	  {
	    BODY_Read_State (bod, bf, iover);
	  }
	  else /* mock read */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);

	    double *conf;
	    double *velo;
	    double energy[10];
	    int rank;

	    ERRMEM (conf = malloc (sizeof(double) * rconf));
	    ERRMEM (velo = malloc (sizeof(double) * rdofs));

	    PBF_Double (bf, conf, rconf);
	    PBF_Double (bf, velo, rdofs);
	    PBF_Double (bf, energy, BODY_ENERGY_SIZE(rkind));
	    if (bf->parallel == PBF_ON)
	    {
	      PBF_Int (bf, &rank, 1);
	    }

	    free (conf);
	    free (velo);
	  }
	}
      }
    }
  }

  return 1;
}
Ejemplo n.º 22
0
/* assumed to be called before parsing class body */
void DaoClass_DeriveClassData( DaoClass *self )
{
	DaoType *type;
	DaoValue *value;
	DArray *parents, *offsets;
	DString *mbs;
	DNode *it, *search;
	daoint i, k, id, perm, index;

	mbs = DString_New(1);

	if( self->clsType->bases == NULL ) self->clsType->bases = DArray_New(D_VALUE);
	if( self->objType->bases == NULL ) self->objType->bases = DArray_New(D_VALUE);
	DArray_Clear( self->clsType->bases );
	DArray_Clear( self->objType->bases );
	for(i=0; i<self->superClass->size; i++){
		if( self->superClass->items.pValue[i]->type == DAO_CLASS ){
			DaoValue *klass = self->superClass->items.pValue[i];
			DArray_Append( self->clsType->bases, klass->xClass.clsType );
			DArray_Append( self->objType->bases, klass->xClass.objType );
			DString_Assign( mbs, klass->xClass.className );
			DString_AppendChar( mbs, '#' );
			DString_AppendInteger( mbs, i+1 );
			DaoClass_AddConst( self, mbs, klass, DAO_DATA_PRIVATE );
		}else if( self->superClass->items.pValue[i]->type == DAO_CTYPE ){
			DaoCtype *cdata = (DaoCtype*) self->superClass->items.pValue[i];
			DaoTypeKernel *kernel = cdata->ctype->kernel;
			DMap *values = kernel->values;
			DMap *methods = kernel->methods;

			DArray_Append( self->clsType->bases, cdata->ctype );
			DArray_Append( self->objType->bases, cdata->cdtype );
			if( values == NULL ){
				DaoNamespace_SetupValues( kernel->nspace, kernel->typer );
				values = kernel->values;
			}
			if( methods == NULL ){
				DaoNamespace_SetupMethods( kernel->nspace, kernel->typer );
				methods = kernel->methods;
			}

			DString_Assign( mbs, cdata->ctype->name );
			// XXX
			DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE );
			DString_AppendChar( mbs, '#' );
			DString_AppendInteger( mbs, i+1 );
			DaoClass_AddConst( self, mbs, (DaoValue*)cdata, DAO_DATA_PRIVATE );
		}
	}
	parents = DArray_New(0);
	offsets = DArray_New(0);
	DaoClass_Parents( self, parents, offsets );
	for(i=1; i<parents->size; i++){
		DaoClass *klass = parents->items.pClass[i];
		DaoCdata *cdata = parents->items.pCdata[i];
		if( klass->type == DAO_CLASS ){
			if( klass->vtable ){
				if( self->vtable == NULL ) self->vtable = DHash_New(0,0);
				for(it=DMap_First(klass->vtable); it; it=DMap_Next(klass->vtable,it)){
					DMap_Insert( self->vtable, it->key.pVoid, it->value.pVoid );
				}
			}
			/* For class data: */
			for( id=0; id<klass->cstDataName->size; id++ ){
				DString *name = klass->cstDataName->items.pString[id];
				value = klass->constants->items.pConst[ id ]->value;
				search = MAP_Find( klass->lookupTable, name );
				if( search == NULL ) continue;
				perm = LOOKUP_PM( search->value.pInt );
				/* NO deriving private member: */
				if( perm <= DAO_DATA_PRIVATE ) continue;
				if( value->type == DAO_ROUTINE ){
					if( DString_EQ( value->xRoutine.routName, klass->className ) ) continue;
				}
				search = MAP_Find( self->lookupTable, name );
				if( search == NULL && value->type == DAO_ROUTINE && value->xRoutine.overloads ){
					/* To skip the private methods: */
					DaoClass_AddConst( self, name, (DaoValue*)value, perm );
				}else if( search == NULL ){
					index = LOOKUP_BIND( DAO_CLASS_CONSTANT, perm, i+1, self->constants->size );
					MAP_Insert( self->lookupTable, name, index );
					DArray_Append( self->constants, klass->constants->items.pConst[id] );
					DArray_Append( self->cstDataName, (void*)name );
					if( value->type == DAO_ROUTINE && (value->xRoutine.attribs & DAO_ROUT_VIRTUAL) ){
						if( self->vtable == NULL ) self->vtable = DHash_New(0,0);
						MAP_Insert( self->vtable, value, value );
					}
				}else if( value->type == DAO_ROUTINE && value->xRoutine.overloads ){
					DRoutines *routs = value->xRoutine.overloads;
					for(k=0; k<routs->routines->size; k++){
						DaoRoutine *rout = routs->routines->items.pRoutine[k];
						/* skip methods not defined in this parent type */
						if( rout->routHost != klass->objType ) continue;
						if( rout->attribs & DAO_ROUT_PRIVATE ) continue;
						DaoClass_AddConst( self, name, (DaoValue*)rout, perm );
					}
				}else if( value->type == DAO_ROUTINE ){
					/* skip methods not defined in this parent type */
					if( value->xRoutine.routHost != klass->objType ) continue;
					if( value->xRoutine.attribs & DAO_ROUT_PRIVATE ) continue;
					DaoClass_AddConst( self, name, value, perm );
				}
			}
			/* class global data */
			for( id=0; id<klass->glbDataName->size; id ++ ){
				DString *name = klass->glbDataName->items.pString[id];
				DaoVariable *var = klass->variables->items.pVar[id];
				search = MAP_Find( klass->lookupTable, name );
				perm = LOOKUP_PM( search->value.pInt );
				/* NO deriving private member: */
				if( perm <= DAO_DATA_PRIVATE ) continue;
				search = MAP_Find( self->lookupTable, name );
				/* To overide data: */
				if( search == NULL ){
					index = LOOKUP_BIND( DAO_CLASS_VARIABLE, perm, i+1, self->variables->size );
					MAP_Insert( self->lookupTable, name, index );
					DArray_Append( self->variables, var );
					DArray_Append( self->glbDataName, (void*)name );
				}
			}
		}else if( cdata->type == DAO_CTYPE ){
			DaoCtype *ctypeobj = (DaoCtype*) cdata;
			DaoTypeKernel *kernel = cdata->ctype->kernel;
			DaoTypeBase *typer = kernel->typer;
			DMap *values = kernel->values;
			DMap *methods = kernel->methods;
			DNode *it;
			int j;

			DaoCdataType_SpecializeMethods( cdata->ctype );
			kernel = cdata->ctype->kernel;
			methods = kernel->methods;

			if( typer->numItems ){
				for(j=0; typer->numItems[j].name!=NULL; j++){
					DString name = DString_WrapMBS( typer->numItems[j].name );
					it = DMap_Find( values, & name );
					if( it && DMap_Find( self->lookupTable, & name ) == NULL )
						DaoClass_AddConst( self, it->key.pString, it->value.pValue, DAO_DATA_PUBLIC );
				}
			}
			for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){
				DaoRoutine *func = it->value.pRoutine;
				DaoRoutine **funcs = & func;
				int k, count = 1;
				if( it->value.pValue->type == DAO_ROUTINE && it->value.pRoutine->overloads ){
					DRoutines *routs = it->value.pRoutine->overloads;
					funcs = routs->routines->items.pRoutine;
					count = routs->routines->size;
				}
				for(k=0; k<count; k++){
					DaoRoutine *func = funcs[k];
					if( func->routHost != ctypeobj->cdtype ) continue;
					if( func->attribs & DAO_ROUT_INITOR ) continue;
					DaoClass_AddConst( self, it->key.pString, (DaoValue*)func, DAO_DATA_PUBLIC );
				}
			}
		}
	}
	DArray_Delete( parents );
	DArray_Delete( offsets );
	DString_Delete( mbs );
}
Ejemplo n.º 23
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);
}
Ejemplo n.º 24
0
int  DaoClass_FindConst( DaoClass *self, DString *name )
{
	DNode *node = MAP_Find( self->lookupTable, name );
	if( node == NULL || LOOKUP_ST( node->value.pInt ) != DAO_CLASS_CONSTANT ) return -1;
	return node->value.pInt;
}
Ejemplo n.º 25
0
/* read state of an individual body */
int dom_read_body (DOM *dom, PBF *bf, BODY *bod)
{
  /* read iover */

  int iover = 2;

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

  if (bod->label)
  {
    for (; bf; bf = bf->next)
    {
      if (PBF_Label (bf, bod->label))
      {
	BODY_Read_State (bod, bf, iover);
	return 1;
      }
    }
  }
  else
  {
    for (; bf; bf = bf->next)
    {
      if (PBF_Label (bf, "BODS"))
      {
	int nbod;

	PBF_Int (bf, &nbod, 1);

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

	  PBF_Uint (bf, &id, 1);
	  ASSERT_DEBUG_EXT (obj = MAP_Find (dom->idb, (void*) (long) id, NULL), "Body id invalid");
	  if (bod->id == obj->id) 
	  {
	    BODY_Read_State (bod, bf, iover);
	    return 1;
	  }
	  else /* skip body and continue */
	  {
	    BODY fake;

	    ERRMEM (fake.conf = malloc (sizeof (double [BODY_Conf_Size (obj)])));
	    ERRMEM (fake.velo = malloc (sizeof (double [obj->dofs])));
	    fake.shape = NULL;

	    BODY_Read_State (&fake, bf, iover);

	    free (fake.conf);
	    free (fake.velo);
	  }
	}
      }
    }
  }

  return 0;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
/* map rigid onto FEM state */
int dom_rigid_to_fem (DOM *dom, PBF *bf, SET *subset)
{
  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);
      }

      ASSERT_TEXT (iover >= 3, "Output files are too old for RIGID_TO_FEM to work");

      /* read body states */

      if (subset)
      {
#if POSIX
	for (SET *item = SET_First (subset); item; item = SET_Next (item))
	{
	  regex_t xp;
	  char *pattern = item->data;
	  int error = regcomp (&xp, pattern, 0);

	  if (error != 0)
	  {
	    char *message = get_regerror (error, &xp);
	    fprintf (stderr, "-->\n");
	    fprintf (stderr, "Regular expression ERROR --> %s\n", message);
	    fprintf (stderr, "<--\n");
	    regfree (&xp);
	    free (message);
	    return 0;
	  }

	  for (BODY *bod = dom->bod; bod; bod = bod->next)
	  {
	    if (bod->label && regexec (&xp, bod->label, 0, NULL, 0) == 0)
	    {
	      if (PBF_Label (bf, bod->label))
	      {
	        double conf [12],
		       velo [6],
		       energy [4];

		int rkind;
		int rconf;
		int rdofs;

		PBF_Int (bf, &rkind, 1);
		PBF_Int (bf, &rconf, 1);
		PBF_Int (bf, &rdofs, 1);
       
		if (bod->kind == FEM && rkind == RIG)
		{

		  PBF_Double (bf, conf, 12);
		  PBF_Double (bf, velo, 6);
		  PBF_Double (bf, energy, 4);

		  BODY_From_Rigid (bod, conf, conf+9, velo, velo+3);
		}
		else
		{
		  ASSERT_TEXT (((bod->kind == RIG || bod->kind == OBS) &&
		    (rkind == RIG || rkind == OBS)) || bod->kind == (unsigned)rkind, "Body kind mismatch when reading state");
		  ASSERT_TEXT (BODY_Conf_Size (bod) == rconf, "Body configuration size mismatch when reading state");
		  ASSERT_TEXT (bod->dofs == rdofs, "Body dofs size mismatch when reading state");

		  BODY_Read_State (bod, bf, 0); /* use 0 state to skip reading of rkind, rnconf, rdofs */
		}
	      }
	    }
	  }

	  regfree (&xp);
	}
#else
	ASSERT_TEXT (0, "Regular expressions require POSIX support --> recompile Solfec with POSIX=yes");
	return 0;
#endif
      }
      else
      {
	ASSERT (PBF_Label (bf, "BODS"), ERR_FILE_FORMAT);

	int nbod;

	PBF_Int (bf, &nbod, 1);

	for (int n = 0; n < nbod; n ++)
	{
	  double conf [12], velo [6], energy [4];
	  unsigned int id;
	  BODY *bod;
	  int rank;

	  PBF_Uint (bf, &id, 1);

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

	  if (bod) /* update state of existing bodies only */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);
   
	    if (bod->kind == FEM && rkind == RIG)
	    {

	      PBF_Double (bf, conf, 12);
	      PBF_Double (bf, velo, 6);
	      PBF_Double (bf, energy, 4);
	      if (bf->parallel == PBF_ON)
	      {
		PBF_Int (bf, &rank, 1);
	      }

	      BODY_From_Rigid (bod, conf, conf+9, velo, velo+3);
	    }
	    else
	    {
	      ASSERT_TEXT (((bod->kind == RIG || bod->kind == OBS) &&
		(rkind == RIG || rkind == OBS)) || bod->kind == (unsigned)rkind, "Body kind mismatch when reading state");
	      ASSERT_TEXT (BODY_Conf_Size (bod) == rconf, "Body configuration size mismatch when reading state");
	      ASSERT_TEXT (bod->dofs == rdofs, "Body dofs size mismatch when reading state");

	      BODY_Read_State (bod, bf, 0); /* use 0 state to skip reading of rkind, rnconf, rdofs */
	    }
	  }
	  else /* mock read */
	  {
	    int rkind;
	    int rconf;
	    int rdofs;

	    PBF_Int (bf, &rkind, 1);
	    PBF_Int (bf, &rconf, 1);
	    PBF_Int (bf, &rdofs, 1);

	    double *conf;
	    double *velo;
	    double energy[10];
	    int rank;

	    ERRMEM (conf = malloc (sizeof(double) * rconf));
	    ERRMEM (velo = malloc (sizeof(double) * rdofs));

	    PBF_Double (bf, conf, rconf);
	    PBF_Double (bf, velo, rdofs);
	    PBF_Double (bf, energy, BODY_ENERGY_SIZE(rkind));
	    if (bf->parallel == PBF_ON)
	    {
	      PBF_Int (bf, &rank, 1);
	    }

	    free (conf);
	    free (velo);
	  }
	}
      }
    }
  }

  return 1;
}
Ejemplo n.º 28
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;
}