Пример #1
0
void DaoxDataColumn_SetCell( DaoxDataColumn *self, daoint i, DaoValue *value )
{
	if( value == NULL ){
		complex16 zero = {0.0,0.0};
		switch( self->type->tid ){
		default :
			GC_DecRC( self->cells->data.values[i] );
			self->cells->data.values[i] = value;
			break;
		case DAO_INTEGER : self->cells->data.daoints[i]   = 0; break;
		case DAO_FLOAT   : self->cells->data.floats[i]    = 0.0; break;
		case DAO_DOUBLE  : self->cells->data.doubles[i]   = 0.0; break;
		case DAO_COMPLEX : self->cells->data.complexes[i] = zero; break;
		case DAO_STRING  : DString_Reset( & self->cells->data.strings[i], 0 ); break;
		}
		return;
	}
	switch( self->type->tid ){
	default :
		GC_ShiftRC( value, self->cells->data.values[i] );
		self->cells->data.values[i] = value;
		break;
	case DAO_INTEGER : self->cells->data.daoints[i]   = DaoValue_GetInteger( value ); break;
	case DAO_FLOAT   : self->cells->data.floats[i]    = DaoValue_GetFloat( value );  break;
	case DAO_DOUBLE  : self->cells->data.doubles[i]   = DaoValue_GetDouble( value ); break;
	case DAO_COMPLEX : self->cells->data.complexes[i] = DaoValue_GetComplex( value ); break;
	case DAO_STRING  : DaoValue_GetString( value, & self->cells->data.strings[i] ); break;
	}
}
Пример #2
0
DLong* DaoValue_GetLong( DaoValue *self, DLong *lng )
{
#ifdef DAO_WITH_LONGINT
	switch( self->type ){
	case DAO_INTEGER : DLong_FromInteger( lng, DaoValue_GetInteger( self ) ); break;
	case DAO_FLOAT   :
	case DAO_DOUBLE  : DLong_FromDouble( lng, DaoValue_GetDouble( self ) ); break;
	case DAO_COMPLEX : DLong_FromDouble( lng, self->xComplex.value.real ); break;
	case DAO_LONG    : DLong_Move( lng, self->xLong.value ); break;
	case DAO_STRING  : DLong_FromString( lng, self->xString.data ); break;
	default : break; /* TODO list array? */
	}
#endif
	return lng;
}
Пример #3
0
static daoint DaoxDF_MakeIndex( DaoxDataFrame *self, int dim, DaoValue *value, DaoProcess *p )
{
	daoint idx = -1;
	if( value->type >= DAO_INTEGER && value->type <= DAO_DOUBLE ){
		idx = DaoValue_GetInteger( value );
	}else if( value->type == DAO_STRING ){
		DString_ToMBS( value->xString.data );
		idx = DaoxDataFrame_GetIndex( self, dim, value->xString.data->mbs );
	}else if( value->type == DAO_NONE && self->dims[2] == 1 ){
		idx = 0;
	}
	if( idx < 0 || idx >= self->dims[dim] ){
		DaoProcess_RaiseException( p, DAO_ERROR_INDEX_OUTOFRANGE, "" );
		return -1;
	}
	return idx;
}
Пример #4
0
static void STD_Array( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *res, *index = (DaoValue*)(void*)&idint;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoArray *array = DaoProcess_PutArray( proc );
	DaoArray *first = NULL;
	DaoArray *sub = NULL;
	daoint i, j, k, entry, size = 1;

	/* if multi-dimensional array is disabled, DaoProcess_PutArray() will raise exception. */
#ifdef DAO_WITH_NUMARRAY
	for(i=0; i<N; i++){
		daoint d = p[i]->xInteger.value;
		if( d < 0 ){
			DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, NULL );
			break;
		}
		size *= d;
	}
	if( size == 0 ) return;
	if( sect == NULL ) return; // TODO exception
	if( DaoProcess_PushSectionFrame( proc ) == NULL ) return;
	entry = proc->topFrame->entry;
	DaoProcess_AcquireCV( proc );
	for(i=0; i<size; i++){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		res = proc->stackValues[0];
		if( i == 0 ){
			int D = N;
			DaoArray_SetDimCount( array, N + (res->type == DAO_ARRAY ? res->xArray.ndim : 0) );
			for(j=0; j<N; j++) array->dims[j] = p[j]->xInteger.value;
			if( res->type == DAO_ARRAY ){
				first = DaoArray_Copy( (DaoArray*) res );
				if( first->ndim == 2 && (first->dims[0] == 1 || first->dims[1] == 1) ){
					D += 1;
					array->dims[N] = first->dims[ first->dims[0] == 1 ];
				}else{
					D += first->ndim;
					memmove( array->dims + N, first->dims, first->ndim*sizeof(daoint) );
				}
			}
			DaoArray_ResizeArray( array, array->dims, D );
		}
		if( res->type == DAO_ARRAY ){
			sub = (DaoArray*) res;
			if( first == NULL || DaoArray_AlignShape( sub, NULL, first->dims, first->ndim ) ==0 ){
				DaoProcess_RaiseException( proc, DAO_ERROR, "inconsistent elements or subarrays" );
				break;
			}
			k = i * sub->size;
			for(j=0; j<sub->size; j++){
				switch( array->etype ){
				case DAO_INTEGER : array->data.i[k+j] = DaoArray_GetInteger( sub, j ); break;
				case DAO_FLOAT   : array->data.f[k+j] = DaoArray_GetFloat( sub, j ); break;
				case DAO_DOUBLE  : array->data.d[k+j] = DaoArray_GetDouble( sub, j ); break;
				case DAO_COMPLEX : array->data.c[k+j] = DaoArray_GetComplex( sub, j ); break;
				}
			}
		}else{
			switch( array->etype ){
			case DAO_INTEGER : array->data.i[i] = DaoValue_GetInteger( res ); break;
			case DAO_FLOAT   : array->data.f[i] = DaoValue_GetFloat( res ); break;
			case DAO_DOUBLE  : array->data.d[i] = DaoValue_GetDouble( res ); break;
			case DAO_COMPLEX : array->data.c[i] = DaoValue_GetComplex( res ); break;
			}
		}
	}
	DaoProcess_ReleaseCV( proc );
	DaoProcess_PopFrame( proc );
	if( first ) DaoArray_Delete( first );
#endif
}
Пример #5
0
/*
// Assumming the value "self" is compatible to the type "tp", if it is not null.
*/
DaoValue* DaoValue_SimpleCopyWithTypeX( DaoValue *self, DaoType *tp, DaoDataCache *cache )
{
	DaoEnum *e;
	daoint i, n;

	if( self == NULL ) return dao_none_value;
	if( (tp == NULL || tp->tid == self->type) && self->type < DAO_ENUM ){
		if( cache ){
			DaoValue *value = DaoDataCache_MakeValue( cache, self->type );
			switch( self->type ){
			case DAO_NONE : return self;
			case DAO_INTEGER : value->xInteger.value = self->xInteger.value; break;
			case DAO_FLOAT   : value->xFloat.value   = self->xFloat.value;   break;
			case DAO_DOUBLE  : value->xDouble.value  = self->xDouble.value;  break;
			case DAO_COMPLEX : value->xComplex.value = self->xComplex.value; break;
#ifdef DAO_WITH_LONGINT
			case DAO_LONG    : DLong_Move( value->xLong.value, self->xLong.value ); break;
#endif
			case DAO_STRING  : DString_Assign( value->xString.data, self->xString.data ); break;
			}
			return value;
		}else{
			switch( self->type ){
			case DAO_NONE : return self;
			case DAO_INTEGER : return (DaoValue*) DaoInteger_New( self->xInteger.value );
			case DAO_FLOAT   : return (DaoValue*) DaoFloat_New( self->xFloat.value );
			case DAO_DOUBLE  : return (DaoValue*) DaoDouble_New( self->xDouble.value );
			case DAO_COMPLEX : return (DaoValue*) DaoComplex_New( self->xComplex.value );
			case DAO_LONG    : return (DaoValue*) DaoLong_Copy( & self->xLong );
			case DAO_STRING  : return (DaoValue*) DaoString_Copy( & self->xString );
			}
		}
		return self; /* unreachable; */
	}else if( self->type == DAO_ENUM ){
		return (DaoValue*) DaoEnum_Copy( & self->xEnum, tp );
	}else if( tp && tp->tid >= DAO_INTEGER && tp->tid <= DAO_DOUBLE ){
		DaoValue *value = cache ? DaoDataCache_MakeValue( cache, tp->tid ) : NULL;
		switch( value == NULL ? tp->tid : 0 ){
		case DAO_INTEGER : value = (DaoValue*) DaoInteger_New(0); break;
		case DAO_FLOAT   : value = (DaoValue*) DaoFloat_New(0);   break;
		case DAO_DOUBLE  : value = (DaoValue*) DaoDouble_New(0);  break;
		}
		switch( tp->tid ){
		case DAO_INTEGER : value->xInteger.value = DaoValue_GetInteger( self ); break;
		case DAO_FLOAT   : value->xFloat.value   = DaoValue_GetFloat( self );   break;
		case DAO_DOUBLE  : value->xDouble.value  = DaoValue_GetDouble( self );  break;
		}
		return value;
	}
#ifdef DAO_WITH_NUMARRAY
	if( self->type == DAO_ARRAY && self->xArray.original ){
		DaoArray_Sliced( (DaoArray*)self );
		return self;
	}else
#endif
	if( self->type == DAO_CSTRUCT || self->type == DAO_CDATA ){
		FuncPtrSliced sliced = self->xCstruct.ctype->kernel->Sliced;
		if( sliced ) (*sliced)( self );
		return self;
	}
	if( self->xBase.trait & DAO_VALUE_NOCOPY ) return self;
	if( (self->xBase.trait & DAO_VALUE_CONST) == 0 ) return self;
	switch( self->type ){
	case DAO_LIST  : return (DaoValue*) DaoList_Copy( (DaoList*) self, tp );
	case DAO_MAP   : return (DaoValue*) DaoMap_Copy( (DaoMap*) self, tp );
	case DAO_TUPLE : return (DaoValue*) DaoTuple_Copy( (DaoTuple*) self, tp );
#ifdef DAO_WITH_NUMARRAY
	case DAO_ARRAY : return (DaoValue*) DaoArray_CopyX( (DaoArray*) self, tp );
#endif
	default : break;
	}
	return self;
}
Пример #6
0
static void MakeSlice( DaoProcess *proc, DaoValue *pid, daoint N, DVector *slice )
{
	daoint j, id, from, to, rc = 1;
	if( pid == NULL || pid->type == 0 ){
		SliceRange2( slice, N, 0, N );
		return;
	}
	switch( pid->type ){
	case DAO_INTEGER :
	case DAO_FLOAT :
	case DAO_DOUBLE :
		{
			id = DaoValue_GetInteger( pid );
			rc = SliceRange2( slice, N, id, 1 );
			break;
		}
	case DAO_STRING :
		{
			break;
		}
	case DAO_TUPLE :
		{
			DaoValue **data = pid->xTuple.items;
			DVector_Clear( slice );
			if( data[0]->type == DAO_INTEGER && data[1]->type == DAO_INTEGER ){
				from = data[0]->xInteger.value;
				to   = data[1]->xInteger.value;
				rc = SliceRange( slice, N, from, to );
			}else if( data[0]->type == DAO_NONE && data[1]->type == DAO_NONE ){
				rc = SliceRange2( slice, N, 0, N );
			}else if( data[0]->type <= DAO_DOUBLE && data[1]->type == DAO_NONE ){
				from = DaoValue_GetInteger( data[0] );
				rc = SliceRange( slice, N, from, -1 );
			}else if( data[0]->type == DAO_NONE && data[1]->type <= DAO_DOUBLE ){
				to = DaoValue_GetInteger( data[1] );
				rc = SliceRange( slice, N, 0, to );
			}else if( data[0]->type == DAO_STRING && data[1]->type == DAO_STRING ){
			}else if( data[0]->type == DAO_STRING && data[1]->type == DAO_NONE ){
			}else if( data[0]->type == DAO_NONE && data[1]->type == DAO_STRING ){
			}else{
				DaoProcess_RaiseException( proc, DAO_ERROR_INDEX, "need number" );
			}
			break;
		}
	case DAO_LIST :
		{
			DaoList *list = & pid->xList;
			DaoValue **v = list->items.items.pValue;
			DVector_Resize( slice, list->items.size + 2 );
			slice->data.daoints[0] = SLICE_ENUM;
			slice->data.daoints[1] = list->items.size;
			for( j=0; j<list->items.size; j++){
				if( v[j]->type < DAO_INTEGER || v[j]->type > DAO_DOUBLE )
					DaoProcess_RaiseException( proc, DAO_ERROR_INDEX, "need number" );
				id = DaoValue_GetInteger( v[j] );
				if( id <0 ) id += N;
				if( id <0 || id >= N ){
					rc = id = 0;
					break;
				}
				slice->data.daoints[j+2] = id;
			}
			break;
		}
	case DAO_ARRAY :
		{
			DaoArray *na = & pid->xArray;
			daoint *p;

			if( na->etype == DAO_COMPLEX ){
				DaoProcess_RaiseException( proc, DAO_ERROR_INDEX,
						"complex array can not be used as index" );
				break;
			}
			DVector_Resize( slice, na->size + 2 );
			slice->data.daoints[0] = SLICE_ENUM;
			slice->data.daoints[1] = na->size;
			p = slice->data.daoints + 2;
			for( j=0; j<na->size; j++){
				id = DaoArray_GetInteger( na, j );
				if( id <0 ) id += N;
				if( id <0 || id >= N ){
					rc = id = 0;
					break;
				}
				p[j] = id;
			}
			break;
		}
	default: break;
	}
	if( slice->size < 2 ) SliceRange2( slice, N, 0, N );
	if( rc == 0 ) DaoProcess_RaiseException( proc, DAO_ERROR_INDEX_OUTOFRANGE, "" );
}
Пример #7
0
/*
// C printf format: %[parameter][flags][width][.precision][length]type
//
// Dao writef format: %[flags][width][.precision]type[color]
//
// Where 'flags', 'width' and 'precision' will conform to the C format,
// but 'type' can only be:
//   d, i, o, u, x/X : for integer;
//   e/E, f/F, g/G : for float and double;
//   c/C : for character, C for local encoding;
//   s/S : for string, S for local encoding;
//   p : for any type, write address;
//   a : automatic, for any type, write in the default format;
// Namely the standard ones except 'n', and plus 'a'.
//
// Optional 'color' format will be in form of: [foreground:background], [foreground]
// or [:background]. The supported color name format will depend on the color printing
// handle. Mininum requirement is the support of the following 8 color names:
// black, white, red, green, blue, yellow, magenta, cyan.
*/
static void DaoIO_Writef0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N )
{
	DaoValue *value;
	DString *fmt2;
	DString *fgcolor = NULL;
	DString *bgcolor = NULL;
	DMap *cycmap = NULL;
	const char *convs = "asSpcCdiouxXfFeEgG";
	char F, *s, *end, *fg, *bg, *fmt, message[100];
	int i, k, id = 0;

	if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return;

	fmt2 = DString_New();
	for(i=0; i<N; i++){
		if( p[i]->type > DAO_ARRAY ){
			cycmap = DHash_New(0,0);
			break;
		}
	}

	s = p[0]->xString.value->chars;
	end = s + p[0]->xString.value->size;
	for(; s<end; s++){
		if( *s != '%' ){
			DaoStream_WriteChar( self, *s );
			continue;
		}

		fmt = s;
		s += 1;
		if( *s =='%' || *s == '[' ){
			DaoStream_WriteChar( self, *s );
			continue;
		}

		if( ++id >= N || p[id] == NULL ) goto NullParameter;
		value = p[id];

		/* flags: */
		while( *s == '+' || *s == '-' || *s == '#' || *s == '0' || *s == ' ' ) s += 1;
		while( isdigit( *s ) ) s += 1; /* width; */
		if( *s == '.' ){ /* precision: */
			s += 1;
			while( isdigit( *s ) ) s += 1;
		}
		DString_SetBytes( fmt2, fmt, s - fmt + 1 );
		if( strchr( convs, *s ) == NULL ){
			DaoProcess_RaiseWarning( proc, NULL, "invalid format conversion" );
			continue;
		}
		F = *s;
		s += 1;
		fg = bg = NULL;
		if( *s == '[' ){
			s += 1;
			fmt = s;
			while( isalnum( *s ) ) s += 1;
			if( fgcolor == NULL ) fgcolor = DString_New();
			DString_SetBytes( fgcolor, fmt, s - fmt );
			if( fgcolor->size ) fg = fgcolor->chars;
			if( *s == ':' ){
				s += 1;
				fmt = s;
				while( isalnum( *s ) ) s += 1;
				if( bgcolor == NULL ) bgcolor = DString_New();
				DString_SetBytes( bgcolor, fmt, s - fmt );
				if( bgcolor->size ) bg = bgcolor->chars;
			}
			if( *s != ']' ) goto WrongColor;
		}else{
			s -= 1;
		}
		if( fg || bg ){
			if( DaoStream_SetColor( self, fg, bg ) == 0 ) goto WrongColor;
		}
		self->format = fmt2->chars;
		if( F == 'c' || F == 'C' ){
			if( value->type != DAO_INTEGER ) goto WrongParameter;
			DString_Reset( fmt2, 0 );
			DString_AppendWChar( fmt2, value->xInteger.value );
			self->format = "%s";
			if( F == 'C' ) DString_ToLocal( fmt2 );
			DaoStream_WriteString( self, fmt2 );
		}else if( F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){
			if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter;
			DString_InsertChars( fmt2, "ll", fmt2->size-1, 0, 2 );
			self->format = fmt2->chars;
			DaoStream_WriteInt( self, DaoValue_GetInteger( value ) );
		}else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){
			if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter;
			DaoStream_WriteFloat( self, DaoValue_GetFloat( value ) );
		}else if( F == 's' && value->type == DAO_STRING ){
			DaoStream_WriteString( self, value->xString.value );
		}else if( F == 'S' && value->type == DAO_STRING ){
			DaoStream_WriteLocalString( self, value->xString.value );
		}else if( F == 'p' ){
			DaoStream_WritePointer( self, value );
		}else if( F == 'a' ){
			self->format = NULL;
			if( value->type > DAO_ARRAY ) DMap_Reset( cycmap );
			DaoValue_Print( value, self, cycmap, proc );
		}else{
			goto WrongParameter;
		}
		self->format = NULL;
		if( fg || bg ) DaoStream_SetColor( self, NULL, NULL );
		continue;
NullParameter:
		sprintf( message, "%i-th parameter is null!", id );
		DaoProcess_RaiseWarning( proc, NULL, message );
		continue;
WrongColor:
		sprintf( message, "%i-th parameter has wrong color format!", id );
		DaoProcess_RaiseWarning( proc, NULL, message );
		continue;
WrongParameter:
		self->format = NULL;
		if( fg || bg ) DaoStream_SetColor( self, NULL, NULL );
		sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", id, fmt2->chars );
		DaoProcess_RaiseWarning( proc, NULL, message );
	}
	if( cycmap ) DMap_Delete( cycmap );
	if( fgcolor ) DString_Delete( fgcolor );
	if( bgcolor ) DString_Delete( bgcolor );
	DString_Delete( fmt2 );
}
Пример #8
0
/*
// Assumming the value "self" is compatible to the type "tp", if it is not null.
*/
DaoValue* DaoValue_SimpleCopyWithTypeX( DaoValue *self, DaoType *tp, DaoType *cst )
{
	if( self == NULL ) return dao_none_value;
	if( self->type < DAO_ENUM && (tp == NULL || tp->tid == self->type) ){
		/*
		// The following optimization is safe theoretically.
		// But it is not practically safe for DaoProcess_PutChars() etc.,
		// which often uses shallow wraps of "const char*" as the source value,
		// and expects it to be copied at the destination as a primitive value.
		*/
		/* if( cst && cst->invar ) return self; */
		switch( self->type ){
		case DAO_NONE : return self;
		case DAO_BOOLEAN : return (DaoValue*) DaoBoolean_New( self->xBoolean.value );
		case DAO_INTEGER : return (DaoValue*) DaoInteger_New( self->xInteger.value );
		case DAO_FLOAT   : return (DaoValue*) DaoFloat_New( self->xFloat.value );
		case DAO_COMPLEX : return (DaoValue*) DaoComplex_New( self->xComplex.value );
		case DAO_STRING  : return (DaoValue*) DaoString_Copy( & self->xString );
		}
		return self; /* unreachable; */
	}else if( tp && tp->tid >= DAO_BOOLEAN && tp->tid <= DAO_FLOAT ){
		DaoValue *va = NULL;
		switch( tp->tid ){
		case DAO_BOOLEAN : va = (DaoValue*) DaoBoolean_New( DaoValue_GetInteger(self) ); break;
		case DAO_INTEGER : va = (DaoValue*) DaoInteger_New( DaoValue_GetInteger(self) ); break;
		case DAO_FLOAT   : va = (DaoValue*) DaoFloat_New( DaoValue_GetFloat(self) );   break;
		}
		return va;
	}else if( self->type == DAO_ENUM ){
		switch( tp ? tp->tid : 0 ){
		case DAO_ENUM :
			if( tp->subtid == DAO_ENUM_ANY ) tp = NULL;
			return (DaoValue*) DaoEnum_Copy( & self->xEnum, tp );
		case DAO_BOOLEAN : return (DaoValue*) DaoBoolean_New( self->xEnum.value );
		case DAO_INTEGER : return (DaoValue*) DaoInteger_New( self->xEnum.value );
		case DAO_FLOAT   : return (DaoValue*) DaoFloat_New( self->xEnum.value );
		}
		return (DaoValue*) DaoEnum_Copy( & self->xEnum, NULL );
	}else if( tp && tp->tid == DAO_ENUM ){
		switch( self->type ){
		case DAO_BOOLEAN :
		case DAO_INTEGER : return (DaoValue*) DaoEnum_New( tp, self->xInteger.value );
		case DAO_FLOAT   : return (DaoValue*) DaoEnum_New( tp, self->xFloat.value );
		}
	}else if( self->type == DAO_CINVALUE ){
		return (DaoValue*) DaoCinValue_Copy( (DaoCinValue*) self );
	}
	if( tp != NULL ){
		assert( tp->tid == 0 || tp->tid > DAO_ENUM );
		assert( self->type == 0 || self->type > DAO_ENUM );
	}

#ifdef DAO_WITH_NUMARRAY
	if( self->type == DAO_ARRAY && self->xArray.original ){
		DaoArray_Sliced( (DaoArray*)self );
		return self;
	}else
#endif
	if( self->type == DAO_CSTRUCT || self->type == DAO_CDATA ){
		if( self->xCstruct.ctype->core->Slice ) self->xCstruct.ctype->core->Slice( self );
		return self;
	}
	if( tp == NULL ){
		switch( self->type ){
		case DAO_LIST  : if( self->xList.ctype->empty ) tp = self->xList.ctype; break;
		case DAO_MAP   : if( self->xMap.ctype->empty  ) tp = self->xMap.ctype; break;
		default : break;
		}
	}
	if( self->xBase.trait & DAO_VALUE_NOCOPY ) return self;
	if( (self->xBase.trait & DAO_VALUE_CONST) == 0 ) return self;
	if( cst != NULL && cst->invar != 0 ) return self;
	if( tp ) tp = DaoType_GetBaseType( tp );
	return DaoValue_CopyContainer( self, tp );
}