src/Expression.h

Sun, 23 Feb 2014 17:45:34 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 23 Feb 2014 17:45:34 +0200
changeset 112
def56932f938
parent 108
6409ece8297c
child 115
9be16e1c1e44
permissions
-rw-r--r--

- changed the PROPERTY macro to a simper version and brought some refactoring with it

#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*		Result();

	private:
		BotscriptParser*		mParser;
		Lexer*					mLexer;
		SymbolList				mSymbols;
		DataType				mType;
		String					mBadTokenText;

		ExpressionValue*		Evaluate(); // Process the expression and yield a result
		ExpressionSymbol*		ParseSymbol();
		String					TokenString();
		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) :
			mType (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