diff --git a/src/CoreData/ClassAttr.hpp b/src/CoreData/ClassAttr.hpp new file mode 100644 index 0000000..5906eee --- /dev/null +++ b/src/CoreData/ClassAttr.hpp @@ -0,0 +1,25 @@ +#ifndef MALACHSCRIPT_CLASSATTR_HPP +#define MALACHSCRIPT_CLASSATTR_HPP + +namespace MalachScript { + enum class ClassAttr : uint8_t { + None = 0, + Shared = 1 << 1, + Abstract = 1 << 2, + Final = 1 << 3, + External = 1 << 4, + }; + + class ClassAttrHelpers { + public: + constexpr inline static bool Contains(ClassAttr set, ClassAttr flag) { + return (static_cast(set) & static_cast(flag)) != 0; + } + constexpr inline static ClassAttr Set(ClassAttr set, ClassAttr flag) { + return static_cast(static_cast(set) | static_cast(flag)); + } + }; + +} + +#endif // MALACHSCRIPT_CLASSATTR_HPP diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index b83fff0..6cb0bec 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -9,8 +9,8 @@ } #define EXPECT_TOKEN(token, kind) \ - if (token->GetKind() != LexTokenKind::kind) { \ - logError(DiagnosticType::UnexpectedToken, token->GetSpan()); \ + if ((token)->GetKind() != LexTokenKind::kind) { \ + logError(DiagnosticType::UnexpectedToken, (token)->GetSpan()); \ } else { \ PROGRESS_TOKEN(token); \ } @@ -32,7 +32,8 @@ namespace MalachScript::Parser { const ParsedScriptStatement* Parser::ParseScript(const LexToken* firstToken, const log_func& log) { std::vector statements; - statements.reserve(32); + const size_t reservedScriptSize = 32; + statements.reserve(reservedScriptSize); size_t current = 0; const auto* currentToken = firstToken; while (true) { @@ -64,12 +65,13 @@ namespace MalachScript::Parser { const auto* current = currentToken; auto start = current->GetSpan().GetStart(); bool lookingForClass = true; + ClassAttr classAttr = ClassAttr::None; while (lookingForClass) { switch (current->GetKind()) { - case LexTokenKind::SharedKeyword: break; - case LexTokenKind::AbstractKeyword: break; - case LexTokenKind::FinalKeyword: break; - case LexTokenKind::ExternalKeyword: break; + case LexTokenKind::SharedKeyword: ClassAttrHelpers::Set(classAttr, ClassAttr::Shared); break; + case LexTokenKind::AbstractKeyword: ClassAttrHelpers::Set(classAttr, ClassAttr::Abstract); break; + case LexTokenKind::FinalKeyword: ClassAttrHelpers::Set(classAttr, ClassAttr::Final); break; + case LexTokenKind::ExternalKeyword: ClassAttrHelpers::Set(classAttr, ClassAttr::External); break; case LexTokenKind::ClassKeyword: lookingForClass = false; break; default: return false; } @@ -83,7 +85,6 @@ namespace MalachScript::Parser { PROGRESS_TOKEN(current); std::vector inherits; std::vector body; - body.reserve(16); switch (current->GetKind()) { case LexTokenKind::SemicolonSymbol: { @@ -132,7 +133,8 @@ namespace MalachScript::Parser { } default: throw; } - out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), identifier, inherits, body); + out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), classAttr, identifier, inherits, + body); currentToken = current; return true; } @@ -716,7 +718,7 @@ namespace MalachScript::Parser { } #define EXPR_PARSER(operator, name, func) \ - operator name; \ + operator(name); \ if (func(name, current)) { \ PROGRESS_TOKEN(current); \ ScopedPtr rightHand = nullptr; \ diff --git a/src/Parser/Statements/ParsedStatement.hpp b/src/Parser/Statements/ParsedStatement.hpp index f782455..270554d 100644 --- a/src/Parser/Statements/ParsedStatement.hpp +++ b/src/Parser/Statements/ParsedStatement.hpp @@ -4,6 +4,7 @@ #include #include #include "../../CoreData/AccessModifier.hpp" +#include "../../CoreData/ClassAttr.hpp" #include "../../CoreData/FuncAttr.hpp" #include "../../CoreData/TypeMod.hpp" #include "../../TextSpan.hpp" @@ -41,24 +42,27 @@ namespace MalachScript::Parser { }; class ParsedClassStatement : public ParsedStatementImpl { - Identifier _identifier; - std::vector _inherits; - std::vector> _body; - public: - ParsedClassStatement(TextSpan span, Identifier identifier, std::vector inherits, - const std::vector& body) - : ParsedStatementImpl(span), _identifier(identifier), _inherits(inherits), - _body(body.size()) { + ParsedClassStatement(TextSpan span, ClassAttr classAttr, Identifier identifier, + 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 {