コード例 #1
0
ファイル: daoStdlib.c プロジェクト: hooloong/dao
static void STD_Load( DaoProcess *proc, DaoValue *p[], int N )
{
	DString *name = p[0]->xString.data;
	int import = p[1]->xInteger.value;
	int runim = p[2]->xInteger.value;
	int safe = p[3]->xInteger.value;
	int wasProt = 0;
	int res = 0;
	DaoVmSpace *vms = proc->vmSpace;
	DaoNamespace *ns;
	DString_ToMBS( name );
	if( safe ) vms->options |= DAO_OPTION_SAFE;
	if( vms->options & DAO_OPTION_SAFE ) wasProt = 1;
	DArray_PushFront( vms->pathLoading, proc->activeNamespace->path );
	ns = DaoVmSpace_LoadEx( vms, DString_GetMBS( name ), runim );
	DaoProcess_PutValue( proc, (DaoValue*) ns );
	if( ! wasProt ) vms->options &= ~DAO_OPTION_SAFE;
	if( ns ){ /* in the case that it is cancelled from console */
		DArray_PushFront( vms->pathLoading, ns->path );
		res = DaoProcess_Call( proc, ns->mainRoutine, NULL, NULL, 0 );
		if( proc->stopit | vms->stopit ){
			DaoProcess_RaiseException( proc, DAO_ERROR, "loading cancelled" );
		}else if( res ){
			DaoProcess_RaiseException( proc, res, "loading failed" );
		}
		DArray_PopFront( vms->pathLoading );
	}else{
		DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" );
	}
	DArray_PopFront( vms->pathLoading );
	if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns );
}
コード例 #2
0
ファイル: daoArray.c プロジェクト: cosim/dao
void DArray_Insert( DArray *self, void *val, daoint id )
{
	void **buf = self->items.pVoid - self->offset;
	daoint i;
	if( id == 0 ){
		DArray_PushFront( self, val );
		return;
	}else if( id >= self->size ){
		DArray_PushBack( self, val );
		return;
	}
	if( (daoint)(self->offset + self->size + 1) >= self->bufsize ){
		int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0;
		if( self->offset > 0 ) memmove( buf, self->items.pVoid, self->size*sizeof(void*) );
		self->bufsize += self->bufsize/5 + 5;
		self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) );
		self->offset = 0;
		DaoGC_UnlockArray( self, locked );
	}
	if( self->type && val != NULL ){
		int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0;
		for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1];
		DaoGC_UnlockArray( self, locked );
		self->items.pVoid[ id ] = DArray_CopyItem( self, val );
	}else{
		for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1];
		self->items.pVoid[id] = val;
	}
	self->size++;
}
コード例 #3
0
/*
// Note: reference count is not handled for "self"!
// But it is cached in the DaoProcess object, so no need to handle it by user!
*/
int DaoValue_Deserialize( DaoValue **self, DString *serial, DaoNamespace *ns, DaoProcess *proc )
{
	DaoParser *parser = DaoParser_New();
	DArray *types = DArray_New(0);
	DMap *omap = DMap_New(0,0);
	int rc;

	*self = NULL;
	parser->nameSpace = ns;
	parser->vmSpace = ns->vmSpace;
	DaoParser_LexCode( parser, DString_GetMBS( serial ), 0 );
	if( parser->tokens->size == 0 ) goto Failed;

	DArray_PushFront( types, NULL );
	rc = DaoParser_Deserialize( parser, 0, parser->tokens->size-1, self, types, ns, proc, omap );
	if( *self ) DaoProcess_CacheValue( proc, *self );
	DaoParser_Delete( parser );
	DArray_Delete( types );
	DMap_Delete( omap );
	return rc;
Failed:
	DaoParser_Delete( parser );
	DArray_Delete( types );
	DMap_Delete( omap );
	return 0;
}
コード例 #4
0
ファイル: daoMacro.c プロジェクト: hooloong/dao
/* Backward traverse the macro units and set stopping tokens for each unit.
 * A stopping token is defined as the content of a macro unit of type DMACRO_TOK.
 * XXX, also define stopping token by DMACRO_BR units?
 */
static void DMacroGroup_SetStop( DMacroGroup *self, DArray *stops )
{
	DMacroGroup *group;
	daoint i, j;
	/*
	   printf( "stop : %i\n", stops->size );
	 */

	for(i=self->units->size-1; i>=0; i--){
		DMacroUnit *unit = (DMacroUnit*) self->units->items.pVoid[i];
		if( unit->type == DMACRO_GRP || unit->type == DMACRO_ALT ){
			group = (DMacroGroup*) unit;
			/* self->stops as temporary array: */
			DArray_Assign( self->stops, stops );
			/* recursive set stopping tokens for macro groups: */
			DMacroGroup_SetStop( group, self->stops );
			/* if the group has to be presented at least once,
			 * no propagating the stopping tokens to the previous macro units. */
			if( group->repeat > DMACRO_ZERO_OR_MORE ) DArray_Clear( stops );
			/* add stopping token, why only one ? XXX */
			if( group->stops->size >0) DArray_PushFront( stops, group->stops->items.pString[0] );
		}else if( unit->type == DMACRO_TOK ){
			/*
			   printf( "%s", unit->marker->mbs );
			 */
			DArray_Clear( stops );
			/* define a stopping token */
			DArray_Append( stops, unit->marker );
			DArray_Append( unit->stops, unit->marker );
		}else{
			/*
			   printf( "%s", unit->marker->mbs );
			 */
			for(j=0; j<stops->size; j++) DArray_Append( unit->stops, stops->items.pString[j] );
		}
		/*
		   printf( " : %i;  ", unit->stops->size );
		 */
	}
	if( self->repeat == DMACRO_ZERO_OR_MORE || self->repeat == DMACRO_ONE_OR_MORE ){
		/* this is fine for DMACRO_GRP unit, what about DMACRO_ALT unit? XXX */
		if( self->units->size >1 ){
			DMacroUnit *first = (DMacroUnit*) self->units->items.pVoid[0];
			DMacroGroup_AddStop( self, first->stops );
		}
	}
	DArray_Assign( self->stops, stops );
	/*
	   printf( "group : %i\n", self->stops->size );
	 */
}
コード例 #5
0
ファイル: daoStdlib.c プロジェクト: wherby/dao
static void STD_Load( DaoProcess *proc, DaoValue *p[], int N )
{
	DString *name = p[0]->xString.data;
	int import = p[1]->xInteger.value;
	int runim = p[2]->xInteger.value;
	int safe = p[3]->xInteger.value;
	int wasProt = 0;
	int res = 0;
	DaoVmSpace *vms = proc->vmSpace;
	DaoNamespace *ns;
	DString_ToMBS( name );
	if( safe ) vms->options |= DAO_OPTION_SAFE;
	if( vms->options & DAO_OPTION_SAFE ) wasProt = 1;
	DArray_PushFront( vms->pathLoading, proc->activeNamespace->path );
	ns = DaoVmSpace_LoadEx( vms, DString_GetMBS( name ), runim );
	DaoProcess_PutValue( proc, (DaoValue*) ns );
	if( ! wasProt ) vms->options &= ~DAO_OPTION_SAFE;
	if( ns == NULL ) DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" );
	DArray_PopFront( vms->pathLoading );
	if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns );
}
コード例 #6
0
void DaoNamespace_Restore( DaoNamespace *self, DaoProcess *proc, FILE *fin )
{
	DaoParser *parser = DaoParser_New();
	DString *line = DString_New(1);
	DArray *types = DArray_New(0);
	DArray *tokens = parser->tokens;
	DMap *omap = DMap_New(0,0);
	DString *name;
	DNode *node;

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

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

		DArray_Clear( parser->errors );
		DArray_Clear( types );
		DArray_PushFront( types, NULL );
		DaoParser_Deserialize( parser, start, tokens->size-1, &value, types, self, proc, omap );
		if( value == NULL ) continue;
		node = DMap_Find( self->lookupTable, name );
		if( node ) continue;
		if( st == DAO_GLOBAL_CONSTANT ){
			DaoNamespace_AddConst( self, name, value, pm );
		}else{
			DaoNamespace_AddVariable( self, name, value, NULL, pm );
		}
	}
	DMap_Delete( omap );
	DString_Delete( line );
	DArray_Delete( types );
	DaoParser_Delete( parser );
}
コード例 #7
0
/*
// Note: reference count is handled for "value2"!
// 
// Item of list/tuple etc. can be directly passed as parameter "value2",
// to avoid creating unnecessary intermediate objects.
*/
static int DaoParser_Deserialize( DaoParser *self, int start, int end, DaoValue **value2, DArray *types, DaoNamespace *ns, DaoProcess *proc, DMap *omap )
{
	DaoToken **tokens = self->tokens->items.pToken;
	DaoType *it1 = NULL, *it2 = NULL, *type = NULL;
	DaoValue *value = *value2;
	DaoValue *tmp = NULL;
	DaoValue *tmp2 = NULL;
	DaoObject *object;
	DaoCdata *cdata;
	DaoArray *array;
	DaoTuple *tuple;
	DaoList *list;
	DaoMap *map;
	DArray *dims;
	DNode *node;
	void *key = NULL;
	char *str;
	int i, j, k, n;
	int minus = 0;
	int next = start + 1;
	int tok2 = start < end ? tokens[start+1]->type : 0;
	int maybetype = tok2 == DTOK_COLON2 || tok2 == DTOK_LT || tok2 == DTOK_LCB;

	if( tokens[start]->type == DTOK_AT && tok2 == DTOK_LCB ){
		int rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end );
		if( rb < 0 ) return next;
		sscanf( tokens[start+2]->string.mbs, "%p", & key );
		node = DMap_Find( omap, key );
		if( node ) DaoValue_Copy( node->value.pValue, value2 );
		return rb + 1;
	}
	if( tokens[start]->name == DTOK_ID_SYMBOL ){
		DString *mbs = DString_New(1);
		while( tokens[start]->name == DTOK_ID_SYMBOL ){
			DString_Append( mbs, & tokens[start]->string );
			start += 1;
		}
		type = DaoNamespace_MakeType( ns, mbs->mbs, DAO_ENUM, NULL, NULL, 0 );
		DString_Delete( mbs );
		if( type == NULL ) return start;
		if( tokens[start]->name != DTOK_LCB ) return start;
		end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end );
		if( end < 0 ) return start;
		next = end + 1;
		start += 1;
		end -= 1;
	}else if( tokens[start]->type == DTOK_IDENTIFIER && maybetype ){
		type = DaoParser_ParseType( self, start, end, & start, NULL );
		if( type == NULL ) return next;
		if( tokens[start]->name != DTOK_LCB ) return start;
		end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end );
		if( end < 0 ) return start;
		next = end + 1;
		start += 1;
		end -= 1;
	}
	if( type == NULL ){
		type = types->items.pType[0];
		if( type && type->tid >= DAO_ARRAY ){
			if( tokens[start]->name != DTOK_LCB ) return start;
			end = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, start, end );
			if( end < 0 ) return start;
			next = end + 1;
			start += 1;
			end -= 1;
		}
	}
	if( type == NULL ) return next;
	DaoValue_Copy( type->value, value2 );
	if( start > end ) return next;
	if( tokens[start]->name == DTOK_SUB ){
		minus = 1;
		start += 1;
		if( start > end ) return next;
	}
	if( type->nested && type->nested->size >0 ) it1 = type->nested->items.pType[0];
	if( type->nested && type->nested->size >1 ) it2 = type->nested->items.pType[1];
	if( tokens[start]->name == DTOK_LB ){
		int rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, start, end );
		if( rb < 0 ) return next;
		sscanf( tokens[start+1]->string.mbs, "%p", & key );
		DMap_Insert( omap, key, *value2 );
		start = rb + 1;
	}
	str = tokens[start]->string.mbs;
#if 0
	printf( "type: %s %s\n", type->name->mbs, str );
	for(i=start; i<=end; i++) printf( "%s ", tokens[i]->string.mbs ); printf( "\n" );
#endif
	value = *value2;
	switch( type->tid ){
	case DAO_NONE :
		break;
	case DAO_INTEGER :
		value->xInteger.value = DaoDecodeInteger( str );
		if( minus ) value->xInteger.value = - value->xInteger.value;
		break;
	case DAO_FLOAT :
		value->xFloat.value = DaoDecodeDouble( str );
		if( minus ) value->xFloat.value = - value->xFloat.value;
		break;
	case DAO_DOUBLE :
		value->xDouble.value = DaoDecodeDouble( str );
		if( minus ) value->xDouble.value = - value->xDouble.value;
		break;
	case DAO_COMPLEX :
		value->xComplex.value.real = DaoDecodeDouble( str );
		if( minus ) value->xComplex.value.real = - value->xComplex.value.real;
		if( start + 1 > end ) return start+1;
		minus = 0;
		if( tokens[start + 1]->name == DTOK_SUB ){
			minus = 1;
			start += 1;
			if( start + 1 > end ) return start+1;
		}
		value->xComplex.value.imag = DaoDecodeDouble( tokens[start+1]->string.mbs );
		if( minus ) value->xComplex.value.imag = - value->xComplex.value.imag;
		next = start + 2;
		break;
#ifdef DAO_WITH_LONGINT
	case DAO_LONG :
		value->xLong.value->base = DaoDecodeInteger( str );
		start += 1;
		if( tokens[start]->name == DTOK_ADD ){
			value->xLong.value->sign = 1;
			start += 1;
		}else if( tokens[start]->name == DTOK_SUB ){
			value->xLong.value->sign = -1;
			start += 1;
		}
		for(i=start; i<=end; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			DLong_PushBack( value->xLong.value, DaoDecodeInteger( tokens[i]->string.mbs ) );
		}
		break;
#endif
	case DAO_STRING :
		n = tokens[start]->string.size - 1;
		for(i=1; i<n; i++){
			char c1 = str[i];
			char c2 = str[i+1];
			if( c1 < 'A' || c1 > 'P' ) continue;
			DString_AppendChar( value->xString.data, (char)((c1-'A')*16 + (c2-'A')) );
			i += 1;
		}
		if( str[0] == '\"' ) DString_ToWCS( value->xString.data );
		break;
	case DAO_ENUM :
		value->xEnum.value = DaoDecodeInteger( str );
		break;
	case DAO_ARRAY :
#ifdef DAO_WITH_NUMARRAY
		if( tokens[start]->name != DTOK_LSB ) return next;
		k = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, start, end );
		if( k < 0 ) return next;
		n = 1;
		for(i=start+1; i<k; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			n *= strtol( tokens[i]->string.mbs, 0, 0 );
		}
		if( n < 0 ) return next;
		if( it1 == NULL || it1->tid == 0 || it1->tid > DAO_COMPLEX ) return next;
		array = & value->xArray;
		dims = DArray_New(0);
		for(i=start+1; i<k; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			j = strtol( tokens[i]->string.mbs, 0, 0 );
			DArray_Append( dims, (size_t) j );
		}
		n = dims->size;
		DaoArray_ResizeArray( array, dims->items.pInt, n );
		DArray_PushFront( types, it1 );
		DArray_Delete( dims );
		n = 0;
		for(i=k+1; i<=end; i++){
			j = i + 1;
			while( j <= end && tokens[j]->name != DTOK_COMMA ) j += 1;
			DaoParser_Deserialize( self, i, j-1, & tmp, types, ns, proc, omap );
			switch( it1->tid ){
			case DAO_INTEGER : array->data.i[n] = tmp->xInteger.value; break;
			case DAO_FLOAT   : array->data.f[n] = tmp->xFloat.value; break;
			case DAO_DOUBLE  : array->data.d[n] = tmp->xDouble.value; break;
			}
			i = j;
			n += 1;
		}
		DArray_PopFront( types );
#endif
		break;
	case DAO_LIST :
		list = & value->xList;
		DArray_PushFront( types, it1 );
		n = 0;
		for(i=start; i<=end; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			DArray_Append( & list->items, NULL );
			k = DaoParser_Deserialize( self, i, end, list->items.items.pValue + n, types, ns, proc, omap );
			i = k - 1;
			n += 1;
		}
		DArray_PopFront( types );
		break;
	case DAO_MAP :
		map = & value->xMap;
		n = 0;
		for(i=start; i<=end; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			DaoValue_Clear( & tmp );
			DaoValue_Clear( & tmp2 );
			DArray_PushFront( types, it1 );
			i = DaoParser_Deserialize( self, i, end, &tmp, types, ns, proc, omap );
			DArray_PopFront( types );
			if( tokens[i]->name == DTOK_COMMA ) continue;
			if( map->items->size == 0 ){
				if( tokens[i]->name == DTOK_COLON ){
					DMap_Delete( map->items );
					map->items = DHash_New( D_VALUE, D_VALUE );
				}
			}
			if( tokens[i]->name == DTOK_COLON || tokens[i]->name == DTOK_FIELD ) i += 1;
			DArray_PushFront( types, it2 );
			i = DaoParser_Deserialize( self, i, end, &tmp2, types, ns, proc, omap );
			DArray_PopFront( types );
			node = DMap_Insert( map->items, (void*) tmp, (void*) tmp2 );
			i -= 1;
			n += 1;
		}
		break;
	case DAO_TUPLE :
		tuple = & value->xTuple;
		n = 0;
		for(i=start; i<=end; i++){
			if( tokens[i]->name == DTOK_COMMA ) continue;
			it1 = NULL;
			if( type->nested && type->nested->size > n ){
				it1 = type->nested->items.pType[n];
				if( it1 && it1->tid == DAO_PAR_NAMED ) it1 = & it1->aux->xType;
			}
			DArray_PushFront( types, it1 );
			i = DaoParser_Deserialize( self, i, end, tuple->items + n, types, ns, proc, omap );
			DArray_PopFront( types );
			i -= 1;
			n += 1;
		}
		break;
	case DAO_OBJECT :
		DArray_PushFront( types, NULL );
		DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap );
		DArray_PopFront( types );
		if( tmp == NULL ) break;
		object = DaoClass_MakeObject( & type->aux->xClass, tmp, proc );
		if( object ) DaoValue_Copy( (DaoValue*) object, value2 );
		break;
	case DAO_CDATA :
	case DAO_CSTRUCT :
		DArray_PushFront( types, NULL );
		DaoParser_Deserialize( self, start, end, & tmp, types, ns, proc, omap );
		DArray_PopFront( types );
		if( tmp == NULL ) break;
		cdata = DaoCdata_MakeObject( & type->aux->xCdata, tmp, proc );
		if( cdata ) DaoValue_Copy( (DaoValue*) cdata, value2 );
		break;
	}
	DaoValue_Clear( & tmp );
	DaoValue_Clear( & tmp2 );
	return next;
}