LCOV - code coverage report
Current view: top level - staxlib/frontend/src/lexer - lexer.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.4 % 54 51
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            8 : Lexer::Lexer(std::string input) : input_(std::move(input)) {
      10            4 :   curr_ = input_.begin();
      11            4 :   peek_ = curr_ + 1;
      12            4 :   ConsumeWhitespace();
      13            4 : }
      14              : 
      15           76 : auto Lexer::NextToken() -> result_t<token::Token> {
      16          152 :   if (IsWhitespace(*curr_)) {
      17           43 :     ConsumeWhitespace();
      18              :   }
      19          152 :   if (curr_ == input_.end()) return token::Token{token::Type::kEOF, ""};
      20              : 
      21           70 :   std::optional<token::Token> t;
      22          140 :   switch (const auto c = *curr_) {
      23            6 :     case '=': t = token::Token{token::Type::kAssign, "="}; break;
      24            2 :     case '+': t = token::Token{token::Type::kPlus, "+"}; break;
      25            5 :     case '(': t = token::Token{token::Type::kLParen, "("}; break;
      26            5 :     case ')': t = token::Token{token::Type::kRParen, ")"}; break;
      27            4 :     case '{': t = token::Token{token::Type::kLBrace, "{"}; break;
      28            4 :     case '}': t = token::Token{token::Type::kRBrace, "}"}; break;
      29            3 :     case ',': t = token::Token{token::Type::kComma, ","}; break;
      30            9 :     case ';': t = token::Token{token::Type::kSemicolon, ";"}; break;
      31           32 :     default: {
      32              :       // Deal with numerics and letters
      33           32 :       if (IsLetter(c)) {
      34           24 :         TRY_RESULT(const auto sv, Identifier());
      35              : 
      36           24 :         if (kKeywords.contains(sv)) {
      37            3 :           return token::Token{kKeywords.at(sv), sv};
      38              :         }
      39              : 
      40           21 :         return token::Token{token::Type::kIdent, sv};
      41           24 :       }
      42              : 
      43            8 :       if (IsDigit(c)) {
      44            8 :         TRY_RESULT(const auto sv, Number());
      45            8 :         return token::Token(token::Type::kInt, sv);
      46            8 :       }
      47              : 
      48            0 :       return result::Err(Error::IllegalCharacter,
      49            0 :                          std::format("{} not recognized", c));
      50              :     }
      51              :   }
      52              : 
      53           38 :   Advance();
      54              : 
      55           38 :   if (t.has_value()) {
      56           38 :     return t.value();
      57              :   }
      58              : 
      59            0 :   return result::Err(Error::Syntax);
      60              : }
      61              : 
      62           24 : auto Lexer::Identifier() -> result_t<std::string_view> {
      63           24 :   auto beg = curr_;
      64          198 :   while (IsLetter(*curr_)) {
      65           75 :     Advance();
      66              :   }
      67              : 
      68           48 :   return {beg, curr_};
      69              : }
      70              : 
      71            8 : auto Lexer::Number() -> result_t<std::string_view> {
      72            8 :   auto beg = curr_;
      73           44 :   while (IsDigit(*curr_)) {
      74           14 :     Advance();
      75              :   }
      76              : 
      77           16 :   return {beg, curr_};
      78              : }
      79              : 
      80          220 : void Lexer::Advance() {
      81          220 :   ++curr_;
      82          220 :   ++peek_;
      83          220 : }
      84              : 
      85           47 : void Lexer::ConsumeWhitespace() {
      86          280 :   while (IsWhitespace(*curr_)) {
      87           93 :     Advance();
      88              :   }
      89           47 : }
      90              : 
      91              : }  // namespace stax::lexer
        

Generated by: LCOV version 2.3.2-1