From 47f33f3dc0ce19121077ddf239f11c4f2739cf1a Mon Sep 17 00:00:00 2001 From: haxala1r Date: Thu, 2 Oct 2025 17:19:51 +0300 Subject: [PATCH] Change lexer code to use an option instead of ignoring the variant when no value is needed --- src/include/lex.hpp | 3 ++- src/lex.cpp | 16 ++++++++-------- src/tests/test.cpp | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/include/lex.hpp b/src/include/lex.hpp index 7a4beda..c66b5b0 100644 --- a/src/include/lex.hpp +++ b/src/include/lex.hpp @@ -3,6 +3,7 @@ #include #include #include +#include enum TokenType { OpenParen, @@ -18,7 +19,7 @@ enum TokenType { // Plain Old Data struct Token { enum TokenType type; - std::variant value; + std::optional> value; }; bool operator==(Token const& one, Token const& other); std::ostream &operator<<(std::ostream &os, Token const &t); diff --git a/src/lex.cpp b/src/lex.cpp index b90c08c..b8ed457 100644 --- a/src/lex.cpp +++ b/src/lex.cpp @@ -12,10 +12,10 @@ std::ostream &operator<<(std::ostream &os, Token const &t) { case TokenType::OpenParen: os << "OpenParen)"; break; case TokenType::CloseParen: os << "CloseParen)"; break; case TokenType::Dollar: os << "Dollar)"; break; - case TokenType::Symbol: os << "Symbol, " << get(t.value) << ")"; break; - case TokenType::String: os << "String, \"" << get(t.value) << "\")"; break; - case TokenType::Int: os << "Int, " << get(t.value) << ")"; break; - case TokenType::Double: os << "Double, " << get(t.value) << ")"; break; + case TokenType::Symbol: os << "Symbol, " << get(*t.value) << ")"; break; + case TokenType::String: os << "String, \"" << get(*t.value) << "\")"; break; + case TokenType::Int: os << "Int, " << get(*t.value) << ")"; break; + case TokenType::Double: os << "Double, " << get(*t.value) << ")"; break; case TokenType::End: os << "END)"; break; default: os << ")"; @@ -131,14 +131,14 @@ Token Lexer::next() { // character while at EOF, even if we have exhausted the stream. char c = ss.get(); if (ss.eof()) - return {TokenType::End}; + return {TokenType::End, nullopt}; if (isspace(c)) continue; switch (c) { - case '(': return {TokenType::OpenParen}; - case ')': return {TokenType::CloseParen}; - case '$': return {TokenType::Dollar}; + case '(': return {TokenType::OpenParen, nullopt}; + case ')': return {TokenType::CloseParen, nullopt}; + case '$': return {TokenType::Dollar, nullopt}; default: ss.unget(); return lexNonSpecial(); diff --git a/src/tests/test.cpp b/src/tests/test.cpp index 6db6ca4..dfdb74d 100644 --- a/src/tests/test.cpp +++ b/src/tests/test.cpp @@ -6,7 +6,7 @@ TEST_CASE("Lexer lexes doubles correctly", "[Lexer]") { SECTION("double and negative syntax") { Lexer l("(1.0 0.1 -.1 -1. . - -. .-)"); - REQUIRE(l.next() == Token({OpenParen})); + REQUIRE(l.next() == Token({OpenParen, nullopt})); REQUIRE(l.next() == Token({Double, 1.0})); REQUIRE(l.next() == Token({Double, 0.1})); REQUIRE(l.next() == Token({Double, -0.1})); @@ -15,7 +15,7 @@ TEST_CASE("Lexer lexes doubles correctly", "[Lexer]") { REQUIRE(l.next() == Token({Symbol, "-"})); REQUIRE(l.next() == Token({Symbol, "-."})); REQUIRE(l.next() == Token({Symbol, ".-"})); - REQUIRE(l.next() == Token({CloseParen})); + REQUIRE(l.next() == Token({CloseParen, nullopt})); } }