home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
ML
/
STACK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-06
|
5KB
|
314 lines
/*
* 演算用スタック制御
*
* T.Kobayashi 1993.8.6
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "data.h"
#include "alloc.h"
#include "inlib.h"
#include "err.h"
extern int ExecDebug ;
/* 演算用スタック */
int MaxStack ;
DataStruct *StackBuf ;
int StackPtr ;
int StackUsed ;
/* スタックトップを得る */
DataStruct *StackTop()
{
assert( -1 <= StackPtr && StackPtr < MaxStack );
return (DataStruct*)&StackBuf[StackPtr] ;
}
/* ポップ */
void StackPop()
{
assert( 0 <= StackPtr && StackPtr < MaxStack );
if ( StackBuf[StackPtr].type & TYPE_OBJECT )
{
ObjectFree( StackBuf[StackPtr].od.ptr );
}
StackPtr -- ;
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "POP [%d] ", StackPtr );
DataPrint( &StackBuf[StackPtr+1] );
printf( "\n" );
}
#endif
}
/* プッシュ */
void StackPush( buf )
DataStruct *buf ;
{
StackPtr ++ ;
assert( 0 <= StackPtr );
if ( StackUsed < StackPtr )
StackUsed = StackPtr ;
if ( StackPtr >= MaxStack )
{
ExecError( "スタックオーバーフロー!!" );
}
if ( buf == NULL )
{
buf->type = TYPE_NOASN ;
}
else
{
StackBuf[StackPtr] = *buf ;
if ( buf->type & TYPE_OBJECT )
{
StackBuf[StackPtr].od.ptr = ObjectCopy( buf->od.ptr );
}
}
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "PUSH[%d] ", StackPtr );
DataPrint( buf );
printf( "\n" );
}
#endif
}
/* 論理型をプッシュ */
void StackPushBoolean( l )
int l ;
{
StackPtr ++ ;
assert( 0 <= StackPtr );
if ( StackUsed < StackPtr )
StackUsed = StackPtr ;
if ( StackPtr >= MaxStack )
{
ExecError( "スタックオーバーフロー!!" );
}
StackBuf[StackPtr].type = TYPE_BOOLEAN ;
StackBuf[StackPtr].ld.l = l ;
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "PUSH[%d] int : %d\n", StackPtr, l );
}
#endif
}
/* 整数をプッシュ */
void StackPushInt( i )
int i ;
{
StackPtr ++ ;
assert( 0 <= StackPtr );
if ( StackUsed < StackPtr )
StackUsed = StackPtr ;
if ( StackPtr >= MaxStack )
{
ExecError( "スタックオーバーフロー!!" );
}
StackBuf[StackPtr].type = TYPE_INT ;
StackBuf[StackPtr].id.i = i ;
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "PUSH[%d] int : %d\n", StackPtr, i );
}
#endif
}
/* 実数をプッシュ */
void StackPushReal( r )
double r ;
{
StackPtr ++ ;
assert( 0 <= StackPtr );
if ( StackUsed < StackPtr )
StackUsed = StackPtr ;
if ( StackPtr >= MaxStack )
{
ExecError( "スタックオーバーフロー!!" );
}
StackBuf[StackPtr].type = TYPE_REAL ;
StackBuf[StackPtr].rd.r = (float)r ;
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "PUSH[%d] int : %d\n", StackPtr, r );
}
#endif
}
/* スタック上に領域を得る */
DataStruct *StackAlloc( size )
int size ;
{
int i ;
DataStruct *data, *ret ;
assert( 0 <= size );
data = & StackBuf[StackPtr] + 1;
ret = data ;
StackPtr += size ;
assert( 0 <= StackPtr );
if ( StackUsed < StackPtr )
StackUsed = StackPtr ;
if ( StackPtr >= MaxStack )
{
ExecError( "スタックオーバーフロー!!" );
}
for( i = 0 ; i < size ; i++ )
{
data->type = TYPE_NOASN ;
data++ ;
}
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "Alloc[%d] : %d\n", StackPtr, size );
}
#endif
return ret ;
}
/* マーク位置まで解放 */
void StackRelease( ptr )
DataStruct *ptr ;
{
DataStruct *top ;
top = StackTop();
assert( StackBuf - 1 <= ptr && ptr <= top );
while( ptr < top )
{
if ( top->type & TYPE_OBJECT )
{
ObjectFree( top->od.ptr );
}
top -- ;
}
StackPtr = top - StackBuf ;
#if PDEBUG
if ( ExecDebug )
{
printf( " " );
printf( "Release[%d]\n", StackPtr );
}
#endif
}
/* スタックの最大使用量を得る */
int StackMaxUsed()
{
return StackUsed ;
}
/* データバッファの内容を表示 */
void DataPrint( buf )
DataStruct *buf ;
{
char str[256] ;
DataToString( str, buf );
printf( str );
}
/* 文字列に変換 */
int DataToString( str, buf )
char *str ;
DataStruct *buf ;
{
char *typename ;
switch( buf->type )
{
case TYPE_BOOLEAN:
if ( buf->ld.l )
strcpy( str, "TRUE" );
else
strcpy( str, "FALSE" );
break ;
case TYPE_INT:
sprintf( str, "%d", buf->id.i );
break ;
case TYPE_REAL:
sprintf( str, "%f", buf->rd.r );
break ;
case TYPE_FUNC:
sprintf( str, "%d", buf->funcd.ident );
break ;
case TYPE_ARRAY:
sprintf( str, "%X[%d]", (int)(buf->ad.ary), buf->ad.size );
break ;
case TYPE_TYPE:
switch( buf->td.t )
{
case TYPE_NOASN:
typename = "NO_ASSIGN" ;
break ;
case TYPE_BOOLEAN:
typename = "NO_ASSIGN" ;
case TYPE_INT:
typename = "INT" ;
break ;
case TYPE_REAL:
typename = "REAL" ;
break ;
case TYPE_TYPE:
typename = "TYPE" ;
break ;
case TYPE_ARRAY:
typename = "ARRAY" ;
break ;
case TYPE_FUNC:
typename = "FUNC" ;
break ;
case TYPE_OBJECT:
typename = "OBJECT" ;
break ;
default:
typename = "DATA TYPE ERROR!!!" ;
break ;
}
strcpy( str, typename );
break ;
case TYPE_OBJECT:
sprintf( str, "Object[%d][%X]", buf->od.ptr->type, buf->od.ptr );
break ;
default:
assert( FALSE );
}
return strlen( str );
}