2019-05-21 18:59:26 +00:00
|
|
|
#ifndef PORYGONLANG_BOUNDEXPRESSION_HPP
|
|
|
|
#define PORYGONLANG_BOUNDEXPRESSION_HPP
|
|
|
|
|
|
|
|
#include <string>
|
2019-06-01 17:20:31 +00:00
|
|
|
#include <memory>
|
2019-06-09 18:15:09 +00:00
|
|
|
#include <utility>
|
2019-07-28 10:58:38 +00:00
|
|
|
#include "../../ScriptTypes/ScriptType.hpp"
|
2019-05-21 20:15:51 +00:00
|
|
|
#include "../BoundOperators.hpp"
|
2019-05-30 13:23:48 +00:00
|
|
|
#include "../BoundVariables/BoundVariableKey.hpp"
|
2019-05-21 18:59:26 +00:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2019-06-17 16:35:12 +00:00
|
|
|
namespace Porygon::Binder {
|
2019-08-11 14:05:14 +00:00
|
|
|
enum class BoundExpressionKind : uint8_t {
|
2019-06-17 16:35:12 +00:00
|
|
|
Bad,
|
|
|
|
|
|
|
|
LiteralInteger,
|
|
|
|
LiteralFloat,
|
|
|
|
LiteralString,
|
|
|
|
LiteralBool,
|
|
|
|
Variable,
|
|
|
|
|
|
|
|
Unary,
|
|
|
|
Binary,
|
|
|
|
FunctionCall,
|
|
|
|
Index,
|
|
|
|
PeriodIndex,
|
|
|
|
NumericalTable,
|
|
|
|
Table,
|
2019-08-10 14:45:15 +00:00
|
|
|
Require,
|
2019-08-18 11:17:53 +00:00
|
|
|
ImplicitCast,
|
2019-05-21 18:59:26 +00:00
|
|
|
};
|
|
|
|
|
2019-06-17 16:35:12 +00:00
|
|
|
class BoundExpression {
|
|
|
|
const unsigned int _start;
|
|
|
|
const unsigned int _length;
|
2019-07-25 15:23:54 +00:00
|
|
|
const shared_ptr<const ScriptType> _type;
|
2019-06-17 16:35:12 +00:00
|
|
|
public:
|
2019-07-25 15:23:54 +00:00
|
|
|
BoundExpression(unsigned int start, unsigned int length, shared_ptr<const ScriptType> type)
|
2019-06-17 16:35:12 +00:00
|
|
|
: _start(start),
|
|
|
|
_length(length),
|
|
|
|
_type(std::move(type)) {
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~BoundExpression() = default;
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
virtual BoundExpressionKind GetKind() const = 0;
|
2019-06-17 16:35:12 +00:00
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
virtual const std::shared_ptr<const ScriptType> &GetType() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _type;
|
|
|
|
};
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline unsigned int GetStartPosition() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _start;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline unsigned int GetLength() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _length;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundBadExpression : public BoundExpression {
|
|
|
|
public:
|
|
|
|
BoundBadExpression(unsigned int start, unsigned int length) : BoundExpression(start, length,
|
|
|
|
make_shared<ScriptType>(
|
|
|
|
TypeClass::Error)) {}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::Bad;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundLiteralIntegerExpression : public BoundExpression {
|
2019-08-18 08:30:58 +00:00
|
|
|
const int64_t _value;
|
2019-06-17 16:35:12 +00:00
|
|
|
public:
|
2019-08-18 08:30:58 +00:00
|
|
|
BoundLiteralIntegerExpression(int64_t value, unsigned int start, unsigned int length)
|
2019-06-17 16:35:12 +00:00
|
|
|
: BoundExpression(start, length, make_shared<NumericScriptType>(true, false)),
|
|
|
|
_value(value) {
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::LiteralInteger;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-08-18 08:30:58 +00:00
|
|
|
inline int64_t GetValue() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundLiteralFloatExpression : public BoundExpression {
|
|
|
|
const double _value;
|
|
|
|
public:
|
|
|
|
BoundLiteralFloatExpression(double value, unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, make_shared<NumericScriptType>(true, true)),
|
|
|
|
_value(value) {
|
|
|
|
}
|
2019-06-09 18:15:09 +00:00
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::LiteralFloat;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline double GetValue() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
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<StringScriptType>(true, Utilities::HashedString::ConstHash(value.c_str()))),
|
|
|
|
_value(value) {
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::LiteralString;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline const u16string* GetValue() const {
|
|
|
|
return &_value;
|
2019-06-17 16:35:12 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundLiteralBoolExpression : public BoundExpression {
|
|
|
|
const bool _value;
|
|
|
|
public:
|
|
|
|
BoundLiteralBoolExpression(bool value, unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, make_shared<ScriptType>(TypeClass::Bool)),
|
|
|
|
_value(value) {
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::LiteralBool;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline bool GetValue() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundVariableExpression : public BoundExpression {
|
|
|
|
const BoundVariableKey *_key;
|
|
|
|
public:
|
2019-07-25 15:23:54 +00:00
|
|
|
BoundVariableExpression(BoundVariableKey *key, const shared_ptr<const ScriptType>& type, unsigned int start,
|
2019-06-17 16:35:12 +00:00
|
|
|
unsigned int length)
|
2019-07-25 15:23:54 +00:00
|
|
|
: BoundExpression(start, length, type),
|
2019-06-17 16:35:12 +00:00
|
|
|
_key(key) {
|
|
|
|
}
|
|
|
|
|
|
|
|
~BoundVariableExpression() override {
|
|
|
|
delete _key;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::Variable;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundVariableKey *GetKey() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
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<ScriptType> 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;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::Binary;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetLeft() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _left;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetRight() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _right;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundBinaryOperation GetOperation() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _operation;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundUnaryExpression : public BoundExpression {
|
|
|
|
const BoundExpression *_operand;
|
|
|
|
const BoundUnaryOperation _operation;
|
|
|
|
public:
|
|
|
|
BoundUnaryExpression(BoundExpression *operand, BoundUnaryOperation op, shared_ptr<ScriptType> result,
|
|
|
|
unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, std::move(result)),
|
|
|
|
_operand(operand),
|
|
|
|
_operation(op) {
|
|
|
|
}
|
|
|
|
|
|
|
|
~BoundUnaryExpression() final {
|
|
|
|
delete _operand;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::Unary;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetOperand() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _operand;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundUnaryOperation GetOperation() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _operation;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundIndexExpression : public BoundExpression {
|
|
|
|
const BoundExpression *_indexableExpression;
|
|
|
|
const BoundExpression *_indexExpression;
|
|
|
|
public:
|
|
|
|
BoundIndexExpression(BoundExpression *indexableExpression, BoundExpression *indexExpression,
|
2019-07-25 15:23:54 +00:00
|
|
|
shared_ptr<const ScriptType> result,
|
2019-06-17 16:35:12 +00:00
|
|
|
unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, std::move(result)), _indexableExpression(indexableExpression),
|
|
|
|
_indexExpression(indexExpression) {}
|
|
|
|
|
|
|
|
~BoundIndexExpression() final {
|
|
|
|
delete _indexableExpression;
|
|
|
|
delete _indexExpression;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::Index;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetIndexableExpression() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _indexableExpression;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetIndexExpression() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _indexExpression;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundPeriodIndexExpression : public BoundExpression {
|
|
|
|
const BoundExpression *_indexableExpression;
|
|
|
|
const Utilities::HashedString _index;
|
|
|
|
public:
|
2019-07-25 15:23:54 +00:00
|
|
|
BoundPeriodIndexExpression(BoundExpression *indexableExpression, const Utilities::HashedString& index,
|
|
|
|
shared_ptr<const ScriptType> result,
|
2019-06-17 16:35:12 +00:00
|
|
|
unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, std::move(result)), _indexableExpression(indexableExpression),
|
|
|
|
_index(index) {}
|
|
|
|
|
|
|
|
~BoundPeriodIndexExpression() final {
|
|
|
|
delete _indexableExpression;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::PeriodIndex;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const BoundExpression *GetIndexableExpression() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return _indexableExpression;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline const Utilities::HashedString* GetIndex() const {
|
|
|
|
return &_index;
|
2019-06-17 16:35:12 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundNumericalTableExpression : public BoundExpression {
|
|
|
|
const vector<const BoundExpression *> _expressions;
|
|
|
|
public:
|
2019-07-25 15:23:54 +00:00
|
|
|
BoundNumericalTableExpression(vector<const BoundExpression *> expressions, shared_ptr<const ScriptType> type,
|
2019-06-17 16:35:12 +00:00
|
|
|
unsigned int start, unsigned int length)
|
|
|
|
: BoundExpression(start, length, std::move(type)),
|
|
|
|
_expressions(std::move(expressions)) {}
|
|
|
|
|
|
|
|
~BoundNumericalTableExpression() final {
|
|
|
|
for (auto e: _expressions) {
|
|
|
|
delete e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
2019-06-17 16:35:12 +00:00
|
|
|
return BoundExpressionKind::NumericalTable;
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:23:54 +00:00
|
|
|
[[nodiscard]]
|
2019-07-04 17:08:13 +00:00
|
|
|
inline const vector<const BoundExpression *> *GetExpressions() const {
|
2019-06-17 16:35:12 +00:00
|
|
|
return &_expressions;
|
|
|
|
}
|
|
|
|
};
|
2019-08-10 14:45:15 +00:00
|
|
|
|
2019-08-18 11:17:53 +00:00
|
|
|
class BoundImplicitCastExpression : public BoundExpression {
|
|
|
|
const BoundExpression* _expression;
|
|
|
|
public:
|
|
|
|
BoundImplicitCastExpression(BoundExpression* expression, shared_ptr<const ScriptType> castType)
|
|
|
|
: BoundExpression(expression->GetStartPosition(), expression->GetLength(), castType),
|
|
|
|
_expression(expression)
|
|
|
|
{}
|
|
|
|
|
|
|
|
const BoundExpression* GetExpression() const{
|
|
|
|
return _expression;
|
|
|
|
}
|
|
|
|
|
|
|
|
~BoundImplicitCastExpression() final {
|
|
|
|
delete _expression;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
inline BoundExpressionKind GetKind() const final {
|
|
|
|
return BoundExpressionKind::ImplicitCast;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-17 16:35:12 +00:00
|
|
|
}
|
2019-05-21 18:59:26 +00:00
|
|
|
|
|
|
|
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP
|