499 lines
16 KiB
C++
499 lines
16 KiB
C++
|
|
#ifndef PORYGONLANG_BOUNDSTATEMENT_HPP
|
|
#define PORYGONLANG_BOUNDSTATEMENT_HPP
|
|
#include <utility>
|
|
#include <vector>
|
|
#include "../BoundExpressions/BoundExpression.hpp"
|
|
#include "../BoundVariables/BoundVariableKey.hpp"
|
|
|
|
|
|
using namespace std;
|
|
|
|
namespace Porygon::Binder {
|
|
enum class BoundStatementKind : uint8_t {
|
|
Bad,
|
|
Break,
|
|
Script,
|
|
Block,
|
|
Expression,
|
|
Assignment,
|
|
IndexAssignment,
|
|
FunctionDeclaration,
|
|
Return,
|
|
Conditional,
|
|
NumericalFor,
|
|
GenericFor,
|
|
While,
|
|
};
|
|
|
|
class BoundStatement {
|
|
public:
|
|
[[nodiscard]]
|
|
virtual BoundStatementKind GetKind() const = 0;
|
|
|
|
virtual ~BoundStatement() = default;
|
|
|
|
virtual void GetTreeString(std::stringstream& stream, size_t indents) const = 0;
|
|
};
|
|
|
|
class BoundBadStatement : public BoundStatement {
|
|
public:
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Bad;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const final{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "BadStatement";
|
|
}
|
|
};
|
|
|
|
class BoundBreakStatement : public BoundStatement {
|
|
public:
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Break;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const final{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "BreakStatement";
|
|
}
|
|
};
|
|
|
|
class BoundBlockStatement : public BoundStatement {
|
|
const vector<const BoundStatement *> _statements;
|
|
public:
|
|
explicit BoundBlockStatement(vector<const BoundStatement *> statements)
|
|
: _statements(std::move(statements)) {
|
|
}
|
|
|
|
~BoundBlockStatement() override {
|
|
for (auto s : _statements) {
|
|
delete s;
|
|
}
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const override {
|
|
return BoundStatementKind::Block;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const vector<const BoundStatement *> *GetStatements() const {
|
|
return &_statements;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "BlockStatement";
|
|
for (auto s : _statements){
|
|
stream << endl;
|
|
s->GetTreeString(stream, indents + 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
class BoundScriptStatement : public BoundBlockStatement {
|
|
const int _localVariableCount;
|
|
public:
|
|
explicit BoundScriptStatement(vector<const BoundStatement *> statements, int localVariableCount)
|
|
: BoundBlockStatement(std::move(statements)),
|
|
_localVariableCount(localVariableCount) {
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Script;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline int GetLocalVariableCount() const {
|
|
return _localVariableCount;
|
|
}
|
|
};
|
|
|
|
class BoundExpressionStatement : public BoundStatement {
|
|
const BoundExpression *_expression;
|
|
public:
|
|
explicit BoundExpressionStatement(BoundExpression *expression)
|
|
: _expression(expression) {
|
|
_expression = expression;
|
|
}
|
|
|
|
~BoundExpressionStatement() final {
|
|
delete _expression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Expression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetExpression() const {
|
|
return _expression;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "ExpressionStatement" << endl;
|
|
_expression->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
|
|
class BoundAssignmentStatement : public BoundStatement {
|
|
const BoundVariableKey *_key;
|
|
const BoundExpression *_expression;
|
|
public:
|
|
BoundAssignmentStatement(const BoundVariableKey *key, BoundExpression *expression)
|
|
: _key(key), _expression(expression) {
|
|
}
|
|
|
|
~BoundAssignmentStatement() final {
|
|
delete _key;
|
|
delete _expression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Assignment;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundVariableKey *GetKey() const {
|
|
return _key;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetExpression() const {
|
|
return _expression;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Assignment -> " << _key->GetIdentifier()->GetString() << endl;
|
|
_expression->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
|
|
class BoundIndexAssignmentStatement : public BoundStatement {
|
|
const BoundExpression *_indexExpression;
|
|
const BoundExpression *_valueExpression;
|
|
public:
|
|
BoundIndexAssignmentStatement(const BoundExpression *index, BoundExpression *value)
|
|
: _indexExpression(index), _valueExpression(value) {
|
|
}
|
|
|
|
~BoundIndexAssignmentStatement() final {
|
|
delete _indexExpression;
|
|
delete _valueExpression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::IndexAssignment;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetIndexExpression() const {
|
|
return _indexExpression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetValueExpression() const {
|
|
return _valueExpression;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "IndexAssignment" << endl;
|
|
_indexExpression->GetTreeString(stream, indents + 1);
|
|
stream << endl;
|
|
_valueExpression->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
|
|
class BoundReturnStatement : public BoundStatement {
|
|
const BoundExpression *_expression;
|
|
public:
|
|
explicit BoundReturnStatement(BoundExpression *expression)
|
|
: _expression(expression) {
|
|
}
|
|
|
|
~BoundReturnStatement() final {
|
|
delete _expression;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Return;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetExpression() const {
|
|
return _expression;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "ReturnStatement" << endl;
|
|
if (_expression != nullptr){
|
|
_expression->GetTreeString(stream, indents + 1);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
class BoundConditionalStatement : public BoundStatement {
|
|
const BoundExpression *_condition;
|
|
const BoundStatement *_block;
|
|
const BoundStatement *_elseStatement;
|
|
public:
|
|
explicit BoundConditionalStatement(BoundExpression *condition, BoundStatement *block, BoundStatement *next)
|
|
: _condition(condition), _block(block), _elseStatement(next) {
|
|
}
|
|
|
|
~BoundConditionalStatement() final {
|
|
delete _condition;
|
|
delete _block;
|
|
delete _elseStatement;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::Conditional;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression *GetCondition() const {
|
|
return _condition;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundStatement *GetBlock() const {
|
|
return _block;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundStatement *GetElseStatement() const {
|
|
return _elseStatement;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "ConditionalStatement" << endl;
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Condition:" << endl;
|
|
_condition->GetTreeString(stream, indents + 1);
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "If True:" << endl;
|
|
_block->GetTreeString(stream, indents + 1);
|
|
if (_elseStatement != nullptr){
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Else:" << endl;
|
|
_elseStatement->GetTreeString(stream, indents + 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
class BoundNumericalForStatement : public BoundStatement {
|
|
const BoundVariableKey* _identifier;
|
|
const BoundExpression *_start;
|
|
const BoundExpression *_end;
|
|
const BoundExpression *_step;
|
|
|
|
const BoundStatement *_block;
|
|
public:
|
|
explicit BoundNumericalForStatement(const BoundVariableKey* identifier, const BoundExpression *start,
|
|
const BoundExpression *end, const BoundExpression *step,
|
|
const BoundStatement *block)
|
|
: _identifier(identifier), _start(start), _end(end), _step(step), _block(block) {
|
|
}
|
|
|
|
~BoundNumericalForStatement() final {
|
|
delete _identifier;
|
|
delete _start;
|
|
delete _end;
|
|
delete _step;
|
|
delete _block;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::NumericalFor;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundVariableKey* GetIdentifier() const{
|
|
return _identifier;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression* GetStart() const{
|
|
return _start;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression* GetEnd() const{
|
|
return _end;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression* GetStep() const{
|
|
return _step;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundStatement* GetBlock() const{
|
|
return _block;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "NumericForLoopStatement" << endl;
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Start:" << endl;
|
|
_start->GetTreeString(stream, indents + 1);
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "End:" << endl;
|
|
_end->GetTreeString(stream, indents + 1);
|
|
if (_step != nullptr){
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Step:" << endl;
|
|
_step->GetTreeString(stream, indents + 1);
|
|
}
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Do:" << endl;
|
|
_block->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
|
|
class BoundGenericForStatement : public BoundStatement {
|
|
const BoundVariableKey* _keyIdentifier;
|
|
const BoundVariableKey* _valueIdentifier;
|
|
const BoundExpression* _iterator;
|
|
|
|
const BoundStatement *_block;
|
|
public:
|
|
explicit BoundGenericForStatement(const BoundVariableKey *keyIdentifier,
|
|
const BoundVariableKey *valueIdentifier,
|
|
const BoundExpression *iterator, const BoundStatement *block)
|
|
: _keyIdentifier(keyIdentifier), _valueIdentifier(valueIdentifier), _iterator(iterator), _block(block) {
|
|
}
|
|
|
|
~BoundGenericForStatement() final {
|
|
delete _keyIdentifier;
|
|
delete _valueIdentifier;
|
|
delete _iterator;
|
|
delete _block;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::GenericFor;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundVariableKey* GetKeyIdentifier() const{
|
|
return _keyIdentifier;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundVariableKey* GetValueIdentifier() const{
|
|
return _valueIdentifier;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression* GetIterator() const{
|
|
return _iterator;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundStatement* GetBlock() const{
|
|
return _block;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "GenericForLoopStatement" << endl;
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Key: " << _keyIdentifier->GetIdentifier()->GetString().get() << endl;
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Value: " << _valueIdentifier->GetIdentifier()->GetString().get() << endl;
|
|
stream << "Iterator: " << endl;
|
|
_iterator->GetTreeString(stream, indents + 1);
|
|
stream << endl;
|
|
_block->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
|
|
class BoundWhileStatement : public BoundStatement {
|
|
const BoundExpression* _condition;
|
|
const BoundStatement *_block;
|
|
public:
|
|
explicit BoundWhileStatement(const BoundExpression *condition, const BoundStatement *block)
|
|
: _condition(condition), _block(block) {
|
|
}
|
|
|
|
~BoundWhileStatement() final {
|
|
delete _condition;
|
|
delete _block;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline BoundStatementKind GetKind() const final {
|
|
return BoundStatementKind::While;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundExpression* GetCondition() const{
|
|
return _condition;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline const BoundStatement* GetBlock() const{
|
|
return _block;
|
|
}
|
|
|
|
void GetTreeString(std::stringstream& stream, size_t indents) const override{
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "ConditionalStatement" << endl;
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "Condition:" << endl;
|
|
_condition->GetTreeString(stream, indents + 1);
|
|
for (size_t i = 0; i < indents; i++)
|
|
stream << "\t";
|
|
stream << "While True:" << endl;
|
|
_block->GetTreeString(stream, indents + 1);
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
#include "BoundFunctionDeclarationStatement.hpp"
|
|
|
|
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP
|