IR generation #3
+61
-40
@@ -1,55 +1,76 @@
|
|||||||
|
// NOLINTBEGIN(readability-identifier-naming)
|
||||||
|
|
||||||
#include "furc/front/lexer.hpp"
|
#include "furc/front/lexer.hpp"
|
||||||
|
|
||||||
|
#include "furlang/result.hpp"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace furc::front;
|
using namespace furc::front;
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
#define EXPECT_TOKEN(lexer, t) EXPECT_EQ((lexer).next_token(), (t));
|
using token_r = furlang::result<token, std::string>;
|
||||||
#define EXPECT_EOF(lexer) EXPECT_EQ((lexer).next_token(), (token{}));
|
using lexer_case = std::pair<std::string, std::vector<token_r>>;
|
||||||
#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) {
|
class LexerTestingFixture : public testing::TestWithParam<lexer_case> {};
|
||||||
lexer lexer("<TEMP>", "()\n\t\t{\n}[\"shto-to\"]; :,.main return func");
|
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::LParen }));
|
TEST_P(LexerTestingFixture, LexerTest) {
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::RParen }));
|
auto [code, expected] = GetParam();
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::LBrace }));
|
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::RBrace }));
|
lexer lexer("<TEMP>", code);
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::LBracket }));
|
auto it = expected.begin();
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::String, "shto-to"sv }));
|
while (it != expected.end()) {
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::RBracket }));
|
const auto& expected = *it++;
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Semicolon }));
|
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Colon }));
|
auto token = std::move(lexer.next_token());
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Comma }));
|
if (expected.has_error()) {
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Dot }));
|
EXPECT_TRUE(token.has_error());
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Identifier, "main"sv }));
|
EXPECT_EQ(token.error(), expected.error());
|
||||||
EXPECT_TOKEN(lexer, (token{ keyword_token::Return }));
|
} else {
|
||||||
EXPECT_TOKEN(lexer, (token{ keyword_token::Func }));
|
EXPECT_EQ(token, expected.value());
|
||||||
EXPECT_EOF(lexer);
|
}
|
||||||
|
}
|
||||||
|
// EOF
|
||||||
|
EXPECT_EQ(lexer.next_token(), token{});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Lexer, Comments) {
|
INSTANTIATE_TEST_SUITE_P(EmptyTests,
|
||||||
lexer lexer("<TEMP>", "(/** skibidi **/func{//)\n}");
|
LexerTestingFixture,
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::LParen, "("sv })); // left out the string-view deliberately
|
testing::Values(lexer_case("", {}), lexer_case(" ", {}), lexer_case("\t", {}), lexer_case("\n", {})));
|
||||||
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) {
|
INSTANTIATE_TEST_SUITE_P(Comments,
|
||||||
lexer lexer("<TEMP>", "67 18446744073709551615 18446744073709551616");
|
LexerTestingFixture,
|
||||||
EXPECT_TOKEN(lexer, (token{ 67ULL }));
|
testing::Values(lexer_case("(/** skibidi **/func{//)\n}",
|
||||||
EXPECT_TOKEN(lexer, (token{ 18446744073709551615ULL }));
|
{ { token_t::LParen }, { keyword_token::Func }, { token_t::LBrace }, { token_t::RBrace } })));
|
||||||
EXPECT_ERROR(lexer, "integer 18446744073709551616 is too big");
|
|
||||||
EXPECT_EOF(lexer);
|
INSTANTIATE_TEST_SUITE_P(Integers,
|
||||||
}
|
LexerTestingFixture,
|
||||||
|
testing::Values(lexer_case("67 6\n7", { { 67 }, { 6 }, { 7 } }),
|
||||||
|
lexer_case("18446744073709551615 18446744073709551616",
|
||||||
|
{ { 18446744073709551615ULL }, token_r(std::string("integer 18446744073709551616 is too big")) })));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Tokens,
|
||||||
|
LexerTestingFixture,
|
||||||
|
testing::Values(lexer_case("()\n\t\t{\n}[\"shto-to\"]; :,.main return func",
|
||||||
|
{ { token_t::LParen },
|
||||||
|
{ token_t::RParen },
|
||||||
|
{ token_t::LBrace },
|
||||||
|
{ token_t::RBrace },
|
||||||
|
{ token_t::LBracket },
|
||||||
|
{ token_t::String, "shto-to"sv },
|
||||||
|
{ token_t::RBracket },
|
||||||
|
{ token_t::Semicolon },
|
||||||
|
{ token_t::Colon },
|
||||||
|
{ token_t::Comma },
|
||||||
|
{ token_t::Dot },
|
||||||
|
{ token_t::Identifier, "main"sv },
|
||||||
|
{ keyword_token::Return },
|
||||||
|
{ keyword_token::Func } })));
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// NOLINTEND(readability-identifier-naming)
|
||||||
Reference in New Issue
Block a user