#include "elna/lexer.hpp" namespace elna { source::source(const std::string& buffer) : m_buffer(buffer) { } source::const_iterator source::begin() const { return source::const_iterator(std::cbegin(m_buffer)); } source::const_iterator source::end() const { source_position end_position{ 0, 0 }; return source::const_iterator(std::cend(m_buffer), end_position); } source::const_iterator::const_iterator(std::string::const_iterator buffer, const source_position start_position) : m_buffer(buffer), m_position(start_position) { } const source_position& source::const_iterator::position() const noexcept { return this->m_position; } source::const_iterator::reference source::const_iterator::operator*() const noexcept { return *m_buffer; } source::const_iterator::pointer source::const_iterator::operator->() const noexcept { return m_buffer.base(); } source::const_iterator& source::const_iterator::operator++() { if (*this->m_buffer == '\n') { this->m_position.column = 1; ++this->m_position.line; } else { ++this->m_position.column; } std::advance(this->m_buffer, 1); return *this; } source::const_iterator& source::const_iterator::operator++(int) { auto tmp = *this; ++(*this); return *this; } bool source::const_iterator::operator==(const source::const_iterator& that) const noexcept { return this->m_buffer == that.m_buffer; } bool source::const_iterator::operator!=(const source::const_iterator& that) const noexcept { return !(*this == that); } token::token(const type of, source::const_iterator begin, source::const_iterator end) : m_type(of), m_value(begin, end) { } token::type token::of() const noexcept { return m_type; } const token::value& token::identifier() const noexcept { return m_value; } const source_position& token::position() const noexcept { return m_position; } result> lex(const std::string& buffer) { std::vector tokens; source input{ buffer }; for (auto iterator = input.begin(); iterator != input.end();) { if (*iterator == ' ' || *iterator == '\n') { } else if (std::isgraph(*iterator)) { auto current_position = iterator; do { ++current_position; } while (current_position != input.end() && std::isgraph(*current_position)); token new_token{ token::type::word, iterator, current_position }; tokens.push_back(new_token); iterator = current_position; continue; } ++iterator; } return tokens; } }