home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
ML
/
EXEC3.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-05
|
7KB
|
337 lines
/*
* 実行処理
*
* 1994.5.22 T.Kobayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "exec.h"
#include "err.h"
#include "inlib.h"
static void ExecOpeBoolean( int, int, DataStruct* );
static void ExecOpeInt( int, int, DataStruct* );
static void ExecOpeReal( int, int, DataStruct* );
extern int (*BreakCheck)(void);
/*
* 式の実行
*/
void ExecExpression()
{
DataStruct *buf, ary ;
if ((*BreakCheck)()) {
ExecError("強制終了しました");
}
for(;;)
{
switch( ExecPtr->type )
{
/* 定数 */
case CODE_CONST :
StackPush( & ExecPtr->c.data );
GotoNextCode();
break ;
/* 変数|関数 */
case CODE_IDENT :
if ( ExecPtr->ident.itype & IDENT_FUNC )
{
ExecFunction( ExecPtr );
}
else
{
buf = ExecRefVar();
if ( buf->type == TYPE_NOASN )
ExecError( "代入されていない変数を参照しました。" );
StackPush( buf );
}
break ;
/* 演算子 */
case CODE_OPERATOR :
if ( ExecPtr->ope.otype == OPE_EXP_END )
{
GotoNextCode();
return ;
}
else if ( ExecPtr->ope.otype < OPE_SINGLE )
{
buf = StackTop();
ExecOpe( ExecPtr->ope.otype, 1, buf );
GotoNextCode();
}
else
{
buf = StackTop() - 1 ;
ExecOpe( ExecPtr->ope.otype, 2, buf );
GotoNextCode();
StackRelease( buf );
}
break ;
/* 配列 */
case CODE_ARRAY :
ary.type = TYPE_ARRAY ;
ary.ad.size = ExecPtr->ary.asize ;
ary.ad.ary = StackTop() - ary.ad.size + 1 ;
StackPush( &ary );
GotoNextCode();
break ;
default:
assert( FALSE );
}
if ( ExecPtr == NULL )
{
ExecError( "式の途中でファイルエンドになりました" );
}
}
}
/* 演算子の処理 */
void ExecOpe( ope, args, buf )
int ope ;
int args ;
DataStruct *buf ;
{
switch( buf->type )
{
case TYPE_OBJECT:
CallFunctionLocal( ope, args, buf );
break ;
case TYPE_BOOLEAN:
ExecOpeBoolean( ope, args, buf );
break ;
case TYPE_INT:
ExecOpeInt( ope, args, buf );
break ;
case TYPE_REAL:
ExecOpeReal( ope, args, buf );
break ;
case TYPE_ARRAY:
case TYPE_TYPE:
case TYPE_FUNC:
if ( ope == OPE_EQ )
{
buf[0].type = TYPE_BOOLEAN ;
buf[0].ld.l = ( buf[0].td.t == buf[1].td.t );
}
else if ( ope == OPE_NOTEQ )
{
buf[0].type = TYPE_BOOLEAN ;
buf[0].ld.l = ( buf[0].td.t != buf[1].td.t );
}
else
ExecError( "演算の型が不正です。" );
break ;
default:
assert( FALSE );
}
}
static void ExecOpeBoolean( ope, args, buf )
int ope ;
int args ;
DataStruct *buf ;
{
if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT) ) )
{
ExecError( "論理演算の型が不正です。" );
}
switch( ope )
{
case OPE_NOT:
buf->ld.l = ! buf->ld.l ;
break ;
case OPE_AND:
buf->ld.l = ( buf[0].ld.l && buf[1].ld.l );
break ;
case OPE_OR:
buf->ld.l = ( buf[0].ld.l || buf[1].ld.l );
break ;
case OPE_XOR:
buf->ld.l = ( buf[0].ld.l ^ buf[1].ld.l );
break ;
case OPE_EQ:
buf->ld.l = ( buf[0].ld.l == buf[1].ld.l );
break ;
case OPE_NOTEQ:
buf->ld.l = ( buf[0].ld.l != buf[1].ld.l );
break ;
default:
ExecError( "論理演算の演算子が不正です。" );
}
}
static void ExecOpeInt( ope, args, buf )
int ope ;
int args ;
DataStruct *buf ;
{
if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT|TYPE_REAL) ) )
{
ExecError( "整数演算の型が不正です。" );
}
if ( buf[1].type == TYPE_REAL )
{
buf[1].type = TYPE_INT ;
buf[1].id.i = (int)( buf[1].rd.r );
}
#if 0
printf( "ExecOpeInt( %d )\n", ope );
#endif
switch( ope )
{
case OPE_NOT:
buf->id.i = ! buf->id.i ;
break ;
case OPE_MINUS1:
buf->id.i = - buf->id.i ;
break ;
case OPE_PLUS:
buf->id.i = buf[0].id.i + buf[1].id.i ;
break ;
case OPE_MINUS:
buf->id.i = buf[0].id.i - buf[1].id.i ;
break ;
case OPE_INC:
buf->id.i ++ ;
break ;
case OPE_DEC:
buf->id.i -- ;
break ;
case OPE_MULT:
buf->id.i = buf[0].id.i * buf[1].id.i ;
break ;
case OPE_DIVIDE:
if (buf[1].id.i != 0) {
buf->id.i = buf[0].id.i / buf[1].id.i ;
}
break ;
case OPE_MOD:
buf->id.i = buf[0].id.i % buf[1].id.i ;
break ;
case OPE_LSFT:
buf->id.i = buf[0].id.i << buf[1].id.i ;
break ;
case OPE_RSFT:
buf->id.i = buf[0].id.i >> buf[1].id.i ;
break ;
case OPE_LSS:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i < buf[1].id.i );
break ;
case OPE_GTR:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i > buf[1].id.i );
break ;
case OPE_LSSEQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i <= buf[1].id.i );
break ;
case OPE_GTREQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i >= buf[1].id.i );
break ;
case OPE_EQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i == buf[1].id.i );
break ;
case OPE_NOTEQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].id.i != buf[1].id.i );
break ;
case OPE_AND:
buf->id.i = ( buf[0].id.i & buf[1].id.i );
break ;
case OPE_OR:
buf->id.i = ( buf[0].id.i | buf[1].id.i );
break ;
case OPE_XOR:
buf->id.i = ( buf[0].id.i ^ buf[1].id.i );
break ;
default:
ExecError( "整数演算の演算子が不正です。" );
}
}
static void ExecOpeReal( ope, args, buf )
int ope ;
int args ;
DataStruct *buf ;
{
if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT|TYPE_REAL) ) )
{
ExecError( "実数演算の型が不正です。" );
}
if ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT) )
{
buf[1].type = TYPE_REAL ;
buf[1].rd.r = (float)( buf[1].id.i );
}
switch( ope )
{
case OPE_MINUS1:
buf->rd.r = - buf->rd.r ;
break ;
case OPE_PLUS:
buf->rd.r = buf[0].rd.r + buf[1].rd.r ;
break ;
case OPE_MINUS:
buf->rd.r = buf[0].rd.r - buf[1].rd.r ;
break ;
case OPE_INC:
buf->rd.r ++ ;
break ;
case OPE_DEC:
buf->rd.r -- ;
break ;
case OPE_MULT:
buf->rd.r = buf[0].rd.r * buf[1].rd.r ;
break ;
case OPE_DIVIDE:
if (buf[1].rd.r > 1e-64 || buf[1].rd.r < -1e-64) {
buf->rd.r = buf[0].rd.r / buf[1].rd.r ;
}
break ;
case OPE_LSS:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r < buf[1].rd.r );
break ;
case OPE_GTR:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r > buf[1].rd.r );
break ;
case OPE_LSSEQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r <= buf[1].rd.r );
break ;
case OPE_GTREQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r >= buf[1].rd.r );
break ;
case OPE_EQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r == buf[1].rd.r );
break ;
case OPE_NOTEQ:
buf->type = TYPE_BOOLEAN ;
buf->ld.l = ( buf[0].rd.r != buf[1].rd.r );
break ;
default:
ExecError( "実数演算の演算子が不正です。" );
break ;
}
}