/*****************************************************************************/
/* ＳＴＫ単独実行プログラム */
/*****************************************************************************/

#include <stdio.h>
#include "defines.h"
#include "stk.h"

/*****************************************************************************/
// 外部コマンドテーブル

extern STKCOM	 vartbl[],kou0tbl[],koutbl[],kou2tbl[],stktbl[],entbl[]
		,arytbl[],strtbl[] ,prntbl[],keytbl[] ,comtbl[],dsktbl[]
		,filtbl[],dttbl[]  ,ebtbl[] ,systbl[]
		;

STKCOM *tkntbls[]={
	// 最初6つは標準なので出来るだけ入れる(無いとほとんど何もできない)
	 vartbl	,kou0tbl,koutbl	,kou2tbl,stktbl	,entbl
	// これ以降はオプション
	,arytbl	,strtbl	,prntbl	,keytbl	,comtbl	,dsktbl
	,filtbl	,dttbl	,ebtbl	,systbl
	// テーブル終了コード
	,NULL
};

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

static int SetNumParam(unchar *opt,int argc,unchar *argv[],int def,int high,int low)
// オプション数値指定の読み取り
{
int num;
	num=def;
	if (check_param3(opt,argv,argc,&num,0)) {
		if (num>high) num=high;
		if (num<low)  num=low;
	}
	return(num);
}

/*****************************************************************************/
/* デフォルト設定 */

#define	VSIZE	2048	/* 変数個数 */
#define	LSIZE	2048	/* ラベル個数 */
#define	NOCHK	32767	// その項目のチェックはしないの印
			// というか、short最大値で、これ以上の設定はだめ。
/*****************************************************************************/

main(int argc,unchar *argv[])
{
STKSYS sys;
int ret,fhelp=0,fnmes;
unint mode;
unchar *text,fname[MAXPATH];
	/* parameter check */
	/* オプションチェック初期化 */
	clear_param();
    HELP:
	if (helpcom0(argc,argv,fhelp,"STKx","[Options] text[.stk]")) {
		exit(fhelp? fhelp:255);
	}
	
	/* バージョン表示 */
	if (check_param2("VER",argv,argc,0)) {
		printf2("STK Ver." STKVER "\n");
		exit(0);
	}
	
	// コマンドラインの受け渡し
	sys.argc=argc;
	sys.argv=argv;
	
	// 最大個数
	sys.vsize=SetNumParam("VS",argc,argv,VSIZE,NOCHK,8); // 変数
	sys.lsize=SetNumParam("LS",argc,argv,LSIZE,NOCHK,8); // ラベル
	
	// 名前長さ
	sys.vlmax=SetNumParam("VL",argc,argv,VLMAX,SCVMAX,VLMIN); // 変数
	sys.llmax=SetNumParam("LL",argc,argv,LLMAX,SCLMAX,LLMIN); // ラベル
	
	// スタック段数
	sys.nmax=SetNumParam("NM",argc,argv,NMAX,NOCHK,NPOPS); // 数値
	sys.lmax=SetNumParam("LM",argc,argv,LMAX,NOCHK,1);  // ラベル
	sys.rmax=SetNumParam("RM",argc,argv,RMAX,NOCHK,1);  // ループ
	
	/* グローバル・ローカル変数 */
	sys.locmax=SetNumParam("LC",argc,argv,LOCAL,NOCHK,1);
	
	#ifndef NOTRACE
	/* トレースモード */
	// BIT0,1=trace , 2=ntrace , 3=ltrace , 4=rtrace
	//    1〜3        4          8          16
	mode=SetNumParam("TR",argc,argv,
		/* デフォルト値 */
		#if DEBUG
		/* デバッグモード：デフォルトでトレースon */
		MDTRmax
		#else
		/* 通常モード」デフォルトはトレースoff */
		0
		#endif
		,MDTRmax	/* 最大値 */
		,0		/* 最小値 */
		)
		<<MDTRbit; // トレースモードに合わせてビット位置へシフト
	#else
	mode=0;
	#endif
	
	/* CTRL-Cチェックフラグ */
	if (check_param2("NBRK",argv,argc,0)) mode|=MDfctrl;
	// 正常終了時メッセージ抑制
	fnmes=check_param2("NMES",argv,argc,0);
	
	/* オプションチェック */
	ret=check_param_error(argv,argc);
	if (ret) {
		printf2("\aオプションエラー：%s\n",argv[ret]);
		exit(1);
	}
	
	/* テキストファイル名取得 */
	ret=getfname(argc,argv,1,NULL);
	if (ret==0) {fhelp=100; goto HELP;}
	/* 拡張子補足 */
	fn_ext0(argv[ret],fname,STKEXT);
	
	// テキストファイル読み込み
	ret=TextRead(fname,&text);
	if (!ret)  {
	    long num;
		// STK実行
		ret=STK(text,tkntbls,&sys,(unlong)mode,&num);
		if (ret>0) { // エラー
			printf2("\a%s:%s\n",STKErrToken(),STKError(ret));
		} else { // 正常終了
			if (!fnmes) printf2("正常終了:%ld\n",num);
		}
		// ここでテキストを解放する
		free(text);
	}
	exit(ret);
}

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