diff --git a/src/Parser/Lexer/LexResult.hpp b/src/Parser/Lexer/LexResult.hpp new file mode 100644 index 0000000..6c6693c --- /dev/null +++ b/src/Parser/Lexer/LexResult.hpp @@ -0,0 +1,19 @@ +#ifndef ELOHIMSCRIPT_LEXRESULT_HPP +#define ELOHIMSCRIPT_LEXRESULT_HPP + +#include "LexToken.hpp" +namespace ElohimScript::Parser { + class LexResult { + public: + LexResult(const LexToken* first, const uint8_t* memoryMap) : _first(first), _memoryMap(memoryMap) {} + + [[nodiscard]] const LexToken* GetFirst() const noexcept { return _first; } + [[nodiscard]] const uint8_t* GetMemoryMap() const noexcept { return _memoryMap; } + + private: + const LexToken* _first; + const uint8_t* _memoryMap; + }; +} + +#endif // ELOHIMSCRIPT_LEXRESULT_HPP diff --git a/src/Parser/Lexer/Lexer.cpp b/src/Parser/Lexer/Lexer.cpp index 543c737..bfac094 100644 --- a/src/Parser/Lexer/Lexer.cpp +++ b/src/Parser/Lexer/Lexer.cpp @@ -25,7 +25,7 @@ namespace ElohimScript::Parser { auto start = _position; auto c = Consume(); switch (c) { - case u8'\0': return new LexTokenImpl(TextSpan(start, 1)); + case u8'\0': return Create>(TextSpan(start, 1)); case u8'*': { auto n = Peek(); if (n == u8'*') { @@ -34,91 +34,91 @@ namespace ElohimScript::Parser { if (n == u8'=') { Progress(); // **= - return new LexTokenImpl(TextSpan(start, 3)); + return Create>(TextSpan(start, 3)); } // ** - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'=') { Progress(); // *= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // * - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'/': if (Peek() == u8'=') { Progress(); // /= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // / - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); case u8'%': if (Peek() == u8'=') { Progress(); // %= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // % - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); case u8'+': { auto n = Peek(); if (n == u8'=') { Progress(); // += - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'+') { Progress(); // ++ - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // + - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'-': { auto n = Peek(); if (n == u8'=') { Progress(); // -= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'-') { Progress(); // -- - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // - - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'<': { auto n = Peek(); if (n == u8'=') { Progress(); // <= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'<') { Progress(); if (Peek() == u8'=') { Progress(); // <<= - return new LexTokenImpl(TextSpan(start, 3)); + return Create>(TextSpan(start, 3)); } // << - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // < - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'>': { auto n = Peek(); if (n == u8'=') { Progress(); // >= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'>') { Progress(); @@ -126,126 +126,126 @@ namespace ElohimScript::Parser { if (n == u8'=') { Progress(); // >>= - return new LexTokenImpl(TextSpan(start, 3)); + return Create>(TextSpan(start, 3)); } if (n == u8'>') { Progress(); if (Peek() == u8'=') { Progress(); // >>>= - return new LexTokenImpl( + return Create>( TextSpan(start, 4)); } // >>> - return new LexTokenImpl( + return Create>( TextSpan(start, 3)); } // >> - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // > - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } - case u8'(': return new LexTokenImpl(TextSpan(start, 1)); - case u8')': return new LexTokenImpl(TextSpan(start, 1)); + case u8'(': return Create>(TextSpan(start, 1)); + case u8')': return Create>(TextSpan(start, 1)); case u8'=': { if (Peek() == u8'=') { Progress(); // == - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // = - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'!': { auto n = Peek(); if (n == u8'=') { Progress(); // != - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'i' && Peek(2) == u8's') { Progress(2); // !is - return new LexTokenImpl(TextSpan(start, 3)); + return Create>(TextSpan(start, 3)); } // ! - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } - case u8'?': return new LexTokenImpl(TextSpan(start, 1)); + case u8'?': return Create>(TextSpan(start, 1)); case u8':': { if (Peek() == u8':') { Progress(); // :: - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // : - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'&': { auto n = Peek(); if (n == u8'=') { Progress(); // &= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'&') { Progress(); // && - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // & - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } - case u8',': return new LexTokenImpl(TextSpan(start, 1)); - case u8'{': return new LexTokenImpl(TextSpan(start, 1)); - case u8'}': return new LexTokenImpl(TextSpan(start, 1)); - case u8';': return new LexTokenImpl(TextSpan(start, 1)); + case u8',': return Create>(TextSpan(start, 1)); + case u8'{': return Create>(TextSpan(start, 1)); + case u8'}': return Create>(TextSpan(start, 1)); + case u8';': return Create>(TextSpan(start, 1)); case u8'|': { auto n = Peek(); if (n == u8'=') { Progress(); // |= - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } if (n == u8'|') { Progress(); // || - return new LexTokenImpl(TextSpan(start, 2)); + return Create>(TextSpan(start, 2)); } // | - return new LexTokenImpl(TextSpan(start, 1)); + return Create>(TextSpan(start, 1)); } case u8'^': { auto n = Peek(); if (n == u8'=') { Progress(); // ^= - return new LexTokenImpl(TextSpan(start, start + 2)); + return Create>(TextSpan(start, start + 2)); } if (n == u8'^') { Progress(); // ^^ - return new LexTokenImpl(TextSpan(start, start + 2)); + return Create>(TextSpan(start, start + 2)); } // ^ - return new LexTokenImpl(TextSpan(start, start + 1)); + return Create>(TextSpan(start, start + 1)); } - case u8'~': return new LexTokenImpl(TextSpan(start, start + 1)); - case u8'.': return new LexTokenImpl(TextSpan(start, start + 1)); - case u8'[': return new LexTokenImpl(TextSpan(start, start + 1)); - case u8']': return new LexTokenImpl(TextSpan(start, start + 1)); - case u8'@': return new LexTokenImpl(TextSpan(start, start + 1)); + case u8'~': return Create>(TextSpan(start, start + 1)); + case u8'.': return Create>(TextSpan(start, start + 1)); + case u8'[': return Create>(TextSpan(start, start + 1)); + case u8']': return Create>(TextSpan(start, start + 1)); + case u8'@': return Create>(TextSpan(start, start + 1)); case u8' ': case u8'\r': case u8'\n': - case u8'\t': return new LexTokenImpl(TextSpan(start, start + 1)); + case u8'\t': return Create>(TextSpan(start, start + 1)); // Byte order mark case u8'\xEF': { if (Peek() == u8'\xBB' && Peek(2) == u8'\xBF') { Progress(2); - return new LexTokenImpl(TextSpan(start, start + 3)); + return Create>(TextSpan(start, start + 3)); } } case u8'0': @@ -270,7 +270,7 @@ namespace ElohimScript::Parser { if (IsAlphaNumericalOrUnderscore(c)) return LexKeywordOrIdentifier(); _diagnostics->LogError(Diagnostics::DiagnosticType::UnknownToken, TextSpan(start, start + 1)); - return new LexTokenImpl(TextSpan(start, start + 1)); + return Create>(TextSpan(start, start + 1)); } } @@ -374,9 +374,9 @@ namespace ElohimScript::Parser { if (isExponent) { val *= pow(10, exponentValue); } - return new FloatLiteral(TextSpan(start, _position), val); + return Create(TextSpan(start, _position), val); } - return new IntegerLiteral(TextSpan(start, _position), value); + return Create(TextSpan(start, _position), value); } IntegerLiteral* Lexer::LexHexadecimal() { @@ -391,7 +391,7 @@ namespace ElohimScript::Parser { value <<= 4; value += v; } - return new IntegerLiteral(TextSpan(start, _position), value); + return Create(TextSpan(start, _position), value); } IntegerLiteral* Lexer::LexOctal() { auto start = _position; @@ -405,7 +405,7 @@ namespace ElohimScript::Parser { value <<= 3; value += v; } - return new IntegerLiteral(TextSpan(start, _position), value); + return Create(TextSpan(start, _position), value); } IntegerLiteral* Lexer::LexBinary() { auto start = _position; @@ -419,7 +419,7 @@ namespace ElohimScript::Parser { value <<= 1; value += v; } - return new IntegerLiteral(TextSpan(start, _position), value); + return Create(TextSpan(start, _position), value); } StringLiteral* Lexer::LexString(char8_t opening, bool heredoc) { Progress(); @@ -453,7 +453,7 @@ namespace ElohimScript::Parser { if (heredoc) { Progress(2); } - return new StringLiteral(TextSpan(start, start + _position), std::u8string(_script.substr(start, offset))); + return Create(TextSpan(start, start + _position), std::u8string(_script.substr(start, offset))); } static uint32_t constexpr Hash(const char8_t* input) { @@ -469,75 +469,75 @@ namespace ElohimScript::Parser { auto str = std::u8string(_script.substr(start, offset)); Progress(offset - 1); switch (Hash(str.c_str())) { - case Hash(u8"and"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"abstract"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"auto"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"bool"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"break"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"case"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"cast"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"catch"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"class"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"const"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"continue"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"default"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"do"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"double"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"else"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"enum"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"explicit"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"external"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"false"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"final"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"float"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"for"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"from"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"funcdef"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"function"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"get"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"if"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"import"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"in"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"inout"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"int"): return new LexTokenImpl(TextSpan(start, _position)); + case Hash(u8"and"): return Create>(TextSpan(start, _position)); + case Hash(u8"abstract"): return Create>(TextSpan(start, _position)); + case Hash(u8"auto"): return Create>(TextSpan(start, _position)); + case Hash(u8"bool"): return Create>(TextSpan(start, _position)); + case Hash(u8"break"): return Create>(TextSpan(start, _position)); + case Hash(u8"case"): return Create>(TextSpan(start, _position)); + case Hash(u8"cast"): return Create>(TextSpan(start, _position)); + case Hash(u8"catch"): return Create>(TextSpan(start, _position)); + case Hash(u8"class"): return Create>(TextSpan(start, _position)); + case Hash(u8"const"): return Create>(TextSpan(start, _position)); + case Hash(u8"continue"): return Create>(TextSpan(start, _position)); + case Hash(u8"default"): return Create>(TextSpan(start, _position)); + case Hash(u8"do"): return Create>(TextSpan(start, _position)); + case Hash(u8"double"): return Create>(TextSpan(start, _position)); + case Hash(u8"else"): return Create>(TextSpan(start, _position)); + case Hash(u8"enum"): return Create>(TextSpan(start, _position)); + case Hash(u8"explicit"): return Create>(TextSpan(start, _position)); + case Hash(u8"external"): return Create>(TextSpan(start, _position)); + case Hash(u8"false"): return Create>(TextSpan(start, _position)); + case Hash(u8"final"): return Create>(TextSpan(start, _position)); + case Hash(u8"float"): return Create>(TextSpan(start, _position)); + case Hash(u8"for"): return Create>(TextSpan(start, _position)); + case Hash(u8"from"): return Create>(TextSpan(start, _position)); + case Hash(u8"funcdef"): return Create>(TextSpan(start, _position)); + case Hash(u8"function"): return Create>(TextSpan(start, _position)); + case Hash(u8"get"): return Create>(TextSpan(start, _position)); + case Hash(u8"if"): return Create>(TextSpan(start, _position)); + case Hash(u8"import"): return Create>(TextSpan(start, _position)); + case Hash(u8"in"): return Create>(TextSpan(start, _position)); + case Hash(u8"inout"): return Create>(TextSpan(start, _position)); + case Hash(u8"int"): return Create>(TextSpan(start, _position)); case Hash(u8"interface"): - return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"int8"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"int16"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"int32"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"int64"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"is"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"mixin"): return new LexTokenImpl(TextSpan(start, _position)); + return Create>(TextSpan(start, _position)); + case Hash(u8"int8"): return Create>(TextSpan(start, _position)); + case Hash(u8"int16"): return Create>(TextSpan(start, _position)); + case Hash(u8"int32"): return Create>(TextSpan(start, _position)); + case Hash(u8"int64"): return Create>(TextSpan(start, _position)); + case Hash(u8"is"): return Create>(TextSpan(start, _position)); + case Hash(u8"mixin"): return Create>(TextSpan(start, _position)); case Hash(u8"namespace"): - return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"not"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"null"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"or"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"out"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"override"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"private"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"property"): return new LexTokenImpl(TextSpan(start, _position)); + return Create>(TextSpan(start, _position)); + case Hash(u8"not"): return Create>(TextSpan(start, _position)); + case Hash(u8"null"): return Create>(TextSpan(start, _position)); + case Hash(u8"or"): return Create>(TextSpan(start, _position)); + case Hash(u8"out"): return Create>(TextSpan(start, _position)); + case Hash(u8"override"): return Create>(TextSpan(start, _position)); + case Hash(u8"private"): return Create>(TextSpan(start, _position)); + case Hash(u8"property"): return Create>(TextSpan(start, _position)); case Hash(u8"protected"): - return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"return"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"set"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"shared"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"super"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"switch"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"this"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"true"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"try"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"typedef"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"uint"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"uint8"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"uint16"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"uint32"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"uint64"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"void"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"while"): return new LexTokenImpl(TextSpan(start, _position)); - case Hash(u8"xor"): return new LexTokenImpl(TextSpan(start, _position)); + return Create>(TextSpan(start, _position)); + case Hash(u8"return"): return Create>(TextSpan(start, _position)); + case Hash(u8"set"): return Create>(TextSpan(start, _position)); + case Hash(u8"shared"): return Create>(TextSpan(start, _position)); + case Hash(u8"super"): return Create>(TextSpan(start, _position)); + case Hash(u8"switch"): return Create>(TextSpan(start, _position)); + case Hash(u8"this"): return Create>(TextSpan(start, _position)); + case Hash(u8"true"): return Create>(TextSpan(start, _position)); + case Hash(u8"try"): return Create>(TextSpan(start, _position)); + case Hash(u8"typedef"): return Create>(TextSpan(start, _position)); + case Hash(u8"uint"): return Create>(TextSpan(start, _position)); + case Hash(u8"uint8"): return Create>(TextSpan(start, _position)); + case Hash(u8"uint16"): return Create>(TextSpan(start, _position)); + case Hash(u8"uint32"): return Create>(TextSpan(start, _position)); + case Hash(u8"uint64"): return Create>(TextSpan(start, _position)); + case Hash(u8"void"): return Create>(TextSpan(start, _position)); + case Hash(u8"while"): return Create>(TextSpan(start, _position)); + case Hash(u8"xor"): return Create>(TextSpan(start, _position)); - default: return new IdentifierToken(TextSpan(start, _position), str); + default: return Create(TextSpan(start, _position), str); } } bool Lexer::IsAlphaNumericalOrUnderscore(char8_t c) { diff --git a/src/Parser/Lexer/Lexer.hpp b/src/Parser/Lexer/Lexer.hpp index 1a4790f..4d98c33 100644 --- a/src/Parser/Lexer/Lexer.hpp +++ b/src/Parser/Lexer/Lexer.hpp @@ -3,6 +3,7 @@ #include #include "../../Diagnostics/Diagnostics.hpp" +#include "../../Utils/MemoryAllocator.hpp" #include "LexToken.hpp" namespace ElohimScript::Parser { @@ -10,17 +11,21 @@ namespace ElohimScript::Parser { public: Lexer(const char* script, Diagnostics::Diagnostics* diag) : Lexer(reinterpret_cast(script), diag) {} - Lexer(const char8_t* script, Diagnostics::Diagnostics* diag) : _script(script), _diagnostics(diag) {} - Lexer(std::u8string_view script, Diagnostics::Diagnostics* diag) : _script(script), _diagnostics(diag) {} + Lexer(const char8_t* script, Diagnostics::Diagnostics* diag) : Lexer(std::u8string_view(script), diag) {} + Lexer(std::u8string_view script, Diagnostics::Diagnostics* diag) + : _script(script), _scriptLength(script.size()), _diagnostics(diag) {} const LexToken* Lex(); private: std::u8string_view _script; size_t _position = -1; + size_t _scriptLength; Diagnostics::Diagnostics* _diagnostics; + Utils::MemoryAllocator<2048, 1024> _allocator; + inline char8_t Consume() { - if (++_position >= _script.size()) { + if (++_position >= _scriptLength) { return '\0'; } return _script[_position]; @@ -30,10 +35,10 @@ namespace ElohimScript::Parser { inline char8_t Peek(size_t offset = 1) { auto pos = _position + offset; - if (pos >= _script.size()) { + if (pos >= _scriptLength) { return '\0'; } - return _script[pos]; + return *(_script.data() + pos); } LexToken* LexNext(); @@ -47,6 +52,10 @@ namespace ElohimScript::Parser { LexToken* LexKeywordOrIdentifier(); static bool IsAlphaNumericalOrUnderscore(char8_t c); + + template inline T* Create(parameters... args) { + return _allocator.Create(args...); + } }; } diff --git a/src/Utils/MemoryAllocator.hpp b/src/Utils/MemoryAllocator.hpp new file mode 100644 index 0000000..a4d79e1 --- /dev/null +++ b/src/Utils/MemoryAllocator.hpp @@ -0,0 +1,45 @@ +#ifndef ELOHIMSCRIPT_MEMORYALLOCATOR_HPP +#define ELOHIMSCRIPT_MEMORYALLOCATOR_HPP + +#include +#include +#include + +namespace ElohimScript::Utils { + template + class MemoryAllocator { + size_t _offset; + size_t _capacity; + uint8_t* _memory = nullptr; + + public: + MemoryAllocator() : _offset(0), _capacity(initialSize) { + auto *ptr = malloc(_capacity); + if (ptr == nullptr) { + throw std::logic_error("Out of memory."); + } + _memory = static_cast(ptr); + } + + ~MemoryAllocator(){ + 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); + } + uint8_t* ptr = _memory + _offset; + T* element = new (ptr) T(args...); + _offset += sizeof(T); + return element; + } + }; +} + +#endif // ELOHIMSCRIPT_MEMORYALLOCATOR_HPP diff --git a/tests/LexerTests/IdentifierLexTests.cpp b/tests/LexerTests/IdentifierLexTests.cpp index 921cb3e..3807922 100644 --- a/tests/LexerTests/IdentifierLexTests.cpp +++ b/tests/LexerTests/IdentifierLexTests.cpp @@ -11,7 +11,6 @@ using namespace ElohimScript::Parser; CHECK(diag.GetMessages().empty()); \ CHECK(token->GetKind() == LexTokenKind::symbol); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } KEYWORD_TEST("and", AndKeyword); @@ -101,7 +100,6 @@ namespace doctest { auto value = ((IdentifierToken*)token)->GetValue(); \ CHECK(value == std::u8string(reinterpret_cast(identifier))); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } IDENTIFIER_TEST("foobar"); diff --git a/tests/LexerTests/LexerIntegrationTests.cpp b/tests/LexerTests/LexerIntegrationTests.cpp index 0099c2a..f51e90f 100644 --- a/tests/LexerTests/LexerIntegrationTests.cpp +++ b/tests/LexerTests/LexerIntegrationTests.cpp @@ -17,7 +17,6 @@ using namespace ElohimScript::Parser; pos++; \ current = current->GetNext().get(); \ } \ - delete token; \ } LEX_TEST("1 + 1", LexTokenKind::IntegerLiteral, LexTokenKind::Whitespace, LexTokenKind::PlusSymbol, diff --git a/tests/LexerTests/NumericalLexTests.cpp b/tests/LexerTests/NumericalLexTests.cpp index 028cac4..5204698 100644 --- a/tests/LexerTests/NumericalLexTests.cpp +++ b/tests/LexerTests/NumericalLexTests.cpp @@ -13,7 +13,6 @@ using namespace ElohimScript::Parser; auto value = ((const IntegerLiteral*)token)->GetValue(); \ CHECK(value == (expected)); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } #define FLOAT_TEST(script, expected) \ @@ -26,7 +25,6 @@ using namespace ElohimScript::Parser; auto value = ((const FloatLiteral*)token)->GetValue(); \ CHECK(value == (expected)); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } // Decimal lexing @@ -72,11 +70,10 @@ INTEGER_TEST("0b110011", 51); TEST_CASE("Lex invalid numerical base") { ElohimScript::Diagnostics::Diagnostics diag; auto lexer = Lexer("0f553", &diag); - const auto* token = lexer.Lex(); + lexer.Lex(); const auto& messages = diag.GetMessages(); REQUIRE(messages.size() == 1); CHECK(messages[0].GetType() == ElohimScript::Diagnostics::DiagnosticType::InvalidNumericalBase); CHECK(messages[0].GetLevel() == ElohimScript::Diagnostics::DiagnosticLevel::Error); CHECK(messages[0].GetSpan() == ElohimScript::TextSpan(0, 2)); - delete token; } diff --git a/tests/LexerTests/StringLexTests.cpp b/tests/LexerTests/StringLexTests.cpp index 3df238f..743d39c 100644 --- a/tests/LexerTests/StringLexTests.cpp +++ b/tests/LexerTests/StringLexTests.cpp @@ -13,7 +13,6 @@ using namespace ElohimScript::Parser; auto value = ((const StringLiteral*)token)->GetValue(); \ CHECK(value == std::u8string(reinterpret_cast(str))); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } STRING_TEST("foo bar", "'"); @@ -34,5 +33,4 @@ bar""")", CHECK(value == std::u8string(reinterpret_cast(R"(foo bar)"))); CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); - delete token; } \ No newline at end of file diff --git a/tests/LexerTests/SymbolLexTests.cpp b/tests/LexerTests/SymbolLexTests.cpp index fecf65f..61a857b 100644 --- a/tests/LexerTests/SymbolLexTests.cpp +++ b/tests/LexerTests/SymbolLexTests.cpp @@ -12,7 +12,6 @@ using namespace ElohimScript::Parser; CHECK(diag.GetMessages().empty()); \ CHECK(token->GetKind() == LexTokenKind::symbol); \ CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); \ - delete token; \ } SYMBOL_TEST("*", StarSymbol) @@ -80,6 +79,5 @@ TEST_CASE("Lex whitespace") { CHECK(diag.GetMessages().empty()); CHECK(token->GetKind() == LexTokenKind::Whitespace); CHECK(token->GetNext()->GetKind() == LexTokenKind::EndOfFile); - delete token; } } \ No newline at end of file