Преглед на файлове

* a few data structures for ERM/VERM interpreter

mateuszb преди 14 години
родител
ревизия
b0ca5b677c
променени са 1 файла, в които са добавени 148 реда и са изтрити 0 реда
  1. 148 0
      lib/ERMInterpreter.cpp

+ 148 - 0
lib/ERMInterpreter.cpp

@@ -13,8 +13,156 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
+
 namespace spirit = boost::spirit;
 
+namespace VERMInterpreter
+{
+	using namespace ERM;
+
+	//different exceptions that can be thrown during interpreting
+	class EInterpreterProblem : public std::exception
+	{};
+
+	class ESymbolNotFound : public EInterpreterProblem
+	{
+		std::string problem;
+	public:
+		ESymbolNotFound(const std::string & sym) : problem(std::string("Symbol ") + sym + std::string(" not found!"))
+		{}
+
+		const char * what() const throw() OVERRIDE
+		{
+			return problem.c_str();
+		}
+	};
+
+
+	///main environment class, manages symbols
+	class Environment
+	{
+	private:
+		std::map<std::string, TVOption> symbols;
+		Environment * lexicalParent;
+
+	public:
+		bool isBound(const std::string & name, bool globalOnly) const
+		{
+			std::map<std::string, TVOption>::const_iterator it = symbols.find(name);
+			if(globalOnly && lexicalParent)
+			{
+				return lexicalParent->isBound(name, globalOnly);
+			}
+
+			//we have it; if globalOnly is true, lexical parent is false here so we are global env
+			if(it != symbols.end())
+				return true;
+
+			//here, we don;t have it; but parent can have
+			if(lexicalParent)
+				return lexicalParent->isBound(name, globalOnly);
+
+			return false;
+		}
+
+		TVOption retrieveValue(const std::string & name) const
+		{
+			std::map<std::string, TVOption>::const_iterator it = symbols.find(name);
+			if(it == symbols.end())
+			{
+				if(lexicalParent)
+				{
+					return lexicalParent->retrieveValue(name);
+				}
+
+				throw ESymbolNotFound(name);
+			}
+			return it->second;
+		}
+		
+		///returns true if symbols was really unbound
+		enum EUnbindMode{LOCAL, RECURSIVE_UNTIL_HIT, FULLY_RECURSIVE};
+		bool unbind(const std::string & name, EUnbindMode mode)
+		{
+			if(isBound(name, false))
+			{
+				if(symbols.find(name) != symbols.end()) //result of isBound could be from higher lexical env
+					symbols.erase(symbols.find(name));
+
+				if(mode == FULLY_RECURSIVE && lexicalParent)
+					lexicalParent->unbind(name, mode);
+
+				return true;
+			}
+			if(lexicalParent && (mode == RECURSIVE_UNTIL_HIT || mode == FULLY_RECURSIVE))
+				return lexicalParent->unbind(name, mode);
+
+			//neither bound nor have lexical parent
+			return false;
+		}
+	};
+
+//		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 TriggerLocalVars
+	{
+		static const int EVAR_NUM = 100; //number of evar locals
+		double evar[EVAR_NUM]; //negative indices
+		
+		static const int YVAR_NUM = 100; //number of yvar locals
+		int yvar[YVAR_NUM];
+	};
+
+	struct FunctionLocalVars
+	{
+		static const int NUM_PARAMETERS = 16; //number of function parameters
+		int params[NUM_PARAMETERS]; //x-vars
+
+		static const int NUM_LOCALS = 100;
+		int locals[NUM_LOCALS]; //y-vars
+
+		static const int NUM_STRINGS = 10;
+		std::string strings[NUM_STRINGS]; //z-vars (negative indices)
+
+		static const int NUM_FLOATINGS = 100;
+		double floats[NUM_FLOATINGS]; //e-vars (positive indices)
+	};
+
+	struct ERMEnvironment
+	{
+		static const int NUM_QUICKS = 't' - 'f' + 1; //it should be 15
+		int quickVars[NUM_QUICKS]; //referenced by letter ('f' to 't' inclusive)
+
+		static const int NUM_STANDARDS = 1000;
+		int standardVars[NUM_STANDARDS]; //v-vars
+
+		static const int NUM_STRINGS = 1000;
+		std::string strings[NUM_STRINGS]; //z-vars (positive indices)
+	};
+
+	//call stack
+	class Stack
+	{
+		std::vector<int> entryPoints; //defines how to pass to current location
+		Environment * env; //most nested VERM environment
+	};
+}
+
+
+
 namespace ERMPrinter
 {
 	//console printer