LCOV - code coverage report
Current view: top level - staxlib/frontend/src/lexer - lexer.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.9 % 59 56
Test Date: 1980-01-01 00:00:00 Functions: 100.0 % 6 6

            Line data    Source code
       1              : #include "stax/lexer/lexer.hpp"
       2              : 
       3              : #include <format>
       4              : #include <stax/utils/result.hpp>
       5              : #include <utility>
       6              : 
       7              : namespace stax::lexer {
       8              : 
       9           30 : Lexer::Lexer(std::string input) : input_(std::move(input)) {
      10           15 :   curr_ = input_.begin();
      11           15 :   peek_ = curr_ + 1;
      12           15 :   ConsumeWhitespace();
      13           15 : }
      14              : 
      15          158 : auto Lexer::NextToken() -> result_t<token::Token> {
      16          316 :   if (IsWhitespace(*curr_)) {
      17           72 :     ConsumeWhitespace();
      18              :   }
      19          316 :   if (curr_ == input_.end()) return token::Token{token::Type::kEOF, ""};
      20              : 
      21          130 :   std::optional<token::Token> t;
      22          260 :   switch (const auto c = *curr_) {
      23           13 :     case '=': t = token::Token{token::Type::kAssign, "="}; break;
      24            4 :     case '+': t = token::Token{token::Type::kPlus, "+"}; break;
      25            2 :     case '-': t = token::Token{token::Type::kMinus, "-"}; break;
      26            1 :     case '>': t = token::Token{token::Type::kGreater, ">"}; break;
      27            1 :     case '<': t = token::Token{token::Type::kLess, "<"}; break;
      28            1 :     case '~': t = token::Token{token::Type::kTilde, "~"}; break;
      29            1 :     case '!': t = token::Token{token::Type::kBang, "!"}; break;
      30            6 :     case '(': t = token::Token{token::Type::kLParen, "("}; break;
      31            6 :     case ')': t = token::Token{token::Type::kRParen, ")"}; break;
      32            4 :     case '{': t = token::Token{token::Type::kLBrace, "{"}; break;
      33            4 :     case '}': t = token::Token{token::Type::kRBrace, "}"}; break;
      34            5 :     case ',': t = token::Token{token::Type::kComma, ","}; break;
      35           17 :     case ';': t = token::Token{token::Type::kSemicolon, ";"}; break;
      36           65 :     default: {
      37              :       // Deal with numerics and letters
      38           65 :       if (IsLetter(c)) {
      39           49 :         TRY_RESULT(const auto sv, Identifier());
      40              : 
      41           49 :         if (kKeywords.contains(sv)) {
      42            3 :           return token::Token{kKeywords.at(sv), sv};
      43              :         }
      44              : 
      45           46 :         return token::Token{token::Type::kIdent, sv};
      46           49 :       }
      47              : 
      48           16 :       if (IsDigit(c)) {
      49           16 :         TRY_RESULT(const auto sv, Number());
      50           16 :         return token::Token(token::Type::kInt, sv);
      51           16 :       }
      52              : 
      53            0 :       return result::Err(Error::IllegalCharacter,
      54            0 :                          std::format("{} not recognized", c));
      55              :     }
      56              :   }
      57              : 
      58           65 :   Advance();
      59              : 
      60           65 :   if (t.has_value()) {
      61           65 :     return t.value();
      62              :   }
      63              : 
      64            0 :   return result::Err(Error::Syntax);
      65              : }
      66              : 
      67           49 : auto Lexer::Identifier() -> result_t<std::string_view> {
      68           49 :   auto beg = curr_;
      69          336 :   while (IsLetter(*curr_)) {
      70          119 :     Advance();
      71              :   }
      72              : 
      73           49 :   return std::string_view{beg, curr_};
      74              : }
      75              : 
      76           16 : auto Lexer::Number() -> result_t<std::string_view> {
      77           16 :   auto beg = curr_;
      78           78 :   while (IsDigit(*curr_)) {
      79           23 :     Advance();
      80              :   }
      81              : 
      82           16 :   return std::string_view{beg, curr_};
      83              : }
      84              : 
      85          309 : void Lexer::Advance() {
      86          309 :   ++curr_;
      87          309 :   ++peek_;
      88          309 : }
      89              : 
      90           87 : void Lexer::ConsumeWhitespace() {
      91          378 :   while (IsWhitespace(*curr_)) {
      92          102 :     Advance();
      93              :   }
      94           87 : }
      95              : 
      96              : }  // namespace stax::lexer
        

Generated by: LCOV version 2.3.2-1