/*	
 *	clipshya.h
 *
 *	操車場アルゴリズム
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2016 Naoyuki Sawa
 *
 *	* Wed May 14 22:25:54 JST 2014 Naoyuki Sawa
 *	- 1stリリース。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 *	* Wed Jun 22 22:49:18 JST 2016 Naoyuki Sawa
 *	- USE_SHUNTINGYARD_SEHシンボルを定義すると、clipshya.c内のDIE()を全て、SEH_throw(ShuntingYardException)に置き換えるようにしました。
 *	  ユーザーが入力した式のテキストを計算するために、他のモジュールから当モジュールのShuntingYard_Eval()を利用する事が有り、
 *	  もし式が間違っていた時にすぐに当モジュール内ですぐにエラー停止してしまうと、使いづらいケースが生じたからです。
 *	  上記のようなケースでは、今後はShuntingYardExceptionを捕捉する事で、実行を継続出来ます。
 *	  それ以外のケースでは、ShuntingYardExceptionを捕捉しなければ、これまで通りすぐにエラー停止します。
 *	- ゼロ除算チェックを追加しました。
 *	  これまではCPUのゼロ除算エラーが発生してしまっていましたが、今後はプログラムで検出してDIE(),又は,例外を投入します。
 *	* Fri Jun 24 21:38:01 JST 2016 Naoyuki Sawa
 *	- ShuntingYard()のバグに気付いたので、コメントを追記しました。
 *	  詳細は、ShuntingYard()内の「//{{2016/06/24コメント追記:〜」を参照して下さい。
 *	  いずれのバグも、'間違った式が入力された時にエラーを検出出来ない事が有る'というものであり、正しい式に対する処理は問題有りません。
 *	- clipexpr.cモジュールでは、上記のバグは修正済みです。
 *	  今後はclipshya.cを廃止してclipexpr.cへ切り替えて行く予定なので、clipshya.cは修正せずにこのままにしておく事にしました。
 *	  しかし、もしまだclipshya.cを使う事が有れば、その時に修正して検証して下さい。
 *	* Mon Sep 05 21:24:05 JST 2016 Naoyuki Sawa
 *	- 64ビット版では、例外コードをアドレスでなく、一意なFourCC識別子で表すようにしました。
 *	  setjmp()/longjmp()のパラメータは(int)であり、(void*)や(intptr_t)を使えないからです。
 *	  尚、32ビット版も64ビット版と共通に変更しても良いのですが、万一既存のコードに影響が生じる事を防ぐために、32ビット版はこれまで通りとしました。
 */
#ifndef __CLIP_SHYA_H__
#define __CLIP_SHYA_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

//{{2016/06/22追加:USE_SHUNTINGYARD_SEHシンボルを定義すると、clipshya.c内のDIE()を全て、SEH_throw(ShuntingYardException)に置き換えるようにしました。
#define USE_SHUNTINGYARD_SEH	//このシンボルを定義すると、clipshya.c内のDIE()を全て、SEH_throw(ShuntingYardException)に置き換えます。
#ifdef  USE_SHUNTINGYARD_SEH
//{{2016/09/05変更:64ビット版では、例外コードをアドレスでなく、一意なFourCC識別子で表すようにしました。
//extern const char ShuntingYardException[1/*dummy*/];
//↓2016/09/05変更:64ビット版では、例外コードをアドレスでなく、一意なFourCC識別子で表すようにしました。
#ifndef _WIN64
extern const char ShuntingYardException[1/*dummy*/];		//32ビット版
#else //_WIN64
#define ShuntingYardException MAKEFOURCC('S','h','y','a')	//64ビット版
#endif//_WIN64
//}}2016/09/05変更:64ビット版では、例外コードをアドレスでなく、一意なFourCC識別子で表すようにしました。
#endif//USE_SHUNTINGYARD_SEH
//}}2016/06/22追加:USE_SHUNTINGYARD_SEHシンボルを定義すると、clipshya.c内のDIE()を全て、SEH_throw(ShuntingYardException)に置き換えるようにしました。

/****************************************************************************
 *	操車場アルゴリズム
 ****************************************************************************/

/* ST_ShuntingYard.fnGetTokenTypeの戻り値 */
#define ShuntingYard_TokenType_Number                    1 /* 数値 */
#define ShuntingYard_TokenType_Function                  2 /* 関数 */
#define ShuntingYard_TokenType_FunctionArgumentSeparator 3 /* 関数の引数セパレータ(カンマなど) */
#define ShuntingYard_TokenType_Operator                  4 /* 演算子 */
#define ShuntingYard_TokenType_LeftParenthesis           5 /* 左括弧 */
#define ShuntingYard_TokenType_RightParenthesis          6 /* 右括弧 */

/* 操車場アルゴリズムの実行情報 */
typedef struct _ST_ShuntingYard {
	int (*fnGetTokenType )(int iToken, void* pParam);		/* アプリケーション定義の関数:トークンの種類を返す */
	int (*fnIsOpLeftAssoc)(int iOpTok, void* pParam);		/* アプリケーション定義の関数:演算子が左結合かを返す */
	int (*fnCompareOpPrec)(int iOpTok1, int iOpTok2, void* pParam);	/* アプリケーション定義の関数:演算子の優先順位を較べる */
} ST_ShuntingYard;

/* 操車場アルゴリズムを使用して、中置記法のトークン並びを、逆ポーランド記法のトークン並びに変換します。
 * [in]
 *	pShuntingYard		操車場アルゴリズムの実行情報
 *	aInput			中置記法のトークン並び。(0終端)
 *	aOutput			逆ポーランド記法のトークン並び(0終端)を格納するバッファ
 *	pParam			アプリケーション定義の関数に引き渡される、任意のパラメータ。
 * [out]
 *	aOutput			逆ポーランド記法のトークン並び(0終端)
 * [note]
 *	- トークン値は、アプリケーション定義の任意の値です。
 *	   ただし、0終端とするために、トークン値として(0)は使用できません。
 *	- aOutput[]には、呼出し側にて、充分なサイズを確保してください。
 *	  当関数は、aOutput[]の終端を認識しないので、サイズが不足すると、バッファの終端を超えて書き込みます。
 *	  aInput[]と同じサイズを確保するようにすれば、安全です。
 *	- aInput[]とaOutput[]に同じバッファを指定しても、動作すると思いますが、まだ確証が持てません。
 *	  (当関数の処理は、aOutput[]への書込みよりも、aInput[]からの読出しの方が、早く進むと思うが…)
 */
void ShuntingYard(const ST_ShuntingYard* pShuntingYard, const int* aInput, int* aOutput, void* pParam);

/* 操車場アルゴリズムを利用して、式テキストの計算を行します。
 * [in]
 *	pText			式テキスト
 * [out]
 *	戻り値			計算結果
 * [note]
 *	- 操車場アルゴリズムを利用して、式テキストの計算を行うサンプルです。
 *	  サンプルではありますが、これはこれで利用価値があると思うので、アプリケーションからも利用可能にしました。
 */
int ShuntingYard_Eval(const char* pText);

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif/*__CLIP_SHYA_H__*/
