#ifndef MALACHSCRIPT_PARSEDSTATEMENT_HPP #define MALACHSCRIPT_PARSEDSTATEMENT_HPP #include #include #include #include #include #include "../../CoreData/AccessModifier.hpp" #include "../../CoreData/ClassAttr.hpp" #include "../../CoreData/FuncAttr.hpp" #include "../../CoreData/Identifier.hpp" #include "../../CoreData/TypeMod.hpp" #include "../../TextSpan.hpp" #include "ParsedStatementKind.hpp" namespace MalachScript::Parser { class ParsedStatement { ScriptTextSpan _span; public: ParsedStatement(ScriptTextSpan span) : _span(span) {} virtual ~ParsedStatement() = default; [[nodiscard]] virtual ParsedStatementKind GetKind() const noexcept = 0; [[nodiscard]] inline const ScriptTextSpan& GetSpan() const noexcept { return _span; } }; template class ParsedStatementImpl : public ParsedStatement { public: ParsedStatementImpl(ScriptTextSpan span) : ParsedStatement(span) {} [[nodiscard]] inline ParsedStatementKind GetKind() const noexcept final { return kind; } }; class ParsedScriptStatement : public ParsedStatementImpl { std::vector> _statements; public: ParsedScriptStatement(ScriptTextSpan span, const std::vector& statements) : ParsedStatementImpl(span), _statements(statements.size()) { for (size_t i = 0; i < statements.size(); i++) _statements[i] = std::unique_ptr(statements[i]); } [[nodiscard]] inline const std::vector>& GetStatements() const noexcept { return _statements; } }; class ParsedClassStatement : public ParsedStatementImpl { public: ParsedClassStatement(ScriptTextSpan span, ClassAttr classAttr, Identifier identifier, const std::vector& inherits, const std::vector& body) : ParsedStatementImpl(span), _classAttr(classAttr), _identifier(identifier), _inherits(inherits), _body(body.size()) { for (size_t i = 0; i < body.size(); i++) { _body[i] = std::unique_ptr(body[i]); } } [[nodiscard]] ClassAttr GetClassAttr() const noexcept { return _classAttr; } [[nodiscard]] const Identifier& GetIdentifier() const noexcept { return _identifier; } [[nodiscard]] const std::vector& GetInherits() const noexcept { return _inherits; } [[nodiscard]] const std::vector>& GetBody() const noexcept { return _body; } private: ClassAttr _classAttr; Identifier _identifier; std::vector _inherits; std::vector> _body; }; class ParsedTypeDefStatement : public ParsedStatementImpl { Identifier _defineFrom; Identifier _defineTo; public: ParsedTypeDefStatement(ScriptTextSpan span, const Identifier& defineFrom, const Identifier& defineTo) : ParsedStatementImpl(span), _defineFrom(defineFrom), _defineTo(defineTo) {} [[nodiscard]] inline const Identifier& GetDefineFrom() const noexcept { return _defineFrom; } [[nodiscard]] inline const Identifier& GetDefineTo() const noexcept { return _defineTo; } }; class ParsedNamespaceStatement : public ParsedStatementImpl { Identifier _identifier; std::unique_ptr _parsedScript; public: ParsedNamespaceStatement(ScriptTextSpan span, const Identifier& identifier, const ParsedScriptStatement* script) : ParsedStatementImpl(span), _identifier(identifier), _parsedScript(script) {} [[nodiscard]] inline const Identifier& GetIdentifier() const noexcept { return _identifier; } [[nodiscard]] inline const std::unique_ptr& GetScript() const noexcept { return _parsedScript; } }; class ParsedTypeStatement : public ParsedStatementImpl { bool _isConst; bool _isArray; bool _isHandle; ScopedIdentifier _scopedIdentifier; public: ParsedTypeStatement(ScriptTextSpan span, bool isConst, bool isArray, bool isHandle, const ScopedIdentifier& scopedIdentifier) : ParsedStatementImpl(span), _isConst(isConst), _isArray(isArray), _isHandle(isHandle), _scopedIdentifier(scopedIdentifier) {} [[nodiscard]] inline bool IsConst() const noexcept { return _isConst; } [[nodiscard]] inline bool IsArray() const noexcept { return _isArray; } [[nodiscard]] inline bool IsHandle() const noexcept { return _isHandle; } [[nodiscard]] inline const ScopedIdentifier& GetScopedIdentifier() const noexcept { return _scopedIdentifier; } }; class ParsedParamListStatement : public ParsedStatementImpl { public: class ParsedParameter { private: std::unique_ptr _typeStatement = nullptr; TypeMod _typeMod = TypeMod::None; Identifier _identifier; std::unique_ptr _defaultExpression = nullptr; public: ParsedParameter(const ParsedTypeStatement* typeStatement, TypeMod typeMod, const Identifier& identifier, const ParsedStatement* defaultExpression) : _typeStatement(typeStatement), _typeMod(typeMod), _identifier(identifier), _defaultExpression(defaultExpression){}; [[nodiscard]] std::unique_ptr& GetTypeStatement() noexcept { return _typeStatement; } [[nodiscard]] const std::unique_ptr& GetTypeStatement() const noexcept { return _typeStatement; } [[nodiscard]] TypeMod& GetTypeMod() noexcept { return _typeMod; } [[nodiscard]] const TypeMod& GetTypeMod() const noexcept { return _typeMod; } [[nodiscard]] Identifier& GetIdentifier() noexcept { return _identifier; } [[nodiscard]] const Identifier& GetIdentifier() const noexcept { return _identifier; } [[nodiscard]] std::unique_ptr& GetDefaultExpression() noexcept { return _defaultExpression; } [[nodiscard]] const std::unique_ptr& GetDefaultExpression() const noexcept { return _defaultExpression; } }; private: std::vector> _parameters; public: ParsedParamListStatement(ScriptTextSpan span, const std::vector& parameters) : ParsedStatementImpl(span), _parameters(parameters.size()) { for (size_t i = 0; i < parameters.size(); i++) { _parameters[i] = std::unique_ptr(parameters[i]); } }; [[nodiscard]] const std::vector>& GetParameters() const noexcept { return _parameters; } }; class ParsedFuncStatement : public ParsedStatementImpl { private: bool _isShared; bool _isExternal; AccessModifier _access; std::unique_ptr _type; bool _returnsReference; Identifier _identifier; std::unique_ptr _paramList; bool _isConst; FuncAttr _funcAttr; std::unique_ptr _statBlock; public: ParsedFuncStatement(const ScriptTextSpan& span, bool isShared, bool isExternal, AccessModifier access, const ParsedStatement* type, bool returnsReference, const Identifier& identifier, const ParsedStatement* paramList, bool isConst, FuncAttr funcAttr, const ParsedStatement* statBlock) : ParsedStatementImpl(span), _isShared(isShared), _isExternal(isExternal), _access(access), _type(type), _returnsReference(returnsReference), _identifier(identifier), _paramList(paramList), _isConst(isConst), _funcAttr(funcAttr), _statBlock(statBlock) {} [[nodiscard]] inline bool IsShared() const noexcept { return _isShared; } [[nodiscard]] inline bool IsExternal() const noexcept { return _isExternal; } [[nodiscard]] inline AccessModifier GetAccess() const noexcept { return _access; } [[nodiscard]] inline const std::unique_ptr& GetTypeStatement() const noexcept { return _type; } [[nodiscard]] inline bool ReturnsReference() const noexcept { return _returnsReference; } [[nodiscard]] inline const Identifier& GetIdentifier() const noexcept { return _identifier; } [[nodiscard]] inline const std::unique_ptr& GetParamList() const noexcept { return _paramList; } [[nodiscard]] inline bool IsConst() const noexcept { return _isConst; } [[nodiscard]] inline FuncAttr GetFuncAttr() const noexcept { return _funcAttr; } [[nodiscard]] inline const std::unique_ptr& GetStatBlock() const noexcept { return _statBlock; } }; class ParsedVirtPropStatement : public ParsedStatementImpl { public: ParsedVirtPropStatement(const ScriptTextSpan& span, AccessModifier access, const ParsedStatement* returnType, bool isReturnTypeRef, Identifier identifier, bool hasGet, bool getConst, FuncAttr getAttr, const ParsedStatement* getStatement, bool hasSet, bool setConst, FuncAttr setAttr, const ParsedStatement* setStatement) : ParsedStatementImpl(span), _access(access), _returnType(returnType), _isReturnTypeRef(isReturnTypeRef), _identifier(identifier), _hasGet(hasGet), _getConst(getConst), _getAttr(getAttr), _getStatement(getStatement), _hasSet(hasSet), _setConst(setConst), _setAttr(setAttr), _setStatement(setStatement) {} [[nodiscard]] inline AccessModifier GetAccess() const noexcept { return _access; } [[nodiscard]] inline const std::unique_ptr& GetReturnType() const noexcept { return _returnType; } [[nodiscard]] inline bool IsReturnTypeRef() const noexcept { return _isReturnTypeRef; } [[nodiscard]] inline const Identifier& GetIdentifier() const noexcept { return _identifier; } [[nodiscard]] inline bool HasGet() const noexcept { return _hasGet; } [[nodiscard]] inline bool IsGetConst() const noexcept { return _getConst; } [[nodiscard]] inline FuncAttr GetGetFuncAttr() const noexcept { return _getAttr; } [[nodiscard]] inline const std::unique_ptr& GetGetStatement() const noexcept { return _getStatement; } [[nodiscard]] inline bool HasSet() const noexcept { return _hasSet; } [[nodiscard]] inline bool IsSetConst() const noexcept { return _setConst; } [[nodiscard]] inline FuncAttr GetSetFuncAttr() const noexcept { return _setAttr; } [[nodiscard]] inline const std::unique_ptr& GetSetStatement() const noexcept { return _setStatement; } private: AccessModifier _access; std::unique_ptr _returnType; bool _isReturnTypeRef; Identifier _identifier; bool _hasGet = false; bool _getConst = false; FuncAttr _getAttr = FuncAttr::None; std::unique_ptr _getStatement; bool _hasSet = false; bool _setConst = false; FuncAttr _setAttr = FuncAttr::None; std::unique_ptr _setStatement; }; class ParsedStatBlockStatement : public ParsedStatementImpl { public: ParsedStatBlockStatement(const ScriptTextSpan& span, const std::vector& statements) : ParsedStatementImpl(span), _statements(statements.size()) { for (size_t i = 0; i < statements.size(); i++) { _statements[i] = std::unique_ptr(statements[i]); } } [[nodiscard]] const std::vector>& GetStatements() const noexcept { return _statements; } private: std::vector> _statements; }; class ParsedVarStatement : public ParsedStatementImpl { public: ParsedVarStatement(const ScriptTextSpan& span, AccessModifier access, const ParsedTypeStatement* typeStatement, Identifier identifier) : ParsedStatementImpl(span), _access(access), _typeStatement(typeStatement), _identifier(identifier) {} [[nodiscard]] AccessModifier GetAccess() const noexcept { return _access; } [[nodiscard]] const std::unique_ptr& GetTypeStatement() const noexcept { return _typeStatement; } [[nodiscard]] const Identifier& GetIdentifier() const noexcept { return _identifier; } private: AccessModifier _access; std::unique_ptr _typeStatement; Identifier _identifier; }; class ParsedIfStatement : public ParsedStatementImpl { public: ParsedIfStatement(const ScriptTextSpan& span, const ParsedStatement* condition, const ParsedStatement* body, const ParsedStatement* elseStatement) : ParsedStatementImpl(span), _condition(condition), _body(body), _elseStatement(elseStatement) {} [[nodiscard]] inline const std::unique_ptr& GetCondition() const noexcept { return _condition; } [[nodiscard]] inline const std::unique_ptr& GetBody() const noexcept { return _body; } [[nodiscard]] inline const std::unique_ptr& GetElseStatement() const noexcept { return _elseStatement; } private: std::unique_ptr _condition; std::unique_ptr _body; std::unique_ptr _elseStatement; }; template class ParsedBinaryStatement : public ParsedStatementImpl { public: ParsedBinaryStatement(const ScriptTextSpan& span, const ParsedStatement* leftHand, TOperator op, const ParsedStatement* rightHand) : ParsedStatementImpl(span), _leftHand(leftHand), _operator(op), _rightHand(rightHand) {} [[nodiscard]] inline size_t GetOperatorType() const noexcept { return typeid(TOperator).hash_code(); } private: std::unique_ptr _leftHand; TOperator _operator; std::unique_ptr _rightHand; }; class ParsedVoidStatement : public ParsedStatementImpl { public: ParsedVoidStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {} }; template class ParsedLiteralStatement : public ParsedStatementImpl { public: ParsedLiteralStatement(const ScriptTextSpan& span, T literalValue) : ParsedStatementImpl(span), _literalValue(literalValue) {} [[nodiscard]] inline const T& GetLiteralValue() const noexcept { return _literalValue; } private: T _literalValue; }; class ParsedReturnStatement : public ParsedStatementImpl { public: ParsedReturnStatement(const ScriptTextSpan& span, const ParsedStatement* statement) : ParsedStatementImpl(span), _statement(statement) {} private: std::unique_ptr _statement; }; class ParsedVarAccessStatement : public ParsedStatementImpl { public: ParsedVarAccessStatement(const ScriptTextSpan& span, std::vector scope) : ParsedStatementImpl(span), _scope(std::move(scope)) {} private: std::vector _scope; }; class ParsedIncrementStatement : public ParsedStatementImpl { public: ParsedIncrementStatement(const ScriptTextSpan& span, const ParsedStatement* statement) : ParsedStatementImpl(span), _statement(statement) {} private: std::unique_ptr _statement; }; class ParsedDecrementStatement : public ParsedStatementImpl { public: ParsedDecrementStatement(const ScriptTextSpan& span, const ParsedStatement* statement) : ParsedStatementImpl(span), _statement(statement) {} private: std::unique_ptr _statement; }; class ParsedContinueStatement : public ParsedStatementImpl { public: ParsedContinueStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {} }; class ParsedBreakStatement : public ParsedStatementImpl { public: ParsedBreakStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {} }; class ParsedForStatement : public ParsedStatementImpl { public: ParsedForStatement(const ScriptTextSpan& span, const ParsedStatement* init, const ParsedStatement* condition, std::vector increment, const ParsedStatement* body) : ParsedStatementImpl(span), _init(init), _condition(condition), _increment(increment.size()), _body(body) { for (size_t i = 0; i < increment.size(); i++) { _increment[i] = std::unique_ptr(increment[i]); } } inline const std::unique_ptr& GetInit() const noexcept { return _init; } inline const std::unique_ptr& GetCondition() const noexcept { return _condition; } inline const std::vector>& GetIncrement() const noexcept { return _increment; } inline const std::unique_ptr& GetBody() const noexcept { return _body; } private: std::unique_ptr _init; std::unique_ptr _condition; std::vector> _increment; std::unique_ptr _body; }; class ParsedWhileStatement : public ParsedStatementImpl { public: ParsedWhileStatement(const ScriptTextSpan& span, const ParsedStatement* condition, const ParsedStatement* body) : ParsedStatementImpl(span), _condition(condition), _body(body) {} private: std::unique_ptr _condition; std::unique_ptr _body; }; class ParsedDoWhileStatement : public ParsedStatementImpl { public: ParsedDoWhileStatement(const ScriptTextSpan& span, const ParsedStatement* condition, const ParsedStatement* body) : ParsedStatementImpl(span), _condition(condition), _body(body) {} private: std::unique_ptr _condition; std::unique_ptr _body; }; class ParsedTryStatement : public ParsedStatementImpl { public: ParsedTryStatement(const ScriptTextSpan& span, const ParsedStatement* tryStatement, const ParsedStatement* catchStatement) : ParsedStatementImpl(span), _tryStatement(tryStatement), _catchStatement(catchStatement) {} private: std::unique_ptr _tryStatement; std::unique_ptr _catchStatement; }; class ParsedSwitchStatement : public ParsedStatementImpl { public: ParsedSwitchStatement(const ScriptTextSpan& span, const ParsedStatement* expression, const std::vector& cases) : ParsedStatementImpl(span), _expression(expression), _cases(cases.size()) { for (size_t i = 0; i < cases.size(); i++) { _cases[i] = std::unique_ptr(cases[i]); } } private: std::unique_ptr _expression; std::vector> _cases; }; class ParsedCaseStatement : public ParsedStatementImpl { public: ParsedCaseStatement(const ScriptTextSpan& span, const ParsedStatement* expression, const std::vector& statements) : ParsedStatementImpl(span), _expression(expression), _statements(statements.size()) { for (size_t i = 0; i < statements.size(); i++) { _statements[i] = std::unique_ptr(statements[i]); } } private: std::unique_ptr _expression; std::vector> _statements; }; } #endif // MALACHSCRIPT_PARSEDSTATEMENT_HPP