diff --git a/src/Parser/Lexer/Lexer.hpp b/src/Parser/Lexer/Lexer.hpp index ced8bbe..430fa7e 100644 --- a/src/Parser/Lexer/Lexer.hpp +++ b/src/Parser/Lexer/Lexer.hpp @@ -3,7 +3,7 @@ #include #include "../../Diagnostics/Diagnostics.hpp" -#include "../../Utils/MemoryAllocator.hpp" +#include "../../Utils/MemoryPool.hpp" #include "LexToken.hpp" namespace MalachScript::Parser { @@ -22,7 +22,7 @@ namespace MalachScript::Parser { size_t _scriptLength; Diagnostics::Diagnostics* _diagnostics; - Utils::MemoryAllocator<2048, 1024> _allocator; + Utils::MemoryPool<2048, 1024> _allocator; inline char8_t Consume() { if (++_position >= _scriptLength) { diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index a428df7..026da54 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -14,7 +14,9 @@ } namespace MalachScript::Parser { - ParsedScriptStatement* Parser::Parse() { + const ParsedScriptStatement* Parser::Parse() { return ParseScript(); } + + const ParsedScriptStatement* Parser::ParseScript() { std::vector statements; statements.reserve(32); size_t current = 0; @@ -26,7 +28,10 @@ namespace MalachScript::Parser { break; } const ParsedStatement* statement; - if (ParseClass(statement)) { + auto result = ParseClass(statement) || ParseNamespace(statement); + if (!result) { + // TODO: Log error + continue; } statements.push_back(statement); current++; @@ -123,16 +128,28 @@ namespace MalachScript::Parser { PROGRESS_TOKEN(_currentToken); Identifier defineTo; - if (!ParseIdentifier(defineTo, _currentToken, encounteredErrors)) { - LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan()); - } + ParseIdentifier(defineTo, _currentToken, encounteredErrors); + PROGRESS_TOKEN(_currentToken); + EXPECT_TOKEN(_currentToken, SemicolonSymbol); PROGRESS_TOKEN(_currentToken); - if (_currentToken->GetKind() != LexTokenKind::SemicolonSymbol) { - LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan()); - } out = new ParsedTypeDefStatement(TextSpan(start, _currentToken->GetSpan().GetEnd()), defineTo, defineFrom); return true; } + bool Parser::ParseNamespace(const ParsedStatement*& out) { + if (_currentToken->GetKind() != LexTokenKind::NamespaceKeyword) { + return false; + } + auto start = _currentToken->GetSpan().GetStart(); + PROGRESS_TOKEN(_currentToken); + Identifier identifier; + bool encounteredErrors = false; + ParseIdentifier(identifier, _currentToken, encounteredErrors); + auto script = ParseScript(); + auto end = _currentToken->GetSpan().GetEnd(); + PROGRESS_TOKEN(_currentToken); + out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script); + return true; + } bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out) { return false; } bool Parser::ParseFunc([[maybe_unused]] const ParsedStatement*& out) { return false; } bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out) { return false; } diff --git a/src/Parser/Parser.hpp b/src/Parser/Parser.hpp index f0f849b..8a88eac 100644 --- a/src/Parser/Parser.hpp +++ b/src/Parser/Parser.hpp @@ -9,7 +9,7 @@ namespace MalachScript::Parser { public: Parser(std::u8string_view scriptName, const LexToken* firstToken, Diagnostics::Diagnostics* diagnostics) : _scriptName(scriptName), _diagnostics(diagnostics), _currentToken(firstToken) {} - ParsedScriptStatement* Parse(); + const ParsedScriptStatement* Parse(); private: std::u8string_view _scriptName; @@ -20,8 +20,10 @@ namespace MalachScript::Parser { _diagnostics->LogError(type, _scriptName, span); } + const ParsedScriptStatement* ParseScript(); bool ParseClass(const ParsedStatement*& out); bool ParseTypeDef(const ParsedStatement*& out); + bool ParseNamespace(const ParsedStatement*& out); bool ParseVirtProp(const ParsedStatement*& out); bool ParseFunc(const ParsedStatement*& out); bool ParseVar(const ParsedStatement*& out); diff --git a/src/Parser/Statements/ParsedStatement.hpp b/src/Parser/Statements/ParsedStatement.hpp index fb025c5..703144e 100644 --- a/src/Parser/Statements/ParsedStatement.hpp +++ b/src/Parser/Statements/ParsedStatement.hpp @@ -59,8 +59,21 @@ namespace MalachScript::Parser { ParsedTypeDefStatement(TextSpan span, const Identifier& defineFrom, const Identifier& defineTo) : ParsedStatementImpl(span), _defineFrom(defineFrom), _defineTo(defineTo) {} - inline const Identifier& GetDefineFrom() const noexcept { return _defineFrom; } - inline const Identifier& GetDefineTo() const noexcept { return _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; + const ParsedScriptStatement* _parsedScript; + + public: + ParsedNamespaceStatement(TextSpan 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 ParsedScriptStatement* GetScript() const noexcept { return _parsedScript; } }; } diff --git a/src/Parser/Statements/ParsedStatementKind.hpp b/src/Parser/Statements/ParsedStatementKind.hpp index 66ba05e..2ca3081 100644 --- a/src/Parser/Statements/ParsedStatementKind.hpp +++ b/src/Parser/Statements/ParsedStatementKind.hpp @@ -6,7 +6,8 @@ namespace MalachScript::Parser { Unknown, Script, Class, - TypeDef + TypeDef, + Namespace }; } diff --git a/src/Utils/MemoryAllocator.hpp b/src/Utils/MemoryPool.hpp similarity index 53% rename from src/Utils/MemoryAllocator.hpp rename to src/Utils/MemoryPool.hpp index 856f55b..2dbb144 100644 --- a/src/Utils/MemoryAllocator.hpp +++ b/src/Utils/MemoryPool.hpp @@ -1,5 +1,5 @@ -#ifndef MALACHSCRIPT_MEMORYALLOCATOR_HPP -#define MALACHSCRIPT_MEMORYALLOCATOR_HPP +#ifndef MALACHSCRIPT_MEMORYPOOL_HPP +#define MALACHSCRIPT_MEMORYPOOL_HPP #include #include @@ -7,13 +7,9 @@ namespace MalachScript::Utils { template - class MemoryAllocator { - size_t _offset; - size_t _capacity; - uint8_t* _memory = nullptr; - + class MemoryPool { public: - MemoryAllocator() : _offset(0), _capacity(initialSize) { + MemoryPool() : _offset(0), _capacity(initialSize) { auto *ptr = malloc(_capacity); if (ptr == nullptr) { throw std::logic_error("Out of memory."); @@ -21,25 +17,33 @@ namespace MalachScript::Utils { _memory = static_cast(ptr); } - ~MemoryAllocator(){ + ~MemoryPool(){ free(_memory); } template T* Create(parameters... args){ if (_offset + sizeof(T) >= _capacity) { - _capacity += steps; - auto newPtr = realloc(_memory, _capacity); - if (newPtr == nullptr) { - throw std::logic_error("Out of memory."); - } - _memory = static_cast(newPtr); + IncreaseStep(); } - uint8_t* ptr = _memory + _offset; - T* element = new (ptr) T(args...); + auto* element = new (_memory + _offset) T(args...); _offset += sizeof(T); return element; } + + private: + size_t _offset; + size_t _capacity; + uint8_t* _memory = nullptr; + + void IncreaseStep(){ + _capacity += steps; + auto newPtr = realloc(_memory, _capacity); + if (newPtr == nullptr) { + throw std::logic_error("Out of memory."); + } + _memory = static_cast(newPtr); + } }; } -#endif // MALACHSCRIPT_MEMORYALLOCATOR_HPP +#endif // MALACHSCRIPT_MEMORYPOOL_HPP