#include "furc/front/lexer.hpp" #include "gtest/gtest.h" namespace { using namespace furc::front; using namespace std::string_view_literals; #define EXPECT_TOKEN(lexer, t) EXPECT_EQ((lexer).next_token(), (t)); #define EXPECT_EOF(lexer) EXPECT_EQ((lexer).next_token(), (token{})); #define EXPECT_ERROR(lexer, err) \ do { \ auto handle = (lexer).next_token(); \ EXPECT_TRUE(handle.has_error()); \ EXPECT_EQ(handle.error(), (err)); \ } while (0) TEST(Lexer, Tokens) { lexer lexer("", "()\n\t\t{\n}[\"shto-to\"]; :,.main return func"); EXPECT_TOKEN(lexer, (token{ token_t::Lparen })); EXPECT_TOKEN(lexer, (token{ token_t::Rparen })); EXPECT_TOKEN(lexer, (token{ token_t::Lbrace })); EXPECT_TOKEN(lexer, (token{ token_t::Rbrace })); EXPECT_TOKEN(lexer, (token{ token_t::Lbracket })); EXPECT_TOKEN(lexer, (token{ token_t::String, "shto-to"sv })); EXPECT_TOKEN(lexer, (token{ token_t::Rbracket })); EXPECT_TOKEN(lexer, (token{ token_t::Semicolon })); EXPECT_TOKEN(lexer, (token{ token_t::Colon })); EXPECT_TOKEN(lexer, (token{ token_t::Comma })); EXPECT_TOKEN(lexer, (token{ token_t::Dot })); EXPECT_TOKEN(lexer, (token{ token_t::Identifier, "main"sv })); EXPECT_TOKEN(lexer, (token{ keyword_token::Return })); EXPECT_TOKEN(lexer, (token{ keyword_token::Func })); EXPECT_EOF(lexer); } TEST(Lexer, Comments) { lexer lexer("", "(/** skibidi **/func{//)\n}"); EXPECT_TOKEN(lexer, (token{ token_t::Lparen, "("sv })); // left out the string-view deliberately EXPECT_TOKEN(lexer, (token{ keyword_token::Func })); EXPECT_TOKEN(lexer, (token{ token_t::Lbrace })); EXPECT_TOKEN(lexer, (token{ token_t::Rbrace })); EXPECT_EOF(lexer); } TEST(Lexer, Integers) { lexer lexer("", "67 18446744073709551615 18446744073709551616"); EXPECT_TOKEN(lexer, (token{ 67ULL })); EXPECT_TOKEN(lexer, (token{ 18446744073709551615ULL })); EXPECT_ERROR(lexer, "integer 18446744073709551616 is too big"); EXPECT_EOF(lexer); } } // namespace