| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | 
							- /*
 
-  * ERMInterpreter.h, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #pragma once
 
- #include "ERMParser.h"
 
- #include "ERMScriptModule.h"
 
- class ERMInterpreter;
 
- namespace VERMInterpreter
 
- {
 
- 	using namespace ERM;
 
- 	//different exceptions that can be thrown during interpreting
 
- 	class EInterpreterProblem : public std::exception
 
- 	{
 
- 		std::string problem;
 
- 	public:
 
- 		const char * what() const throw() override
 
- 		{
 
- 			return problem.c_str();
 
- 		}
 
- 		~EInterpreterProblem() throw()
 
- 		{}
 
- 		EInterpreterProblem(const std::string & problemDesc) : problem(problemDesc)
 
- 		{}
 
- 	};
 
- 	struct ESymbolNotFound : public EInterpreterProblem
 
- 	{
 
- 		ESymbolNotFound(const std::string & sym) :
 
- 		  EInterpreterProblem(std::string("Symbol \"") + sym + std::string("\" not found!"))
 
- 		{}
 
- 	};
 
- 	struct EInvalidTrigger : public EInterpreterProblem
 
- 	{
 
- 		EInvalidTrigger(const std::string & sym) :
 
- 		  EInterpreterProblem(std::string("Trigger \"") + sym + std::string("\" is invalid!"))
 
- 		{}
 
- 	};
 
- 	struct EUsageOfUndefinedMacro : public EInterpreterProblem
 
- 	{
 
- 		EUsageOfUndefinedMacro(const std::string & macro) :
 
- 			EInterpreterProblem(std::string("Macro ") + macro + " is undefined")
 
- 		{}
 
- 	};
 
- 	struct EIexpProblem : public EInterpreterProblem
 
- 	{
 
- 		EIexpProblem(const std::string & desc) :
 
- 			EInterpreterProblem(desc)
 
- 		{}
 
- 	};
 
- 	struct ELineProblem : public EInterpreterProblem
 
- 	{
 
- 		ELineProblem(const std::string & desc) :
 
- 			EInterpreterProblem(desc)
 
- 		{}
 
- 	};
 
- 	struct EExecutionError : public EInterpreterProblem
 
- 	{
 
- 		EExecutionError(const std::string & desc) :
 
- 			EInterpreterProblem(desc)
 
- 		{}
 
- 	};
 
- 	//internal interpreter error related to execution
 
- 	struct EInterpreterError : public EExecutionError
 
- 	{
 
- 		EInterpreterError(const std::string & desc) :
 
- 			EExecutionError(desc)
 
- 		{}
 
- 	};
 
- 	//wrong script
 
- 	struct EScriptExecError : public EExecutionError
 
- 	{
 
- 		EScriptExecError(const std::string & desc) :
 
- 			EExecutionError(desc)
 
- 		{}
 
- 	};
 
- 	//wrong script
 
- 	struct EVermScriptExecError : public EScriptExecError
 
- 	{
 
- 		EVermScriptExecError(const std::string & desc) :
 
- 			EScriptExecError(desc)
 
- 		{}
 
- 	};
 
- 	//		All numeric variables are integer variables and have a range of -2147483647...+2147483647
 
- 	//		c			stores game active day number			//indirect variable
 
- 	//		d			current value							//not an actual variable but a modifier
 
- 	// 		e1..e100 	Function floating point variables		//local
 
- 	// 		e-1..e-100	Trigger local floating point variables	//local
 
- 	// 		'f'..'t'	Standard variables ('quick variables')	//global
 
- 	// 		v1..v1000	Standard variables						//global
 
- 	// 		w1..w100	Hero variables
 
- 	// 		w101..w200	Hero variables
 
- 	// 		x1..x16		Function parameters						//local
 
- 	// 		y1..y100	Function local variables				//local
 
- 	// 		y-1..y-100	Trigger-based local integer variables	//local
 
- 	// 		z1..z1000	String variables						//global
 
- 	// 		z-1..z-10	Function local string variables			//local
 
- 	struct TriggerType
 
- 	{
 
- 		//the same order of trigger types in this enum and in validTriggers array is obligatory!
 
- 		enum ETrigType
 
- 		{
 
- 			AE, BA, BF, BG, BR, CM, CO, FU, GE, GM, HE, HL, HM, IP, LE, MF, MG, MM, MR,	MW, OB, PI, SN, TH, TM
 
- 		};
 
- 		ETrigType type;
 
- 		static ETrigType convertTrigger(const std::string & trig)
 
- 		{
 
- 			static const std::string validTriggers[] =
 
- 			{
 
- 				"AE", "BA", "BF", "BG", "BR", "CM", "CO", "FU",
 
- 				"GE", "GM", "HE", "HL", "HM", "IP", "LE", "MF", "MG", "MM", "MR", "MW", "OB", "PI", "SN",
 
- 				"TH", "TM"
 
- 			};
 
- 			for(int i=0; i<ARRAY_COUNT(validTriggers); ++i)
 
- 			{
 
- 				if(validTriggers[i] == trig)
 
- 					return static_cast<ETrigType>(i);
 
- 			}
 
- 			throw EInvalidTrigger(trig);
 
- 		}
 
- 		bool operator<(const TriggerType & t2) const
 
- 		{
 
- 			return type < t2.type;
 
- 		}
 
- 		TriggerType(const std::string & sym)
 
- 		{
 
- 			type = convertTrigger(sym);
 
- 		}
 
- 	};
 
- 	struct LinePointer
 
- 	{
 
- 		int lineNum;
 
- 		int realLineNum;
 
- 		int fileLength;
 
- 		LinePointer()
 
- 			: fileLength(-1)
 
- 		{}
 
- 		LinePointer(int _fileLength, int line, int _realLineNum)
 
- 			: fileLength(_fileLength),
 
- 			lineNum(line),
 
- 			realLineNum(_realLineNum)
 
- 		{}
 
- 		bool operator<(const LinePointer & rhs) const
 
- 		{
 
- 			return lineNum < rhs.lineNum;
 
- 		}
 
- 		bool operator!=(const LinePointer & rhs) const
 
- 		{
 
- 			return lineNum != rhs.lineNum;
 
- 		}
 
- 		LinePointer & operator++()
 
- 		{
 
- 			++lineNum;
 
- 			return *this;
 
- 		}
 
- 		bool isValid() const
 
- 		{
 
- 			return fileLength > 0 && lineNum < fileLength;
 
- 		}
 
- 	};
 
- 	struct Trigger
 
- 	{
 
- 		LinePointer line;
 
- 		Trigger()
 
- 		{}
 
- 	};
 
- 	//verm goodies
 
- 	struct VSymbol
 
- 	{
 
- 		std::string text;
 
- 		VSymbol(const std::string & txt) : text(txt)
 
- 		{}
 
- 	};
 
- 	struct VNode;
 
- 	struct VOptionList;
 
- 	struct VNIL
 
- 	{};
 
- 	typedef boost::variant<char, double, int, std::string> TLiteral;
 
- 	typedef boost::variant<VNIL, boost::recursive_wrapper<VNode>, VSymbol, TLiteral, ERM::Tcommand> VOption; //options in v-expression, VNIl should be the default
 
- 	template<typename T, typename SecType>
 
- 	T& getAs(SecType & opt)
 
- 	{
 
- 		if(opt.type() == typeid(T))
 
- 			return boost::get<T>(opt);
 
- 		else
 
- 			throw EVermScriptExecError("Wrong type!");
 
- 	}
 
- 	template<typename T, typename SecType>
 
- 	bool isA(const SecType & opt)
 
- 	{
 
- 		if(opt.type() == typeid(T))
 
- 			return true;
 
- 		else
 
- 			return false;
 
- 	}
 
- 	struct VermTreeIterator
 
- 	{
 
- 	private:
 
- 		friend struct VOptionList;
 
- 		VOptionList * parent;
 
- 		enum Estate {NORM, CAR} state;
 
- 		int basePos; //car/cdr offset
 
- 	public:
 
- 		VermTreeIterator(VOptionList & _parent) : parent(&_parent), state(NORM), basePos(0)
 
- 		{}
 
- 		VermTreeIterator() : parent(nullptr), state(NORM)
 
- 		{}
 
- 		VermTreeIterator & operator=(const VOption & opt);
 
- 		VermTreeIterator & operator=(const std::vector<VOption> & opt);
 
- 		VermTreeIterator & operator=(const VOptionList & opt);
 
- 		VOption & getAsItem();
 
- 		VOptionList getAsList();
 
- 		size_t size() const;
 
- 		VermTreeIterator& operator=(const VermTreeIterator & rhs)
 
- 		{
 
- 			if(this == &rhs)
 
- 			{
 
- 				return *this;
 
- 			}
 
- 			parent = rhs.parent;
 
- 			state = rhs.state;
 
- 			basePos = rhs.basePos;
 
- 			return *this;
 
- 		}
 
- 	};
 
- 	struct VOptionList : public std::vector<VOption>
 
- 	{
 
- 	private:
 
- 		friend struct VermTreeIterator;
 
- 	public:
 
- 		VermTreeIterator car();
 
- 		VermTreeIterator cdr();
 
- 	};
 
- 	struct OptionConverterVisitor : boost::static_visitor<VOption>
 
- 	{
 
- 		VOption operator()(ERM::TVExp const& cmd) const;
 
- 		VOption operator()(ERM::TSymbol const& cmd) const;
 
- 		VOption operator()(char const& cmd) const;
 
- 		VOption operator()(double const& cmd) const;
 
- 		VOption operator()(int const& cmd) const;
 
- 		VOption operator()(ERM::Tcommand const& cmd) const;
 
- 		VOption operator()(ERM::TStringConstant const& cmd) const;
 
- 	};
 
- 	struct VNode
 
- 	{
 
- 	private:
 
- 		void processModifierList(const std::vector<TVModifier> & modifierList, bool asSymbol);
 
- 	public:
 
- 		VOptionList children;
 
- 		VNode( const ERM::TVExp & exp);
 
- 		VNode( const VOptionList & cdren );
 
- 		VNode( const ERM::TSymbol & sym ); //only in case sym has modifiers!
 
- 		VNode( const VOption & first, const VOptionList & rest); //merges given arguments into [a, rest];
 
- 		void setVnode( const VOption & first, const VOptionList & rest);
 
- 	};
 
- }
 
- class ERMInterpreter
 
- {
 
- /*not so*/ public:
 
- 	std::map<VERMInterpreter::LinePointer, ERM::TLine> scripts;
 
- 	typedef std::map<VERMInterpreter::TriggerType, std::vector<VERMInterpreter::Trigger> > TtriggerListType;
 
- 	TtriggerListType triggers;
 
- 	TtriggerListType postTriggers;
 
- 	std::vector<VERMInterpreter::LinePointer> instructions;
 
- 	static bool isCMDATrigger(const ERM::Tcommand & cmd);
 
- 	static bool isATrigger(const ERM::TLine & line);
 
- 	static ERM::EVOtions getExpType(const ERM::TVOption & opt);
 
- 	ERM::TLine & retrieveLine(const VERMInterpreter::LinePointer & linePtr);
 
- 	static ERM::TTriggerBase & retrieveTrigger(ERM::TLine & line);
 
- public:
 
- 	vstd::CLoggerBase * logger;
 
- 	ERMInterpreter(vstd::CLoggerBase * logger_);
 
- 	virtual ~ERMInterpreter();
 
- 	std::string loadScript(const std::string & name, const std::string & source);
 
- };
 
 
  |