/*****************************************************************************/
/* 変数,継続無し 式評価ルーチン */
/*****************************************************************************/

#include "defines.h"
#include "amacro.h"
#include "vsiki.h"

extern	VSSYS	Vsikis;

/*****************************************************************************/

int vsiki_mini(unchar *(*str0),long *num0)
/* 式評価ルーチン */
/* return : >0:error , 0=正常終了 */
{
long num;
unsint en,een;
unchar *str,*str1,c;
short fv=0,fc=0,ff=1; /* 数値フラグ、括弧フラグ、符号フラグ */
int err;
	/* スタックに数値、演算子を積む */
	Vsikis.vs=Vsikis.es=0;
	str=*str0;
	while (c=*str,c!=0&&c!=','&&c!='\n') {
	    if (c==SPC||c==TAB) {
		str++;
		continue;
	    }
	    /* 演算子読み取り */
	    if ((str1=EnzanRead(str,&en))!=NULL) {
		str=str1;
		switch (en) {
		    default:/* 演算子 */
			fv=fc=0;
			if (ff) {
				if (en=='-') en=VMINUS; /* 単項演算子：負号 */
				if (en=='+') {
					ff=0;
					continue; /* 単項演算子：正号->消す */
				}
			}
			if (Vsikis.vs==0&&en!=VMINUS&&en!='~'&&en!='!') return(VSOEN); /* 演算子のみ */
			if (Vsikis.es>0) {
			    /* 優先順位の同じ／高い演算子が出てきた時は先に演算する */
			    /* ただし代入だけは、それが続く場合、後の代入を優先する */
			    een=en;
			    while (Vsikis.es>0
			        && Yusen(een)<=Yusen(Vsikis.estack[Vsikis.es-1])) {
				int ret;
				ret=Enzan(NULL,NULL,&err);
				if (ret<0) return(err);
				een=ret;
			    }
			}
			/* 演算子をスタックに積む */
			if (Vsikis.es==Vsikis.emax) return(VSCPXE); /* stack over */
			Vsikis.estack[Vsikis.es++]=en;
			ff=(en==VMINUS? 0:2);
			
			#if DEBUG
			printc('<');
			printc2(en);
			crlf();
			#endif
			
			continue;
		    /* 括弧 */
		    case '(':
			if (fv==1) return(VSENONE); /* 数値の後ろに即'(' */
			if (Vsikis.es==Vsikis.emax) return(VSCPXC);
			Vsikis.estack[Vsikis.es++]=en;
			fv=0;
			fc=1;
			ff=3;
			continue;
		    case ')':
			if (fc==1) return(VSNNONE);
			/* 括弧を閉じる時、それまでのスタック内容で演算を行なう */
			while (Vsikis.estack[Vsikis.es-1]!='(') {
			    int ret;
				ret=Enzan(NULL,NULL,&err);
				if (ret<0) return(err);
				if (Vsikis.es==0) return(VSCNONE);
			}
			--Vsikis.es; /* (も消す */
			fv=fc=ff=0;
			continue;
		}
	    }
	    /* 数値変数読み取り */
	    if (fv==1) return(VSDBL); /* 数値が２つ続く */
	    if (Vsikis.vs==Vsikis.vmax) return(VSCPXS); /* stack over */
	    
	    /* 変数はその内容の数値が対象になる */
	    str1=NumRead(str,&num);
	    if (str1==NULL) return(VSNONE);
	
	    Vsikis.vstack[Vsikis.vs++]=num;
	
	    fv=1;	/* 数値を積んだ */
	    fc=ff=0;	/* 括弧/演算子は積んでない */
	    str=str1;
	
	    #if DEBUG
	    printf("[%ld\n",num);
	    #endif
	
	}
	
	/* スタックに積んである数値を演算子で計算する */
	while (Vsikis.es>0) {
	    int ret;
		ret=Enzan(NULL,NULL,&err);
		if (ret<0) {
			if (err==VSILL) {
				if (Vsikis.estack[Vsikis.es-1]=='(') return(VSCNENG);
			}
			return(err);
		}
	}
	/* 正常終了 */
	*num0=Vsikis.vstack[0];
	*str0=str;
	return(0);
}

/*****************************************************************************/
