//---------------------------------------------------------------------------
//
// "缽狟咭" for 丐木動陸及窒井動陸及窒井
// 醱棉戊□玉
//
//      Programed by NAKAUE.T (Meister) / Suikyo.
//
//  2001.05.27  Phase 5.1     奶件正□皿伉正’戊件由奶仿祭
//  2001.06.12  Phase 5.3.2   賬輯移邂巨件玄伉卞云仃月戊件氾平旦玄及田弘膜懇
//  2001.06.17  Phase 5.4     奶件仿奶件旦弁伉皿玄ま及簽賄濠曰請仄及田弘膜懇
//                            奶件仿奶件旦弁伉皿玄ま及咺昳輔寰及田弘膜懇
//                            菅戊件由奶仿
//  2002.03.10  Phase 7.9.0   憮踏及躂濤失弁本旦嗟鞅
//  2002.03.17                KIU卞寧歹六化TKisEngine井日TKawariVM卞抩憊庍凳
//                            き元仁TKawariCode黎楔咫橯KVMCode黎楔佮噢恀揤//  2002.03.18                KIU卞寧歹六化TKawariCompiler坌峊
//  2002.04.18  Phase 8.0.0   醱棉戊□玉弁仿旦蟈潸勻贅尹﹝
//
//---------------------------------------------------------------------------
#ifndef CODE_H__
#define CODE_H__
//---------------------------------------------------------------------------
#include <string>
#include <vector>
#include <iostream>
#include <typeinfo>
//---------------------------------------------------------------------------
class TKawariVM;			// VM

class TKVMCode_base;		// 醱棉戊□玉及奶件正□白尼□旦
class TKVMCodeList_base;	// 醱棉戊□玉及奶件正□白尼□旦(湘瓖弁仿旦)
class TKVMCodeList;			// 醱棉戊□玉弅

class TKVMCodeString;		// 妐儂昫
class TKVMCodeIDString;		// ID妐儂昫(菅戊件由奶伙瑛絆互唱卅月)
class TKVMCodeInlineScript;	// 奶件仿奶件旦弁伉皿玄
class TKVMCodeScriptStatment;	// 旦弁伉皿玄妐
class TKVMCodeEntryIndex;	// 巨件玄伉т昫失弁本旦
//--------------------------------------------------------------------------
// class TKVMCode_base;
//
// Interface class.
// 醱棉戊□玉及奶件正□白尼□旦
class TKVMCode_base {
public:
	// 撢墊
	virtual std::string Run(TKawariVM &vm)=0;
	// 菅戊件由奶伙
	virtual std::string DisCompile(void) const { return ""; }
	// Debug匹請恘毛公欠尹月
	virtual std::ostream &DebugIndent(std::ostream& os, unsigned int level=0) const;
	// 犯田永弘迕汁伉□刓憎
	virtual std::ostream &Debug(std::ostream& os, unsigned int level=0) const=0;
	// 輛昫 き元弁仿旦及樺寧及心裟壬木月﹝
	virtual bool Less(const TKVMCode_base& R_) const =0;
	// 犯旦玄仿弁正
	virtual ~TKVMCode_base () {};
};
//---------------------------------------------------------------------------
// Comparator (for STL)
class TKVMCode_baseP_Less {
public:
	bool operator()(const TKVMCode_base *L,const TKVMCode_base *R) const;
};
//--------------------------------------------------------------------------
typedef std::vector<TKVMCode_base *> TCodePVector;
//--------------------------------------------------------------------------
// class TKVMCodeList_base : public TKVMCode_base;
//
// Interface class.
// 伉旦玄毛儅勾醱棉戊□玉及奶件正□白尼□旦
// (恌仁卅中鏟擂祭及拺)
class TKVMCodeList_base : public TKVMCode_base{
public:
	std::vector<TKVMCode_base *> list;

	virtual bool Less(const TKVMCode_base &R_) const;
	virtual std::ostream &Debug(std::ostream& os, unsigned int level=0) const;
	virtual ~TKVMCodeList_base();
	TKVMCodeList_base (const std::vector<TKVMCode_base *> &tmplist);
protected:
	virtual const std::string GetName(void) const=0;
};

//--------------------------------------------------------------------------
// 醱棉戊□玉伉旦玄
// 儅勻化中月Code毛洘糧讀卞撢墊仄﹜蟈化及瑛絆毛瑛寧仄化請恘
class TKVMCodeList : public TKVMCodeList_base {
public:
	virtual std::string Run(class TKawariVM &vm);
	virtual std::string DisCompile(void) const;
	virtual ~TKVMCodeList() {}
	TKVMCodeList(const std::vector<TKVMCode_base *> &tmplist) : TKVMCodeList_base(tmplist) {}
protected:
	virtual const std::string GetName(void) const { return ""; }
};

//--------------------------------------------------------------------------
// 妐儂昫 (Literal)
// done.
class TKVMCodeString : public TKVMCode_base {
public:
	std::string s;

	virtual std::string Run(class TKawariVM &vm) { return s; }
	virtual std::string DisCompile(void) const;
	virtual bool Less(const TKVMCode_base &r_) const{
		const TKVMCodeString& r=dynamic_cast<const TKVMCodeString&>(r_);
		return(s<r.s);
	}
	virtual std::ostream &Debug(std::ostream& os, unsigned int level=0) const {
		return DebugIndent(os, level) << "S(" << s << ")" << std::endl;
	}
	virtual ~TKVMCodeString() {}
	TKVMCodeString(const std::string &str);
};

//--------------------------------------------------------------------------
// ID妐儂昫 (IdLiteral)
class TKVMCodeIDString : public TKVMCodeString {
public:
	virtual std::string DisCompile(void) const {
		return s;
	}
	virtual std::ostream &Debug(std::ostream& os, unsigned int level=0) const {
		return DebugIndent(os, level) << "ID(" << s << ")" << std::endl;
	}
	TKVMCodeIDString(const std::string &str) : TKVMCodeString(str) {}
};

//--------------------------------------------------------------------------
// 旦弁伉皿玄妐 ( WS ( Word WS ) * )
// 湘呿讀卞Statement午き元﹝
class TKVMCodeScriptStatement : public TKVMCodeList_base {
public:
	virtual std::string GetArg0(void);
	virtual std::string Run(class TKawariVM &vm);
	virtual std::string DisCompile(void) const;
	virtual ~TKVMCodeScriptStatement() {}
	TKVMCodeScriptStatement(const std::vector<TKVMCode_base *> &tmplist):TKVMCodeList_base(tmplist) {}
protected:
	virtual const std::string GetName(void) const { return "ScriptStatement"; }
};

//--------------------------------------------------------------------------
// 奶件仿奶件旦弁伉皿玄 ( '$(' ScriptStatementSeq ') )
class TKVMCodeInlineScript : public TKVMCodeList_base {
public:
	virtual std::string Run(class TKawariVM &vm);
	virtual std::string DisCompile(void) const;
	virtual ~TKVMCodeInlineScript() {}
	TKVMCodeInlineScript(const std::vector<TKVMCode_base *> &tmplist):TKVMCodeList_base(tmplist) {}
protected:
	virtual const std::string GetName(void) const { return "InlineScriptSubst"; }
};

//--------------------------------------------------------------------------
// 驕尹儂尥五巨件玄伉裟太請仄
// ( '$' EntryWord '[' WS Expr WS ']' )
class TKVMCodeEntryIndex : public TKVMCode_base {
public:
	TKVMCode_base *entry_id;
	TKVMCode_base *expr;	// 呿侳TKawariExpr互ェ月

	virtual std::string Run(class TKawariVM &vm);
	virtual std::string DisCompile(void) const;
	virtual bool Less(const TKVMCode_base &R_) const;
	virtual std::ostream &Debug(std::ostream& os, unsigned int level=0) const;
	virtual ~TKVMCodeEntryIndex();
	TKVMCodeEntryIndex(TKVMCode_base *eid, TKVMCode_base *e):entry_id(eid), expr(e) {}
};
//--------------------------------------------------------------------------
#endif // CODE_H__
