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