Beispiel #1
0
DaoClass* DaoClass_New()
{
	DaoClass *self = (DaoClass*) dao_calloc( 1, sizeof(DaoClass) );
	DaoValue_Init( self, DAO_CLASS );
	self->trait |= DAO_VALUE_DELAYGC;
	self->className = DString_New(1);

	self->lookupTable = DHash_New(D_STRING,0);
	self->ovldRoutMap = DHash_New(D_STRING,0);
	self->abstypes    = DMap_New(D_STRING,D_VALUE);
	self->constants   = DArray_New(D_VALUE);
	self->variables   = DArray_New(D_VALUE);
	self->instvars    = DArray_New(D_VALUE);
	self->objDataName = DArray_New(D_STRING);
	self->cstDataName = DArray_New(D_STRING);
	self->glbDataName = DArray_New(D_STRING);
	self->parent = NULL;
	self->mixinBases = DArray_New(0);  /* refcount handled in ::allBases; */
	self->allBases   = DArray_New(D_VALUE);
	self->mixins  = DArray_New(0);
	self->ranges  = DVector_New(sizeof(ushort_t));
	self->offsets = DVector_New(sizeof(ushort_t));
	self->references  = DArray_New(D_VALUE);
	self->inter = NULL;

	self->cstMixinStart = self->cstMixinEnd = self->cstMixinEnd2 = 0;
	self->glbMixinStart = self->glbMixinEnd = self->glbMixinEnd2 = 0;
	self->objMixinStart = self->objMixinEnd = self->objMixinEnd2 = 0;
	self->cstParentStart = self->cstParentEnd = 0;
	self->glbParentStart = self->glbParentEnd = 0;
	return self;
}
Beispiel #2
0
DVector* DVector_Copy( DVector *self )
{
	DVector *copy = DVector_New( self->stride );
	copy->type = self->type;
	DVector_Resize( copy, self->size );
	memcpy( copy->data.base, self->data.base, self->size * self->stride );
	return copy;
}
Beispiel #3
0
DaoxDataColumn* DaoxDataColumn_New( DaoType *type )
{
	DaoxDataColumn *self = (DaoxDataColumn*) dao_calloc( 1, sizeof(DaoxDataColumn) );
	if( type == NULL ) type = dao_type_any;
	GC_IncRC( type );
	self->type = type;
	self->cells = DVector_New( DaoType_GetDataSize( type ) );
	self->cells->type = DaoType_GetDataType( type );
	return self;
}
Beispiel #4
0
static void DaoxDataFrame_MakeFullSlice( DaoxDataFrame *self, DArray *slices )
{
	DVector *tmp = DVector_New( sizeof(daoint) );
	daoint i, D = 3;

	/* slices: DArray<DVector<int> > */
	DArray_Clear( slices );
	DVector_Resize( tmp, 3 );
	tmp->data.daoints[0] = SLICE_RANGE;
	tmp->data.daoints[2] = 0;
	for(i=0; i<D; ++i){
		tmp->data.daoints[1] = self->dims[i];
		DArray_Append( slices, tmp );
	}
	DVector_Delete( tmp );
}
Beispiel #5
0
int DaoLexer_Tokenize( DaoLexer *self, const char *src, int flags )
{
	DString *source = DString_New(1);
	DVector *lexenvs = DVector_New( sizeof(int) );
	DaoToken *token = DaoToken_New();
	DString *literal = & token->string;
	char ch, *ss, hex[11] = "0x00000000";
	int replace = flags & DAO_LEX_ESCAPE;
	int comment = flags & DAO_LEX_COMMENT;
	int space = flags & DAO_LEX_SPACE;
	int srcSize = (int)strlen( src );
	int old=0, state = TOK_START;
	int lexenv = LEX_ENV_NORMAL;
	int unicoded = 0;
	int line = 1;
	int cpos = 0;
	int ret = 1;
	int it = 0;
	int i, m = 4;

	DString_SetSharing( literal, 0 );
	for(it=0; it<srcSize; it++){
		if( (signed char) src[it] < 0 ){
			unicoded = 1;
			break;
		}
	}
	if( unicoded && daoConfig.mbs == 0 ){
		DString *wcs = DString_New(0);
		/* http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html */
		wchar_t quotes[] = {
			0x27 , 0x27 , 0x27, /* single q.m. */
			0x22 , 0x22 , 0x22, /* double q.m. */
			0x27 + 0xfee0 , 0x27 + 0xfee0 , 0x27 , /* single q.m. unicode */
			0x22 + 0xfee0 , 0x22 + 0xfee0 , 0x22 , /* double q.m. unicode */
			0x60 , 0x27 , 0x27, /* grave accent */
			0x2018 , 0x2019 , 0x27 , /* left/right single q.m. */
			0x201C , 0x201D , 0x22   /* left/right double q.m. */
		};
		wchar_t sl = L'\\' + 0xfee0;
		wchar_t stop;
		int i, N = 21;
		it = 0;
		DString_SetMBS( wcs, src );
		while( it < wcs->size ){ // TODO: handle verbatim string!
			for( i=0; i<N; i+=3 ){
				if( wcs->wcs[it] == quotes[i] ){
					stop = quotes[i+1];
					wcs->wcs[it] = quotes[i+2];
					it ++;
					while( it < wcs->size && wcs->wcs[it] != stop ){
						if( wcs->wcs[it] == sl || wcs->wcs[it] == L'\\' ){
							it ++;
							continue;
						}
						it ++;
					}
					if( it < wcs->size ) wcs->wcs[it] = quotes[i+2];
					break;
				}
			}
			if( it >= wcs->size ) break;
			if( wcs->wcs[it] == 0x3000 ){
				wcs->wcs[it] = 32; /* blank space */
			}else if( wcs->wcs[it] > 0xff00 && wcs->wcs[it] < 0xff5f ){
				wcs->wcs[it] -= 0xfee0; /* DBC to SBC */
			}
			it ++;
		}
		if( wcs->size ){
			DString_SetWCS( source, wcs->wcs );
			src = source->mbs;
			srcSize = source->size;
		}
		DString_Delete( wcs );
	}
	DaoLexer_Reset( self );

	DVector_PushInt( lexenvs, LEX_ENV_NORMAL );
	it = 0;
	token->cpos = 0;
	while( it < srcSize ){
#if 0
		printf( "tok: %i %i  %i  %c    %s\n", srcSize, it, ch, ch, literal->mbs );
#endif
		token->type = state;
		token->name = 0;
		token->line = line;
		ch = src[it];
		cpos += ch == '\t' ? daoConfig.tabspace : 1;
		if( ch == '\n' ) cpos = 0, line ++;
		if( literal->size == 0 ) token->cpos = cpos;
		if( state == TOK_STRING_MBS || state == TOK_STRING_WCS ){
			if( ch == '\\' ){
				it ++;
				if( replace == 0 ){
					DString_AppendChar( literal, ch );
					if( it < srcSize ){
						if( src[it] == '\n' ) cpos = 0, line ++;
						DString_AppendChar( literal, src[it] );
					}
					it ++;
					continue;
				}
				if( it >= srcSize ){
					ret = 0;
					printf( "error: incomplete string at line %i.\n", line );
					break;
				}
				if( src[it] == '\n' ) cpos = 0, line ++;
				switch( src[it] ){
				case '0' : case '1' : case '2' : case '3' :
				case '4' : case '5' : case '6' : case '7' : /* \ooo */
					i = 2;
					while( i < 5 && it < srcSize && src[it] >= '0' && src[it] < '8' ){
						hex[i] = src[it++];
						hex[++i] = 0;
					}
					DString_AppendChar( literal, (char) strtol( hex+2, NULL, 8 ) );
					it --;
					break;
				case '8' : case '9' :
					DString_AppendChar( literal, (char) (src[it] - '0') );
					break;
				case 'x' :
				case 'u' :
				case 'U' :
					i = 2;
					switch( src[it] ){
					case 'x' : m = 4;  break; /* \xhh: max 2 hex digit; */
					case 'u' : m = 6;  break; /* \uhhhh: max 4 hex digit; */
					case 'U' : m = 10; break; /* \Uhhhhhhhh: max 8 hex digit; */
					}
					while( i < m && (it+1) < srcSize && isxdigit( src[it+1] ) ){
						hex[i] = src[++it];
						hex[++i] = 0;
					}
					DString_AppendWChar( literal, (wchar_t) strtol( hex, NULL, 0 ) );
					break;
				case 't' : DString_AppendChar( literal, '\t' ); break;
				case 'n' : DString_AppendChar( literal, '\n' ); break;
				case 'r' : DString_AppendChar( literal, '\r' ); break;
				case '\'' : DString_AppendChar( literal, '\'' ); break;
				case '\"' : DString_AppendChar( literal, '\"' ); break;
				default : DString_AppendChar( literal, src[it] ); break;
				}
			}else if( ch == '\'' && state == TOK_STRING_MBS ){
				DString_AppendChar( literal, ch );
				state = TOK_RESTART;
				token->type = token->name = DTOK_MBS;
				DaoLexer_AppendToken( self, token );
				DString_Clear( literal );
			}else if( ch == '\"' && state == TOK_STRING_WCS ){
				DString_AppendChar( literal, ch );
				state = TOK_RESTART;
				token->type = token->name = DTOK_WCS;
				DaoLexer_AppendToken( self, token );
				DString_Clear( literal );
			}else{
				DString_AppendChar( literal, ch );
			}
		}else if( ch == ']' && state == TOK_VERBATIM ){
			int len = srcSize - it - 1;
			DString_AppendChar( literal, ']' );
			token->type = token->name = DTOK_VBT_OPEN;
			if( (ss = strstr( src + it + 1, literal->mbs )) != NULL ){
				len = (ss - src) - it - 1 + literal->size;
				token->type = token->name = DTOK_VERBATIM;
			}
			for(i=0; i<len; i++) if( src[it+1+i] == '\n' ) line += 1;
			DString_AppendDataMBS( literal, src + it + 1, len );
			state = TOK_RESTART;
			DaoLexer_AppendToken( self, token );
			DString_Clear( literal );
			it += len;
		}else if( lexenv == LEX_ENV_NORMAL ){
			old = state;
			if( ch >=0 ){
				state = daoLexTable[ state ][ (int)ch ];
			}else if( state <= TOK_START ){
				state = TOK_RESTART;
			}else if( state != TOK_IDENTIFIER && state != TOK_STRING_MBS
					&& state != TOK_STRING_WCS
					&& state != TOK_COMT_LINE && state != TOK_COMT_OPEN ){
				state = TOK_RESTART;
			}
			if( state >= TOK_END ){
				DString_AppendChar( literal, ch );
				token->type = token->name = daoTokenMap[ state ];
				if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL )
					token->type = DTOK_IDENTIFIER;
				if( space || comment || token->type != DTOK_COMMENT ){
					if( isspace( token->string.mbs[0] ) )
						token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ];
					DaoLexer_AppendToken( self, token );
				}
				/* may be a token before the line break; */
				DString_Clear( literal );
				state = TOK_START;
			}else if( state == TOK_RESTART ){
				if( literal->size ){
					if( old == TOK_IDENTIFIER ){
						token->name = dao_key_hash( literal->mbs, literal->size );
						token->type = DTOK_IDENTIFIER;
						if( token->name == 0 ) token->name = DTOK_IDENTIFIER;
						DaoLexer_AppendToken( self, token );
					}else if( old > TOK_RESTART && old != TOK_END ){
						token->type = token->name = daoTokenMap[ old ];
						if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL )
							token->type = DTOK_IDENTIFIER;
						DaoLexer_AppendToken( self, token );
					}else if( space ){
						if( isspace( token->string.mbs[0] ) )
							token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ];
						DaoLexer_AppendToken( self, token );
					}
					DString_Clear( literal );
					token->cpos = cpos;
				}
				DString_AppendChar( literal, ch );
				if( ch >=0 )
					state = daoLexTable[ TOK_START ][ (int)ch ];
				else
					state = TOK_IDENTIFIER;

			}else if( state == TOK_COMT_OPEN ){
				DString_AppendChar( literal, ch );
				lexenv = LEX_ENV_COMMENT;
				DVector_PushInt( lexenvs, LEX_ENV_COMMENT );
			}else{
				DString_AppendChar( literal, ch );
			}
		}else if( lexenv == LEX_ENV_COMMENT ){
			DString_AppendChar( literal, ch );
			if( ch == '#' ){
				state = TOK_OP_SHARP;
			}else if( ch == '{' && state == TOK_OP_SHARP ){
				state = TOK_COMT_OPEN;
				DVector_PushInt( lexenvs, LEX_ENV_COMMENT );
			}else if( ch == '}' && state == TOK_OP_SHARP ){
				state = TOK_COMT_CLOSE;
				DVector_Pop( lexenvs );
				lexenv = lexenvs->data.ints[lexenvs->size-1];
				if( lexenv != LEX_ENV_COMMENT ){
					token->type = token->name = DTOK_COMMENT;
					if( comment ) DaoLexer_AppendToken( self, token );
					DString_Clear( literal );
					state = TOK_RESTART;
				}
			}else{
				state = TOK_START;
			}
		}
		it ++;
	}
	if( literal->size ){
		token->type = token->name = daoTokenMap[ state ];
		if( lexenv == LEX_ENV_COMMENT ) token->type = token->name = DTOK_CMT_OPEN;
		switch( state ){
		case TOK_STRING_MBS : token->type = token->name = DTOK_MBS_OPEN; break;
		case TOK_STRING_WCS : token->type = token->name = DTOK_WCS_OPEN; break;
		}
		if( token->type == DTOK_IDENTIFIER ){
			token->name = dao_key_hash( literal->mbs, literal->size );
			if( token->name == 0 ) token->name = DTOK_IDENTIFIER;
		}else if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ){
			token->type = DTOK_IDENTIFIER;
		}
		if( token->type || space ){
			if( isspace( token->string.mbs[0] ) )
				token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ];
			DaoLexer_AppendToken( self, token );
		}
	}
	DaoToken_Delete( token );
	DVector_Delete( lexenvs );
	DString_Delete( source );
#if 0
	for(i=0; i<self->tokens->size; i++){
		DaoToken *tk = self->tokens->items.pToken[i];
		printf( "%4i: %4i %4i , %4i,  %s\n", i, tk->type, tk->name, tk->cpos, tk->string.mbs );
	}
#endif
	return ret ? line : 0;
}
Beispiel #6
0
static void DaoxDataFrame_SliceFrom( DaoxDataFrame *self, DaoxDataFrame *orig, DArray *slices )
{
	DVector *rows = DVector_New( sizeof(daoint) );
	DVector *cols = DVector_New( sizeof(daoint) );
	DVector *deps = DVector_New( sizeof(daoint) );
	daoint N = slices->items.pVector[0]->data.daoints[1];
	daoint M = slices->items.pVector[1]->data.daoints[1];
	daoint K = slices->items.pVector[2]->data.daoints[1];
	daoint d, i, j, k;
	daoint *maps[3];
	DaoxDataFrame_Reset( self );
	DVector_Resize( rows, orig->dims[0] );
	DVector_Resize( cols, orig->dims[1] );
	DVector_Resize( deps, orig->dims[2] );
	for(i=0; i<rows->size; ++i) rows->data.daoints[i] = -1;
	for(i=0; i<cols->size; ++i) cols->data.daoints[i] = -1;
	for(i=0; i<deps->size; ++i) deps->data.daoints[i] = -1;
	maps[0] = rows->data.daoints;
	maps[1] = cols->data.daoints;
	maps[2] = deps->data.daoints;
	for(j=0; j<M; ++j){
		daoint jj = DaoSlice_GetIndex( slices->items.pVector[1], j );
		DaoxDataColumn *source = (DaoxDataColumn*) orig->columns->items.pVoid[jj];
		DaoxDataColumn *target = DaoxDataFrame_MakeColumn( self, source->type );
		int datatype = DaoType_GetDataType( target->type );

		cols->data.daoints[jj] = j;
		DArray_Append( self->columns, target );
		DaoxDataColumn_Reset( target, N*K );
		for(i=0; i<N; ++i){
			daoint ii = DaoSlice_GetIndex( slices->items.pVector[0], i );
			rows->data.daoints[ii] = i;
			for(k=0; k<K; ++k){
				daoint kk = DaoSlice_GetIndex( slices->items.pVector[2], k );
				daoint id2 = kk * orig->dims[0] + ii;
				daoint id3 = k * N + i;
				void *src = DVector_Get( source->cells, id2 );
				void *des = DVector_Get( target->cells, id3 );
				deps->data.daoints[kk] = k;
				if( datatype == 0 ){ /* DaoValue */
					DaoValue *value = source->cells->data.values[id2];
					GC_IncRC( value );
				}
				memcpy( des, src, source->cells->stride );
			}
		}
	}
	self->dims[0] = N;
	self->dims[1] = M;
	self->dims[2] = K;
	for(d=0; d<3; ++d){
		DArray *labels = orig->labels[d];
		for(i=0; i<labels->size; ++i){
			DMap *labmap = labels->items.pMap[i];
			DNode *it;
			DaoxDataFrame_AddLabelGroup( self, d );
			for(it=DMap_First(labmap); it; it=DMap_Next(labmap,it)){
				daoint id = maps[d][it->value.pInt];
				if( id < 0 ) continue;
				DaoxDataFrame_AddLabel( self, d, it->key.pString->mbs, id );
			}
		}
	}
	DVector_Delete( rows );
	DVector_Delete( cols );
	DVector_Delete( deps );
}
Beispiel #7
0
static void FRAME_PRINT( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoxDataFrame *self = (DaoxDataFrame*) p[0];
	DaoxDataFrame *original = self->original;
	DaoStream *stream = proc->stdioStream;
	DaoStream *sstream = DaoStream_New();
	DaoValue valueBuffer, *nulls[3] = {NULL,NULL,NULL};
	DVector *rlabwidth = DVector_New( sizeof(int) );
	DVector *clabwidth = DVector_New( sizeof(int) );
	DVector *decimals = DVector_New( sizeof(int) );
	DVector *scifmts = DVector_New( sizeof(int) );
	DVector *aligns = DVector_New( sizeof(int) );
	DString *label = DString_New(1);
	daoint d, g, i, j, k, s, N, M, K, J = 1;
	int idwidth, maxwidth = 16, maxdec = 3;
	char idfmt[16];
	char fmt[16];
	char buf[512];

	sstream->attribs |= DAO_IO_STRING;
	memset( &valueBuffer, 0, sizeof(DaoValue) );
	if( stream == NULL ) stream = proc->vmSpace->stdioStream;
	if( self->original == NULL ){
		DaoxDataFrame_PrepareSlices( self );
		DaoDataFrame_MakeSlice( self, proc, nulls, 3, self->slices );
		original = self;
	}
	N = self->slices->items.pVector[0]->data.daoints[1];
	M = self->slices->items.pVector[1]->data.daoints[1];
	K = self->slices->items.pVector[2]->data.daoints[1];
	DString_Reset( label, 10 + 4*sizeof(void*) + log10(1+N+M+K) );
	sprintf( label->mbs, "\nDataFrame[%p]", self );
	DaoStream_WriteMBS( stream, label->mbs );
	if( original != self ){
		sprintf( label->mbs, " (Slices from DataFrame[%p])", original );
		DaoStream_WriteMBS( stream, label->mbs );
	}
	sprintf( label->mbs, "\nDimensions: Rows=%" DAO_INT_FORMAT ";", N );
	DaoStream_WriteMBS( stream, label->mbs );
	sprintf( label->mbs, " Cols=%" DAO_INT_FORMAT ";", M );
	DaoStream_WriteMBS( stream, label->mbs );
	sprintf( label->mbs, " Deps=%" DAO_INT_FORMAT ";\n", K );
	DaoStream_WriteMBS( stream, label->mbs );

	idwidth = 1 + (int)log10(N+1);
	for(i=0; i<N; ++i){
		daoint ii = DaoSlice_GetIndex( self->slices->items.pVector[0], i );
		int width = 1 + (int)log10(ii+1);
		if( width > idwidth ) idwidth = width;
	}
	sprintf( idfmt, "%%%i%s:", idwidth, DAO_INT_FORMAT );

	if( M == 1 ){
		maxwidth = 64;
		maxdec = 24;
	}else if( M == 2 ){
		maxwidth = 40;
		maxdec = 12;
	}else if( M <= 4 ){
		maxwidth = 24;
		maxdec = 6;
	}

	for(g=0; g<original->labels[DAOX_DF_ROW]->size; ++g){
		int width = 0;
		for(i=0; i<N; ++i){
			daoint ii = DaoSlice_GetIndex( self->slices->items.pVector[0], i );
			DaoxDataFrame_GetLabel( original, DAOX_DF_ROW, g, ii, label );
			if( label->size > width ) width = label->size;
			if( width > maxwidth ) break;
		}
		if( width > maxwidth ) width = maxwidth;
		DVector_PushInt( rlabwidth, width );
	}
	for(j=0; j<M; ++j){
		int w, datatype, max = 0, min = 0, dec = 0;
		daoint width, jj = DaoSlice_GetIndex( self->slices->items.pVector[2], j );
		DaoxDataColumn *col = (DaoxDataColumn*) original->columns->items.pVoid[jj];
		DVector *cells = col->cells;

		datatype = DaoType_GetDataType( col->type );
		width = DaoxDataColumn_GetPrintWidth( col, 16 );
		for(i=0; i<N && i<1000; ++i){
			daoint v, ii = DaoSlice_GetIndex( self->slices->items.pVector[0], i );
			complex16 com;
			switch( datatype ){
			case DAO_INTEGER :
				v = cells->data.daoints[ii];
				w = log10( fabs(v) + 1E-32 ) + (v < 0);
				if( w > max ) max = w;
				break;
			case DAO_FLOAT   :
				CheckPrintWidth( cells->data.floats[ii], & max, & min, & dec );
				break;
			case DAO_DOUBLE  :
				CheckPrintWidth( cells->data.doubles[ii], & max, & min, & dec );
				break;
			case DAO_COMPLEX :
				com = cells->data.complexes[ii];
				CheckPrintWidth( com.real, & max, & min, & dec );
				CheckPrintWidth( com.imag, & max, & min, & dec );
				break;
			case DAO_STRING :
				if( cells->data.strings[i].size > max ) max = cells->data.strings[i].size;
				break;
			default :
				break;
			}
		}
		if( dec > maxdec ) dec = maxdec;
		if( col->type->tid == DAO_COMPLEX ){
			max *= 2;
			min *= 2;
		}
		if( datatype == 0 ){
			width = maxwidth;
			DVector_PushInt( aligns, 1 );
			DVector_PushInt( scifmts, 0 );
			DVector_PushInt( decimals, 0 );
		}else if( datatype == DAO_STRING ){
			width = max;
			DVector_PushInt( aligns, 1 );
			DVector_PushInt( scifmts, 0 );
			DVector_PushInt( decimals, 0 );
		}else if( max >= maxwidth || min <= -dec ){
			width = 16;
			DVector_PushInt( aligns, 0 );
			DVector_PushInt( scifmts, 1 );
			DVector_PushInt( decimals, dec );
		}else{
			width = max + dec + 1;
			if( col->type->tid == DAO_COMPLEX ) width += dec + 6;
			DVector_PushInt( aligns, 0 );
			DVector_PushInt( scifmts, 0 );
			DVector_PushInt( decimals, dec );
		}

		for(g=0; g<original->labels[DAOX_DF_COL]->size; ++g){
			DaoxDataFrame_GetLabel( original, DAOX_DF_COL, g, jj, label );
			if( label->size > width ) width = label->size;
			if( width > maxwidth ) break;
		}
		if( width > maxwidth ) width = maxwidth;
		DVector_PushInt( clabwidth, width );
	}

	for(k=0; k<K; ++k){
		daoint kk = DaoSlice_GetIndex( self->slices->items.pVector[2], k );
		DaoStream_WriteMBS( stream, "Depth: " );
		DaoStream_WriteInt( stream, kk );
		DaoStream_WriteMBS( stream, ";" );
		if( original->labels[DAOX_DF_DEP]->size ) DaoStream_WriteMBS( stream, "\nLabels:" );
		for(g=0; g<original->labels[DAOX_DF_DEP]->size; ++g){
			DaoxDataFrame_GetLabel( original, DAOX_DF_DEP, g, kk, label );
			DaoStream_WriteMBS( stream, " " );
			DaoStream_WriteString( stream, label );
			DaoStream_WriteMBS( stream, ";" );
		}
		DaoStream_WriteMBS( stream, "\n" );
		for(j=0; j<M; j=J){
			int width2, width = idwidth+1;
			for(i=0; i<rlabwidth->size; ++i) width += rlabwidth->data.ints[i] + 1;
			width += 1;

			J = j;
			width2 = width;
			for(J=j; J<M; ++J){
				daoint jj = DaoSlice_GetIndex( self->slices->items.pVector[1], J );
				width2 += clabwidth->data.ints[J] + 2;
				if( width2 > 80 ){
					width2 -= clabwidth->data.ints[J] + 2;
					break;
				}
			}
			if( J == j ) J += 1;

			sprintf( buf, "from %" DAO_INT_FORMAT " to %" DAO_INT_FORMAT ":\n", j, J-1 );
			DaoStream_WriteMBS( stream, j == 0 ? "| Columns " : "> Columns " );
			DaoStream_WriteMBS( stream, buf );
			for(g=0; g<original->labels[DAOX_DF_COL]->size; ++g){
				sprintf( fmt, "%%-%is", width );
				sprintf( buf, fmt, j == 0 ? "|" : ">" );
				DaoStream_WriteMBS( stream, buf );
				for(s=j; s<J; ++s){
					daoint jj = DaoSlice_GetIndex( self->slices->items.pVector[1], s );
					int width = clabwidth->data.ints[s];
					int align = aligns->data.ints[s];
					if( align ){
						sprintf( fmt, "%%-%is", width );
					}else{
						sprintf( fmt, "%%%is", width );
					}
					DaoxDataFrame_GetLabel( original, DAOX_DF_COL, g, jj, label );
					if( label->size > width ) DString_Reset( label, width );
					snprintf( buf, width+1, fmt, label->mbs );
					DaoStream_WriteMBS( stream, "  " );
					DaoStream_WriteMBS( stream, buf );
				}
				DaoStream_WriteMBS( stream, "\n" );
			}
			printf( j == 0 ? "|" : ">" );
			while( --width2 ) printf( "-" );
			DaoStream_WriteMBS( stream, J < M ? ">" : "|" );
			DaoStream_WriteMBS( stream, "\n" );
			for(i=0; i<N; ++i){
				daoint ii = DaoSlice_GetIndex( self->slices->items.pVector[0], i );
				sprintf( buf, idfmt, ii );
				DaoStream_WriteMBS( stream, buf );
				for(g=0; g<original->labels[DAOX_DF_ROW]->size; ++g){
					int width = rlabwidth->data.ints[g];
					DaoxDataFrame_GetLabel( original, DAOX_DF_ROW, g, ii, label );
					if( label->size > width ) DString_Reset( label, width );
					if( g ) DaoStream_WriteMBS( stream, "," );
					sprintf( fmt, "%%-%is", width );
					snprintf( buf, width+1, fmt, label->mbs );
					DaoStream_WriteMBS( stream, buf );
				}
				DaoStream_WriteMBS( stream, ": " );
				for(s=j; s<J; ++s){
					int scifmt = scifmts->data.ints[s];
					int dec = decimals->data.ints[s];
					int width = clabwidth->data.ints[s];
					daoint jj = DaoSlice_GetIndex( self->slices->items.pVector[2], s );
					DaoxDataColumn *col = (DaoxDataColumn*) original->columns->items.pVoid[jj];
					DaoValue *value = DaoxDataColumn_GetCell( col, i, & valueBuffer );

					DaoStream_WriteMBS( stream, "  " );
					if( value == NULL ){
						sprintf( fmt, "%%-%is", width );
						snprintf( buf, width+1, fmt, " " );
					}else if( value->type == DAO_INTEGER ){
						sprintf( fmt, "%%%i%s", width, DAO_INT_FORMAT );
						snprintf( buf, width+1, fmt, value->xInteger.value );
					}else if( value->type == DAO_FLOAT || value->type == DAO_DOUBLE ){
						double f = DaoValue_GetDouble( value );
						if( scifmt ){
							sprintf( fmt, "%%%iE", width );
						}else{
							sprintf( fmt, "%%%i.%if", width, dec );
						}
						snprintf( buf, width+1, fmt, f );
					}else if( value->type == DAO_COMPLEX ){
						complex16 com = value->xComplex.value;
						char s = com.imag>=0 ? '+' : '-';
						int w = width/2-2;
						int d = dec;
						if( scifmt ){
							sprintf( fmt, "(%%%i.3E,%%%i.3E)", w, w );
						}else{
							sprintf( fmt, "(%%%i.%if,%%%i.%if)", w, d, w, d );
						}
						snprintf( buf, width, fmt, com.real, com.imag );
					}else{
						DString_Reset( sstream->streamString, 0 );
						DaoValue_Print( value, proc, sstream, NULL );
						DString_Reset( label, 0 );
						DString_Append( label, sstream->streamString );
						if( label->size > width ) DString_Reset( label, width );
						DString_ChangeMBS( label, "%t", "\\t", 0 );
						DString_ChangeMBS( label, "%n", "\\n", 0 );
						sprintf( fmt, "%%-%is", width );
						snprintf( buf, width+1, fmt, label->mbs );
					}
					DaoStream_WriteMBS( stream, buf );
				}
				DaoStream_WriteMBS( stream, "\n" );
			}
			DaoStream_WriteMBS( stream, "\n" );
		}
	}
	DaoStream_Delete( sstream );
	DVector_Delete( aligns );
	DVector_Delete( scifmts );
	DVector_Delete( decimals );
	DVector_Delete( rlabwidth );
	DVector_Delete( clabwidth );
	DString_Delete( label );
}