/*****************************************************************************
 * Bison/Flexプログラム部分をテストするための、Windowsアプリケーションの雛型 *
 * □ビルド・実行方法:                                                       *
 * ┃"C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"  *
 * ┃make -f winapp.mk run                                                   *
 *****************************************************************************/
#ifndef __WINAPP_H__
#define __WINAPP_H__
/*{{定型コード:winapp.h======================================================*/
#include <clip.h>
/* y.tab.y */
extern int yynerrs;
#if     (YYDEBUG!=0)
extern int yydebug;
#endif/*(YYDEBUG!=0)*/
int yyparse();
void yyerror(const char* fmt, ...);
/* lex.yy.l */
extern FILE* yyin;
extern FILE* yyout;
extern int yylineno;
int yylex();
void yylex_init(FILE* input_file);
/* winapp.c */
void push_location(const char* path);
void pop_location();
/*}}定型コード:winapp.h======================================================*/
//-----------------------------------------------------------------------------
//エラー回避
//-----------------------------------------------------------------------------
//clipsnrs.hで定義されている同名の構造体や関数との名前衝突を回避する。
#define _ST_SnrSeq	_ST_SnrSeq_
#define  ST_SnrSeq	 ST_SnrSeq_
#define  SnrSeq_New	 SnrSeq_New_
//-----------------------------------------------------------------------------
//構造体定義
//-----------------------------------------------------------------------------
typedef struct	_ST_Arg			ST_Arg;
typedef struct	_ST_Args		ST_Args;
typedef struct	_ST_Func		ST_Func;
typedef struct	_ST_Cond		ST_Cond;
typedef struct	_ST_CondSubs		ST_CondSubs;
typedef struct	_ST_ValueSubs		ST_ValueSubs;
typedef struct	_ST_SnrTbl		ST_SnrTbl;
typedef struct	_ST_SnrTblBody		ST_SnrTblBody;
typedef struct	_ST_OnUnlockStmt	ST_OnUnlockStmt;
typedef struct	_ST_OnGotoStmt		ST_OnGotoStmt;
typedef struct	_ST_OnExecStmt		ST_OnExecStmt;
typedef union	_ST_SnrTblStmt		ST_SnrTblStmt;
typedef struct	_ST_SnrSeq		ST_SnrSeq;
typedef struct	_ST_SnrSeqBody		ST_SnrSeqBody;
typedef struct	_ST_ExitStmt		ST_ExitStmt;
typedef struct	_ST_EscapeStmt		ST_EscapeStmt;
typedef struct	_ST_WaitStmt		ST_WaitStmt;
typedef struct	_ST_WaitForStmt		ST_WaitForStmt;
typedef struct	_ST_ForkStmt		ST_ForkStmt;
typedef struct	_ST_HideStmt		ST_HideStmt;
typedef struct	_ST_JoinStmt		ST_JoinStmt;
typedef struct	_ST_GotoStmt		ST_GotoStmt;
typedef struct	_ST_CallStmt		ST_CallStmt;
typedef struct	_ST_IfStmt		ST_IfStmt;
typedef struct	_ST_CaseStmt		ST_CaseStmt;
typedef struct	_ST_RepeatStmt		ST_RepeatStmt;
typedef struct	_ST_BreakStmt		ST_BreakStmt;
typedef struct	_ST_WhileStmt		ST_WhileStmt;
typedef struct	_ST_ActStmt		ST_ActStmt;
typedef union	_ST_SnrSeqStmt		ST_SnrSeqStmt;
typedef struct	_ST_Code		ST_Code;
//-----------------------------------------------------------------------------
//引数
enum {
	ArgType_Bit = 1,
	ArgType_Byte,
	ArgType_Half,
	ArgType_Exp10,
	ArgType_Word,
	ArgType_Ber,		//{{2018/04/07追加:引数リストにBER圧縮整数も含められるようにしました。}}
	ArgType_Fp16,
	ArgType_Fp32,
	ArgType_Fp64,
	ArgType_String,
	ArgType_File,
	ArgType_Table,		//当ツール特有の型
	ArgType_Trig,		//当ツール特有の型
	ArgType_Func,		//当ツール特有の型
};
/*typedef*/ struct _ST_Arg {
	int			iArgType;
	union {
		int		v_bit;
		int		v_byte;
		int		v_half;
		int		v_exp10;
		int		v_word;
		int		v_ber;		//{{2018/04/07追加:引数リストにBER圧縮整数も含められるようにしました。}}
		double		v_fp16;
		double		v_fp32;
		double		v_fp64;
		char*		v_string;					//ポインタで比較出来るように、単一化して格納する。
		char*		v_file;						//ポインタで比較出来るように、単一化して格納する。
		char*		v_table;					//ポインタで比較出来るように、単一化して格納する。
		char*		v_trig;						//ポインタで比較出来るように、単一化して格納する。
		char*		v_func;						//ポインタで比較出来るように、単一化して格納する。
	} value;
} /*ST_Arg*/;
ST_Arg* Arg_NewBit(   int n);
ST_Arg* Arg_NewByte(  int n);
ST_Arg* Arg_NewHalf(  int n);
ST_Arg* Arg_NewExp10( int n);
ST_Arg* Arg_NewWord(  int n);
ST_Arg* Arg_NewBer(   int n);		//{{2018/04/07追加:引数リストにBER圧縮整数も含められるようにしました。}}
ST_Arg* Arg_NewFp16(  double d);
ST_Arg* Arg_NewFp32(  double d);
ST_Arg* Arg_NewFp64(  double d);
ST_Arg* Arg_NewString(char* s);
ST_Arg* Arg_NewFile(  char* s);
ST_Arg* Arg_NewTable( char* s);
ST_Arg* Arg_NewTrig(  char* s);
ST_Arg* Arg_NewFunc(  char* s);
ST_Arg* Arg_Intern(ST_Arg* pArg);
int Arg_Compar(const void* _a, const void* _b);
GSList* ArgList_AddArg(GSList* pArgList, ST_Arg* pArg);
GSList* ArgList_Intern(GSList* pArgList);
int ArgList_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//引数リスト
/*typedef*/ struct _ST_Args {
	GSList*			pArgList/*NULL可*/;				//pArgListの要素のpArgを、ポインタで比較出来るように単一化して追加し、最後に、pArgListも単一化して格納する。
} /*ST_Args*/;
ST_Args* Args_New(GSList* pArgList/*NULL可*/);
ST_Args* Args_Intern(ST_Args* pArgs);
int Args_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//関数
/*typedef*/ struct _ST_Func {
	char*			pFuncName;					//ポインタで比較出来るように、単一化して格納する。
	ST_Args*		pArgs;						//ポインタで比較出来るように、単一化して格納する。
} /*ST_Func*/;
ST_Func* Func_New(char* pFuncName, ST_Args* pArgs);
ST_Func* Func_Intern(ST_Func* pFunc);
int Func_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//条件
/*typedef*/ struct _ST_Cond {
	int			bNot;
	ST_Func*		pFunc;						//ポインタで比較出来るように、単一化して格納する。
} /*ST_Cond*/;
ST_Cond* Cond_New(int bNot, ST_Func* pFunc);
ST_Cond* Cond_Intern(ST_Cond* pCond);
int Cond_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//条件副文
/*typedef*/ struct _ST_CondSubs {	//'Subs'は'SubStmt'(副文)の略です。
	ST_Cond*		pCond;						//ポインタで比較出来るように、単一化して格納する。
	struct _ST_SnrSeqBody*	pSnrSeqBody;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_CondSubs*/;
ST_CondSubs* IfSubs_New(ST_Cond* pCond, ST_SnrSeqBody* pSnrSeqBody);
ST_CondSubs* UnlessSubs_New(ST_Cond* pCond, ST_SnrSeqBody* pSnrSeqBody);
ST_CondSubs* ElifSubs_New(ST_Cond* pCond, ST_SnrSeqBody* pSnrSeqBody);
ST_CondSubs* CondSubs_Intern(ST_CondSubs* pCondSubs);
int CondSubs_Compar(const void* _a, const void* _b);
GSList* CondSubsList_AddCondSubs(GSList* pCondSubsList, ST_CondSubs* pCondSubs);
GSList* CondSubsList_Intern(GSList* pCondSubsList);
int CondSubsList_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//値副文
/*typedef*/ struct _ST_ValueSubs {	//'Subs'は'SubStmt'(副文)の略です。
	int			iValue;
	struct _ST_SnrSeqBody*	pSnrSeqBody;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_ValueSubs*/;
ST_ValueSubs* OfSubs_New(int iValue, ST_SnrSeqBody* pSnrSeqBody);
ST_ValueSubs* ValueSubs_Intern(ST_ValueSubs* pValueSubs);
int ValueSubs_Compar(const void* _a, const void* _b);
GSList* ValueSubsList_AddValueSubs(GSList* pValueSubsList, ST_ValueSubs* pValueSubs);
GSList* ValueSubsList_Intern(GSList* pValueSubsList);
int ValueSubsList_Compar(const void* _a, const void* _b);
//-----------------------------------------------------------------------------
//シナリオテーブル
/*typedef*/ struct _ST_SnrTbl {
	char*			pSnrTblLabel;					//必須ではないが、単一化して格納する。
	struct _ST_SnrTblBody*	pSnrTblBody;					//最適化のために、単一化して格納する。
	//以下のフィールドは2パス目で格納する。ST_SnrTbl構造体は辞書のキーにしないので作成後に内容を変更して問題無い。
	int			iSnrTbl;					//シナリオテーブル番号
} /*ST_SnrTbl*/;
ST_SnrTbl* SnrTbl_New(char* pSnrTblLabel, ST_SnrTblBody* pSnrTblBody);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//シナリオテーブルボディ
/*typedef*/ struct _ST_SnrTblBody {
	GSList*			pSnrTblStmtList/*NULL可*/;			//pSnrTblStmtListは単一化しないが、pSnrTblStmtListの要素のpSnrTblStmtを、ポインタで比較出来るように単一化して追加する。pSnrTblStmtListはpTrigNameに対して重複無く、g_slist_insert_sorted()を使って追加する。
} /*ST_SnrTblBody*/;
ST_SnrTblBody* SnrTblBody_New();
ST_SnrTblBody* SnrTblBody_AddSnrTblStmt(ST_SnrTblBody* pSnrTblBody, ST_SnrTblStmt* pSnrTblStmt);
ST_SnrTblBody* SnrTblBody_Intern(ST_SnrTblBody* pSnrTblBody);
int SnrTblBody_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//シナリオテーブル文
enum {
	SnrTblStmtType_OnUnlock = 1,
	SnrTblStmtType_OnGoto,
	SnrTblStmtType_OnExec,
};
/*typedef*/ struct _ST_OnUnlockStmt {
	int			iSnrTblStmtType;
	char*			pTrigName;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_OnUnlockStmt*/;
ST_SnrTblStmt* OnUnlockStmt_New(char* pTrigName);
/*typedef*/ struct _ST_OnGotoStmt {
	int			iSnrTblStmtType;
	char*			pTrigName;					//ポインタで比較出来るように、単一化して格納する。
	int			bUnlock;
	char*			pSnrSeqLabel;					//ポインタで比較出来るように、単一化して格納する。
	int			nLock;
} /*ST_OnGotoStmt*/;
ST_SnrTblStmt* OnGotoStmt_New(char* pTrigName, int bUnlock, char* pSnrSeqLabel, int nLock);
ST_SnrTblStmt* OnGotoStmt_NewInline(char* pTrigName, int bUnlock, int nLock, ST_SnrSeqBody* pSnrSeqBody);
/*typedef*/ struct _ST_OnExecStmt {
	int			iSnrTblStmtType;
	char*			pTrigName;					//ポインタで比較出来るように、単一化して格納する。
	int			bUnlock;
	char*			pSnrSeqLabel;					//ポインタで比較出来るように、単一化して格納する。
	int			nLock;
} /*ST_OnExecStmt*/;
ST_SnrTblStmt* OnExecStmt_New(char* pTrigName, int bUnlock, char* pSnrSeqLabel, int nLock);
ST_SnrTblStmt* OnExecStmt_NewInline(char* pTrigName, int bUnlock, int nLock, ST_SnrSeqBody* pSnrSeqBody);
int Lock_New(int nLock);
/*typedef*/ union _ST_SnrTblStmt {
	int			iSnrTblStmtType;
	ST_OnUnlockStmt		onUnlockStmt;
	ST_OnGotoStmt		onGotoStmt;
	ST_OnExecStmt		onExecStmt;
} /*ST_SnrTblStmt*/;
ST_SnrTblStmt* SnrTblStmt_Intern(ST_SnrTblStmt* pSnrTblStmt);
int SnrTblStmt_Compar(const void* _a, const void* _b);
//-----------------------------------------------------------------------------
//シナリオシーケンス
/*typedef*/ struct _ST_SnrSeq {
	char*			pSnrSeqLabel;					//必須ではないが、単一化して格納する。
	struct _ST_SnrSeqBody*	pSnrSeqBody;					//最適化のために、単一化して格納する。
} /*ST_SnrSeq*/;
ST_SnrSeq* SnrSeq_New(char* pSnrSeqLabel, ST_SnrSeqBody* pSnrSeqBody);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//シナリオシーケンスボディ
/*typedef*/ struct _ST_SnrSeqBody {
	GSList*			pSnrSeqStmtList/*NULL可*/;			//pSnrSeqStmtListは単一化しないが、pSnrSeqStmtListの要素のpSnrSeqStmtを、ポインタで比較出来るように単一化して追加する。
} /*ST_SnrSeqBody*/;
ST_SnrSeqBody* SnrSeqBody_New();
ST_SnrSeqBody* SnrSeqBody_AddSnrSeqStmt(ST_SnrSeqBody* pSnrSeqBody, ST_SnrSeqStmt* pSnrSeqStmt);
ST_SnrSeqBody* SnrSeqBody_Intern(ST_SnrSeqBody* pSnrSeqBody);
int SnrSeqBody_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//シナリオシーケンス文
enum {
	SnrSeqStmtType_Exit = 1,
	SnrSeqStmtType_Escape,
	SnrSeqStmtType_Wait,
	SnrSeqStmtType_WaitFor,
	SnrSeqStmtType_Fork,
	SnrSeqStmtType_Hide,
	SnrSeqStmtType_Join,
	SnrSeqStmtType_Goto,
	SnrSeqStmtType_Call,
	SnrSeqStmtType_If,
	SnrSeqStmtType_Case,
	SnrSeqStmtType_Repeat,
	SnrSeqStmtType_Break,
	SnrSeqStmtType_While,
	SnrSeqStmtType_Act,
};
/*typedef*/ struct _ST_ExitStmt {
	int			iSnrSeqStmtType;
} /*ST_ExitStmt*/;
ST_SnrSeqStmt* ExitStmt_New();
/*typedef*/ struct _ST_EscapeStmt {
	int			iSnrSeqStmtType;
} /*ST_EscapeStmt*/;
ST_SnrSeqStmt* EscapeStmt_New();
/*typedef*/ struct _ST_WaitStmt {
	int			iSnrSeqStmtType;
	int			nWaitCnt;
} /*ST_WaitStmt*/;
ST_SnrSeqStmt* WaitStmt_New(int nWaitCnt);
int WaitCnt_New(int nWaitCnt);
/*typedef*/ struct _ST_WaitForStmt {
	int			iSnrSeqStmtType;
	ST_Cond*		pCond;						//ポインタで比較出来るように、単一化して格納する。
} /*ST_WaitForStmt*/;
ST_SnrSeqStmt* WaitForStmt_New(ST_Cond* pCond);
/*typedef*/ struct _ST_ForkStmt {
	int			iSnrSeqStmtType;
	ST_SnrSeqBody*		pSnrSeqBody;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_ForkStmt*/;
ST_SnrSeqStmt* ForkStmt_New(ST_SnrSeqBody* pSnrSeqBody);
/*typedef*/ struct _ST_HideStmt {
	int			iSnrSeqStmtType;
} /*ST_HideStmt*/;
ST_SnrSeqStmt* HideStmt_New();
/*typedef*/ struct _ST_JoinStmt {
	int			iSnrSeqStmtType;
} /*ST_JoinStmt*/;
ST_SnrSeqStmt* JoinStmt_New();
/*typedef*/ struct _ST_GotoStmt {
	int			iSnrSeqStmtType;
	char*			pSnrSeqLabel;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_GotoStmt*/;
ST_SnrSeqStmt* GotoStmt_New(char* pSnrSeqLabel);
/*typedef*/ struct _ST_CallStmt {
	int			iSnrSeqStmtType;
	char*			pSnrSeqLabel;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_CallStmt*/;
ST_SnrSeqStmt* CallStmt_New(char* pSnrSeqLabel);
/*typedef*/ struct _ST_IfStmt {
	int			iSnrSeqStmtType;
	ST_CondSubs*		pIfSubs;					//ポインタで比較出来るように、単一化して格納する。
	GSList*			pElifSubsList/*NULL可*/;			//pElifSubsListの要素のpCondSubsを、ポインタで比較出来るように単一化して追加し、最後に、pElifSubsListも単一化して格納する。
	ST_SnrSeqBody*		pElseSubs/*NULL可*/;				//ポインタで比較出来るように、単一化して格納する。
} /*ST_IfStmt*/;
ST_SnrSeqStmt* IfStmt_New(ST_CondSubs* pIfSubs, GSList* pElifSubsList/*NULL可*/, ST_SnrSeqBody* pElseSubs/*NULL可*/);
ST_SnrSeqStmt* UnlessStmt_New(ST_CondSubs* pUnlessSubs, ST_SnrSeqBody* pElseSubs/*NULL可*/);
/*typedef*/ struct _ST_CaseStmt {
	int			iSnrSeqStmtType;
	ST_Func*		pFunc;						//ポインタで比較出来るように、単一化して格納する。
	GSList*			pOfSubsList;					//pOfSubsListの要素のpValueSubsを、ポインタで比較出来るように単一化して追加し、最後に、pOfSubsListも単一化して格納する。pOfSubsListはiValueに対して重複無く、g_slist_insert_sorted()を使って追加する。
	ST_SnrSeqBody*		pElseSubs/*NULL可*/;				//ポインタで比較出来るように、単一化して格納する。
} /*ST_CaseStmt*/;
ST_SnrSeqStmt* CaseStmt_New(ST_Func* pFunc, GSList* pOfSubsList, ST_SnrSeqBody* pElseSubs/*NULL可*/);
/*typedef*/ struct _ST_RepeatStmt {
	int			iSnrSeqStmtType;
	int			nRepeatCnt;
	ST_SnrSeqBody*		pSnrSeqBody;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_RepeatStmt*/;
ST_SnrSeqStmt* RepeatStmt_New(int nRepeatCnt, ST_SnrSeqBody* pSnrSeqBody);
int RepeatCnt_New(int nRepeatCnt);
/*typedef*/ struct _ST_BreakStmt {
	int			iSnrSeqStmtType;
	int			nBreakCnt;
} /*ST_BreakStmt*/;
ST_SnrSeqStmt* BreakStmt_New(int nBreakCnt);
int BreakCnt_New(int nBreakCnt);
/*typedef*/ struct _ST_WhileStmt {
	int			iSnrSeqStmtType;
	ST_Cond*		pCond;						//ポインタで比較出来るように、単一化して格納する。
	ST_SnrSeqBody*		pSnrSeqBody;					//ポインタで比較出来るように、単一化して格納する。
} /*ST_WhileStmt*/;
ST_SnrSeqStmt* WhileStmt_New(ST_Cond* pCond, ST_SnrSeqBody* pSnrSeqBody);
ST_SnrSeqStmt* UntilStmt_New(ST_Cond* pCond, ST_SnrSeqBody* pSnrSeqBody);
/*typedef*/ struct _ST_ActStmt {
	int			iSnrSeqStmtType;
	ST_Func*		pFunc;						//ポインタで比較出来るように、単一化して格納する。
	int			bEnsure;
} /*ST_ActStmt*/;
ST_SnrSeqStmt* ActStmt_New(ST_Func* pFunc, int bEnsure);
/*typedef*/ union _ST_SnrSeqStmt {
	int			iSnrSeqStmtType;
	ST_ExitStmt		exitStmt;
	ST_EscapeStmt		escapeStmt;
	ST_WaitStmt		waitStmt;
	ST_WaitForStmt		waitForStmt;
	ST_ForkStmt		forkStmt;
	ST_HideStmt		hideStmt;
	ST_JoinStmt		joinStmt;
	ST_GotoStmt		gotoStmt;
	ST_CallStmt		callStmt;
	ST_IfStmt		ifStmt;
	ST_CaseStmt		caseStmt;
	ST_RepeatStmt		repeatStmt;
	ST_BreakStmt		breakStmt;
	ST_WhileStmt		whileStmt;
	ST_ActStmt		actStmt;
} /*ST_SnrSeqStmt*/;
ST_SnrSeqStmt* SnrSeqStmt_Intern(ST_SnrSeqStmt* pSnrSeqStmt);
int SnrSeqStmt_Compar(const void* _a, const void* _b);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//コード
/*typedef*/ struct _ST_Code {
	int			addr;
	GByteArray*		code;
} /*ST_Code*/;
ST_Code* Code_New(int addr);
int Code_AddValue(ST_Code* pCode, int value, int size);
int Code_AddData(ST_Code* pCode, const void* data, int size);
//-----------------------------------------------------------------------------
//定数定義
//-----------------------------------------------------------------------------
#undef  INT24_MIN		//┐
#undef  INT24_MAX		//├念のため確実に未定義としておく。(Microchipのヘッダファイル等では定義されているみたいです。)
#undef  UINT24_MAX		//┘
#define INT24_MIN		(INT32_MIN>>8)
#define INT24_MAX		(INT32_MAX>>8)
#define UINT24_MAX		((int)(UINT32_MAX>>8))	//(int)が必要です。忘れると、int変数との比較の際に、間違ってunsignedで比較してしまう。
//-----------------------------------------------------------------------------
//グローバル関数宣言
//-----------------------------------------------------------------------------
int cast_dbl_to_int(double d);
void addSnrTbl(ST_SnrTbl* pSnrTbl);
void addSnrSeq(ST_SnrSeq* pSnrSeq);
char* LabDef_New(char* pLabel);
char* LabRef_New(char* pLabel);
int TrigName_Compar(const void* _a, const void* _b);
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * Sat Oct 14 22:22:29 JST 2017 Naoyuki Sawa
// - 1st リリース。
// * Fri Oct 27 23:39:55 JST 2017 Naoyuki Sawa
// - 引数リストに、table,trig,func型を追加しました。
//   コールバック関数への引数リストの中で、シナリオテーブル番号，トリガ番号，関数番号を引き渡せるようになりました。
//   これまでは、これらの番号は当ツールがヘッダファイルを出力するまで決定出来ず、当ツールの入力スクリプト内では使用出来なかったのですが、
//   今回の変更により、当ツールの入力スクリプト内でも(自己参照のような感じで)これらの番号が使えるようになりました。
//   別のチャネルにシナリオテーブルを設定したり、別のチャネルにトリガを送信するようなコールバック関数が、作り易くなったと思います。
//   (ただし、自分自身のチャネルを操作する事は不可である事に注意して下さい。
//   詳細は/clip/clipsnrs.cの'Tue Oct 24 23:47:20 JST 2017 Naoyuki Sawa'のコメントを参照して下さい。)
//   尚、関数番号を有効に利用出来るケースはあまり思い付かないのですが、関数番号も他の番号と同じ方法で対応出来たので、対応しておきました。
// * Sun Oct 29 23:57:57 JST 2017 Naoyuki Sawa
// - 'wait for'命令と'wait for not'命令を追加しました。
// * Tue Oct 31 23:47:56 JST 2017 Naoyuki Sawa
// - シナリオテーブルの中でシナリオシーケンスを定義する糖衣構文(OnStmt_NewInline())を追加しました。
// * Sat Nov 04 23:56:59 JST 2017 Naoyuki Sawa
// - '-l'オプションを追加しました。
// - ラベルテーブルの格納構造は、以下の通りです。
//   │┌────────┐TBL_SnrTblNo
//   ││アドレステーブル│
//   │└────────┘
//   │┌────────┐TBL_SnrSeq
//   ││ラベルテーブル  │
//   │├────────┤
//   ││命令コード　　　│
//   │└────────┘
//   アトレステーブルに格納される値は、ラベルテーブルによって増加したサイズも考慮した、TBL_SnrSeq先頭からのオフセット値です。
//   従って、既存のアプリケーションの観点からは、ラベルテーブルを意識する必要は無く、既存のアプリケーションの変更は不要です。
//   上図のような格納構造とした理由の一つは、命令コード内の距離の限界に影響を与えないようにするためです。
//   命令コード内の距離は24ビットで格納しているので、符号付きと見なせば最大8MBです。
//   もし、命令コードの途中にラベルテーブルが散財するような格納構造にしていたら、距離の限界を超える恐れが生じたでしょう。
//   しかし、上図のようにラベルテーブルと命令コードを分離していれば、命令コード内同士の距離には影響は無く、問題は生じません。
//   尚、アドレステーブルから命令コードへの距離は増えましたが、アドレステーブルの値は元々32ビットですから、問題はありません。
// - '-l'オプションが指定された場合の、ラベルテーブルの構造は、以下の通りです。
//   │シナリオテーブル#1の名前,'\0'	┐
//   │シナリオテーブル#2の名前,'\0'	│
//   │…				│シナリオテーブルの名前のリスト
//   │シナリオテーブル#Maxの名前,'\0'	│
//   │'\0'				┘
//   │トリガ#1の名前,'\0'		┐
//   │トリガ#2の名前,'\0'		│
//   │…				│トリガの名前のリスト	トリガ#0("set")とトリガ#255("clr")は格納されない事に注意して下さい。
//   │トリガ#Maxの名前,'\0'		│
//   │'\0'				┘
//   │関数#1の名前,'\0'		┐
//   │関数#2の名前,'\0'		│
//   │…				│関数の名前のリスト
//   │関数#Maxの名前,'\0'		│
//   │'\0'				┘
// - '-l'オプションが指定されなかった場合の、ラベルテーブルの構造は、以下の通りです。
//   │'\0'				─シナリオテーブルの名前のリスト(空)
//   │'\0'				─トリガの名前のリスト(空)
//   │'\0'				─関数の名前のリスト(空)
//   上図のように、空のリストとして格納されるので、アプリケーションの観点からは構造上は同じと見なせます。
// - ラベルテーブルを検索するユーティリティ関数として、clipsnrs.cに以下の関数を追加しました。
//   │SnrSeq_GetTableName(),SnrSeq_GetTrigName(),SnrSeq_GetFuncName()
//   │SnrSeq_GetTableNo(),SnrSeq_GetTrigNo(),SnrSeq_GetFuncNo()
//   │SnrSeq_TryGetTableName(),SnrSeq_TryGetTrigName(),SnrSeq_TryGetFuncName()
//   │SnrSeq_TryGetTableNo(),SnrSeq_TryGetTrigNo(),SnrSeq_TryGetFuncNo()
//   ただし、ラベルテーブルの構造上、これらの関数は毎回ラベルテーブルの先頭から走査する必要が有り、実行速度が遅いです。
//   実行速度が必要なケースでは、アプリケーションが直接ラベルテーブルを走査して、辞書を構築する等の方法を取って下さい。
//   アプリケーションが直接ラベルテーブルを取得するための関数として、clipsnrs.cに以下の関数も追加しました。
//   │SnrSeq_GetLabelTable()
// * Sat Nov 11 23:59:59 JST 2017 Naoyuki Sawa
// - 'escape'命令を追加しました。
//   詳細は、/clip/clipsnrs.c の同日のコメントを参照して下さい。
// * Tue Nov 21 23:59:59 JST 2017 Naoyuki Sawa
// - 'on unlock','on exec','on unlock exec'命令を追加しました。
//   詳細は、/clip/clipsnrs.c の同日のコメントを参照して下さい。
// * Thu Nov 23 23:09:00 JST 2017 Naoyuki Sawa
// - '-t'オプションを追加しました。
//   目的と、マクロ定義の仕組みは、dFsmMapC.exeの'-t'オプションと同様です。
//   詳細は、/clip/tool/dFsmMapC/winapp.h の、'Tue Mar 01 23:23:41 JST 2016 Naoyuki Sawa'のコメントを参照して下さい。
// - '-t'オプションと'-xcs'オプションの併用は未実装です。
//   dFsmMapC.exeと同様に実装する事も出来たのですが、今はC#アプリケーションを作成していないのですぐにテスト出来ません。
//   テスト無しで実装してバグが残っていると、今後使用する時に混乱を招くので、今回は未実装のままにしておく事にしました。
//   今後、C#アプリケーションを作成する時に、実装する予定です。
//   実装する箇所は、/clip/tool/dSnrSeqC/winapp.c のoutput()内の、「※TODO:未実装」の箇所です。
// * Sat Apr 07 23:59:59 JST 2018 Naoyuki Sawa
// - 引数リストにBER圧縮整数も含められるようにしました。
// * Thu May 03 23:59:59 JST 2018 Naoyuki Sawa
// - Boehm GCを修正した事に伴い、当ツールもリビルドしました。
//   詳細は、/clip/tool/gc/README.TXTの'Wed May 02 23:59:59 JST 2018 Naoyuki Sawa'のコメントを参照して下さい。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20180503"
//-----------------------------------------------------------------------------
#endif//__WINAPP_H__
