src/expression.h

changeset 119
bdf8d46c145f
child 131
8ae8038b0168
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/expression.h	Sun Mar 30 21:51:23 2014 +0300
@@ -0,0 +1,132 @@
+#ifndef BOTC_EXPRESSION_H
+#define BOTC_EXPRESSION_H
+#include "parser.h"
+
+class DataBuffer;
+class ExpressionSymbol;
+class ExpressionValue;
+class ExpressionOperator;
+
+// =============================================================================
+//
+named_enum ExpressionOperatorType
+{
+	OPER_NegateLogical,
+	OPER_UnaryMinus,
+	OPER_Multiplication,
+	OPER_Division,
+	OPER_Modulus,
+	OPER_Addition,
+	OPER_Subtraction,
+	OPER_LeftShift,
+	OPER_RightShift,
+	OPER_CompareLesser,
+	OPER_CompareGreater,
+	OPER_CompareAtLeast,
+	OPER_CompareAtMost,
+	OPER_CompareEquals,
+	OPER_CompareNotEquals,
+	OPER_BitwiseAnd,
+	OPER_BitwiseXOr,
+	OPER_BitwiseOr,
+	OPER_LogicalAnd,
+	OPER_LogicalOr,
+	OPER_Ternary,
+};
+
+// =============================================================================
+//
+enum ExpressionSymbolType
+{
+	EXPRSYM_Operator,
+	EXPRSYM_Value,
+	EXPRSYM_Colon,
+};
+
+class Expression final
+{
+	public:
+		using SymbolList = List<ExpressionSymbol*>;
+
+		Expression (BotscriptParser* parser, Lexer* lx, DataType reqtype);
+		~Expression();
+		ExpressionValue*		getResult();
+
+	private:
+		BotscriptParser*		m_parser;
+		Lexer*					m_lexer;
+		SymbolList				m_symbols;
+		DataType				m_type;
+		String					m_badTokenText;
+
+		ExpressionValue*		evaluate(); // Process the expression and yield a result
+		ExpressionSymbol*		parseSymbol();
+		String					getTokenString();
+		void					adjustOperators();
+		void					verify(); // Ensure the expr is valid
+		void					tryVerifyValue (bool* verified, SymbolList::Iterator it);
+		ExpressionValue*		evaluateOperator (const ExpressionOperator* op,
+												  const List<ExpressionValue*>& values);
+		SymbolList::Iterator	findPrioritizedOperator();
+};
+
+// =============================================================================
+//
+class ExpressionSymbol
+{
+	public:
+		ExpressionSymbol (ExpressionSymbolType type) :
+			m_type (type) {}
+
+	PROPERTY (private, ExpressionSymbolType, type, setType, STOCK_WRITE)
+};
+
+// =============================================================================
+//
+class ExpressionOperator final : public ExpressionSymbol
+{
+	PROPERTY (public, ExpressionOperatorType, id, setID, STOCK_WRITE)
+
+	public:
+		ExpressionOperator (ExpressionOperatorType id);
+};
+
+// =============================================================================
+//
+class ExpressionValue final : public ExpressionSymbol
+{
+	PROPERTY (public, int,			value,		setValue,		STOCK_WRITE)
+	PROPERTY (public, DataBuffer*,	buffer,		setBuffer,		STOCK_WRITE)
+	PROPERTY (public, DataType,		valueType,	setValueType,	STOCK_WRITE)
+
+	public:
+		ExpressionValue (DataType valuetype);
+		~ExpressionValue();
+
+		void					convertToBuffer();
+
+		inline ExpressionValue* clone() const
+		{
+			return new ExpressionValue (*this);
+		}
+
+		inline bool isConstexpr() const
+		{
+			return buffer() == null;
+		}
+};
+
+// =============================================================================
+//
+// This class represents a ":" in the expression. It serves as the colon for the
+// ternary ?: OPER_erator. It's not an OPER_erand nor is an OPER_erator, nor can we just
+// skip it so it is its own thing here.
+//
+class ExpressionColon final : public ExpressionSymbol
+{
+	public:
+		ExpressionColon() :
+			ExpressionSymbol (EXPRSYM_Colon) {}
+};
+
+#endif // BOTC_EXPRESSION_H

mercurial