#ifndef PORYGONLANG_BOUNDEXPRESSION_HPP #define PORYGONLANG_BOUNDEXPRESSION_HPP #include #include #include #include "../../ScriptType.hpp" #include "../BoundOperators.hpp" #include "../BoundVariables/BoundVariableKey.hpp" #include "../../FunctionScriptType.hpp" using namespace std; namespace Porygon::Binder { enum class BoundExpressionKind : u_int8_t { Bad, LiteralInteger, LiteralFloat, LiteralString, LiteralBool, Variable, Unary, Binary, FunctionCall, Index, PeriodIndex, NumericalTable, Table, }; class BoundExpression { const unsigned int _start; const unsigned int _length; const shared_ptr _type; public: BoundExpression(unsigned int start, unsigned int length, shared_ptr type) : _start(start), _length(length), _type(std::move(type)) { } virtual ~BoundExpression() = default; [[nodiscard]] virtual BoundExpressionKind GetKind() const = 0; [[nodiscard]] virtual const std::shared_ptr &GetType() const { return _type; }; [[nodiscard]] inline unsigned int GetStartPosition() const { return _start; } [[nodiscard]] inline unsigned int GetLength() const { return _length; } }; class BoundBadExpression : public BoundExpression { public: BoundBadExpression(unsigned int start, unsigned int length) : BoundExpression(start, length, make_shared( TypeClass::Error)) {} [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::Bad; } }; class BoundLiteralIntegerExpression : public BoundExpression { const long _value; public: BoundLiteralIntegerExpression(long value, unsigned int start, unsigned int length) : BoundExpression(start, length, make_shared(true, false)), _value(value) { } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::LiteralInteger; } [[nodiscard]] inline long GetValue() const { return _value; } }; class BoundLiteralFloatExpression : public BoundExpression { const double _value; public: BoundLiteralFloatExpression(double value, unsigned int start, unsigned int length) : BoundExpression(start, length, make_shared(true, true)), _value(value) { } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::LiteralFloat; } [[nodiscard]] inline double GetValue() const { return _value; } }; class BoundLiteralStringExpression : public BoundExpression { const u16string _value; public: BoundLiteralStringExpression(const u16string &value, unsigned int start, unsigned int length) : BoundExpression(start, length, make_shared(true, Utilities::HashedString::ConstHash(value.c_str()))), _value(value) { } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::LiteralString; } [[nodiscard]] inline const u16string* GetValue() const { return &_value; } }; class BoundLiteralBoolExpression : public BoundExpression { const bool _value; public: BoundLiteralBoolExpression(bool value, unsigned int start, unsigned int length) : BoundExpression(start, length, make_shared(TypeClass::Bool)), _value(value) { } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::LiteralBool; } [[nodiscard]] inline bool GetValue() const { return _value; } }; class BoundVariableExpression : public BoundExpression { const BoundVariableKey *_key; public: BoundVariableExpression(BoundVariableKey *key, const shared_ptr& type, unsigned int start, unsigned int length) : BoundExpression(start, length, type), _key(key) { } ~BoundVariableExpression() override { delete _key; } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::Variable; } [[nodiscard]] inline const BoundVariableKey *GetKey() const { return _key; } }; class BoundBinaryExpression : public BoundExpression { const BoundExpression *_left; const BoundExpression *_right; const BoundBinaryOperation _operation; public: BoundBinaryExpression(BoundExpression *left, BoundExpression *right, BoundBinaryOperation op, shared_ptr result, unsigned int start, unsigned int length) : BoundExpression(start, length, std::move(result)), _left(left), _right(right), _operation(op) { } ~BoundBinaryExpression() final { delete _left; delete _right; } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::Binary; } [[nodiscard]] inline const BoundExpression *GetLeft() const { return _left; } [[nodiscard]] inline const BoundExpression *GetRight() const { return _right; } [[nodiscard]] inline BoundBinaryOperation GetOperation() const { return _operation; } }; class BoundUnaryExpression : public BoundExpression { const BoundExpression *_operand; const BoundUnaryOperation _operation; public: BoundUnaryExpression(BoundExpression *operand, BoundUnaryOperation op, shared_ptr result, unsigned int start, unsigned int length) : BoundExpression(start, length, std::move(result)), _operand(operand), _operation(op) { } ~BoundUnaryExpression() final { delete _operand; } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::Unary; } [[nodiscard]] inline const BoundExpression *GetOperand() const { return _operand; } [[nodiscard]] inline BoundUnaryOperation GetOperation() const { return _operation; } }; class BoundIndexExpression : public BoundExpression { const BoundExpression *_indexableExpression; const BoundExpression *_indexExpression; public: BoundIndexExpression(BoundExpression *indexableExpression, BoundExpression *indexExpression, shared_ptr result, unsigned int start, unsigned int length) : BoundExpression(start, length, std::move(result)), _indexableExpression(indexableExpression), _indexExpression(indexExpression) {} ~BoundIndexExpression() final { delete _indexableExpression; delete _indexExpression; } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::Index; } [[nodiscard]] inline const BoundExpression *GetIndexableExpression() const { return _indexableExpression; } [[nodiscard]] inline const BoundExpression *GetIndexExpression() const { return _indexExpression; } }; class BoundPeriodIndexExpression : public BoundExpression { const BoundExpression *_indexableExpression; const Utilities::HashedString _index; public: BoundPeriodIndexExpression(BoundExpression *indexableExpression, const Utilities::HashedString& index, shared_ptr result, unsigned int start, unsigned int length) : BoundExpression(start, length, std::move(result)), _indexableExpression(indexableExpression), _index(index) {} ~BoundPeriodIndexExpression() final { delete _indexableExpression; } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::PeriodIndex; } [[nodiscard]] inline const BoundExpression *GetIndexableExpression() const { return _indexableExpression; } [[nodiscard]] inline const Utilities::HashedString* GetIndex() const { return &_index; } }; class BoundNumericalTableExpression : public BoundExpression { const vector _expressions; public: BoundNumericalTableExpression(vector expressions, shared_ptr type, unsigned int start, unsigned int length) : BoundExpression(start, length, std::move(type)), _expressions(std::move(expressions)) {} ~BoundNumericalTableExpression() final { for (auto e: _expressions) { delete e; } } [[nodiscard]] inline BoundExpressionKind GetKind() const final { return BoundExpressionKind::NumericalTable; } [[nodiscard]] inline const vector *GetExpressions() const { return &_expressions; } }; } #endif //PORYGONLANG_BOUNDEXPRESSION_HPP