#ifndef MALACHSCRIPT_LEXER_HPP #define MALACHSCRIPT_LEXER_HPP #include #include "../../Diagnostics/Diagnostics.hpp" #include "../../Utils/MemoryPool.hpp" #include "LexToken.hpp" namespace MalachScript::Parser { class Lexer { public: Lexer(const char8_t* scriptName, const char8_t* script, Diagnostics::Diagnostics* diag) : Lexer(std::u8string_view(scriptName), std::u8string_view(script), diag) {} Lexer(std::u8string_view scriptName, std::u8string_view script, Diagnostics::Diagnostics* diag) : _scriptName(scriptName), _script(script), _scriptLength(script.size()), _diagnostics(diag) {} const LexToken* Lex(); private: std::u8string_view _scriptName; std::u8string_view _script; size_t _position = -1; size_t _scriptLength; Diagnostics::Diagnostics* _diagnostics; Utils::MemoryPool<2048, 1024> _allocator; inline char8_t Consume() { if (++_position >= _scriptLength) { return '\0'; } return _script[_position]; } inline void Progress(size_t steps = 1) { _position += steps; } inline char8_t Peek(size_t offset = 1) { auto pos = _position + offset; if (pos >= _scriptLength) { return '\0'; } return _script[pos]; } LexToken* LexNext(); LexToken* LexNumerical(char8_t); LexToken* LexDecimal(uint64_t initial); IntegerLiteral* LexHexadecimal(); IntegerLiteral* LexOctal(); IntegerLiteral* LexBinary(); StringLiteral* LexString(char8_t opening, bool heredoc); LexToken* LexKeywordOrIdentifier(); static bool IsAlphaNumericalOrUnderscore(char8_t c); template inline T* Create(parameters... args) { return _allocator.Create(args...); } inline void LogError(Diagnostics::DiagnosticType type, TextSpan span) { _diagnostics->LogError(type, _scriptName, span); } }; } #endif // MALACHSCRIPT_LEXER_HPP