PorygonLang/src/Binder/BoundStatements/BoundStatement.hpp

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