src/Expression.h

Mon, 03 Mar 2014 17:02:38 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Mon, 03 Mar 2014 17:02:38 +0200
changeset 117
cc1e14d55047
parent 115
9be16e1c1e44
permissions
-rw-r--r--

- reserved 'constexpr' as a keyword because I know I will need it someday

#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