summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-02-20 13:08:37 -0800
committerGitHub <noreply@github.com>2024-02-20 13:08:37 -0800
commitc0cdd267492956e9789148c8e478c467dd59d67b (patch)
treece57c212b27345b4957c538d1c51ef2fbd3b8dac
parenta9f01c0c911afabc86dfc210f3ea596f1c35de6e (diff)
downloadbinaryen-c0cdd267492956e9789148c8e478c467dd59d67b.tar.gz
binaryen-c0cdd267492956e9789148c8e478c467dd59d67b.tar.bz2
binaryen-c0cdd267492956e9789148c8e478c467dd59d67b.zip
[Parser] Simplify the lexer interface (#6319)
The lexer was previously an iterator over tokens, but that expressivity is not actually used in the parser. Instead, we have `input.h` that adapts the token iterator interface into an iterface that is actually useful. As a first step toward simplifying the lexer implementation to no longer be an iterator over tokens, update its interface by moving the adaptation from input.h to the lexer itself. This requires extensive changes to the lexer unit tests, which will not have to change further when we actually simplify the lexer implementation.
-rw-r--r--src/parser/input-impl.h255
-rw-r--r--src/parser/input.h69
-rw-r--r--src/parser/lexer.h246
-rw-r--r--test/gtest/wat-lexer.cpp2263
4 files changed, 1083 insertions, 1750 deletions
diff --git a/src/parser/input-impl.h b/src/parser/input-impl.h
deleted file mode 100644
index e3cf52015..000000000
--- a/src/parser/input-impl.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2023 WebAssembly Community Group participants
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "input.h"
-
-#ifndef parser_input_impl_h
-#define parser_input_impl_h
-
-inline std::optional<Token> ParseInput::peek() {
- if (!empty()) {
- return *lexer;
- }
- return {};
-}
-
-inline bool ParseInput::takeLParen() {
- auto t = peek();
- if (!t || !t->isLParen()) {
- return false;
- }
- ++lexer;
- return true;
-}
-
-inline bool ParseInput::takeRParen() {
- auto t = peek();
- if (!t || !t->isRParen()) {
- return false;
- }
- ++lexer;
- return true;
-}
-
-inline bool ParseInput::takeUntilParen() {
- while (true) {
- auto t = peek();
- if (!t) {
- return false;
- }
- if (t->isLParen() || t->isRParen()) {
- return true;
- }
- ++lexer;
- }
-}
-
-inline std::optional<Name> ParseInput::takeID() {
- if (auto t = peek()) {
- if (auto id = t->getID()) {
- ++lexer;
- // See comment on takeName.
- return Name(std::string(*id));
- }
- }
- return {};
-}
-
-inline std::optional<std::string_view> ParseInput::takeKeyword() {
- if (auto t = peek()) {
- if (auto keyword = t->getKeyword()) {
- ++lexer;
- return *keyword;
- }
- }
- return {};
-}
-
-inline bool ParseInput::takeKeyword(std::string_view expected) {
- if (auto t = peek()) {
- if (auto keyword = t->getKeyword()) {
- if (*keyword == expected) {
- ++lexer;
- return true;
- }
- }
- }
- return false;
-}
-
-inline std::optional<uint64_t> ParseInput::takeOffset() {
- if (auto t = peek()) {
- if (auto keyword = t->getKeyword()) {
- if (keyword->substr(0, 7) != "offset="sv) {
- return {};
- }
- Lexer subLexer(keyword->substr(7));
- if (subLexer == subLexer.end()) {
- return {};
- }
- if (auto o = subLexer->getU<uint64_t>()) {
- ++subLexer;
- if (subLexer == subLexer.end()) {
- ++lexer;
- return o;
- }
- }
- }
- }
- return std::nullopt;
-}
-
-inline std::optional<uint32_t> ParseInput::takeAlign() {
- if (auto t = peek()) {
- if (auto keyword = t->getKeyword()) {
- if (keyword->substr(0, 6) != "align="sv) {
- return {};
- }
- Lexer subLexer(keyword->substr(6));
- if (subLexer == subLexer.end()) {
- return {};
- }
- if (auto a = subLexer->getU<uint32_t>()) {
- ++subLexer;
- if (subLexer == subLexer.end()) {
- ++lexer;
- return a;
- }
- }
- }
- }
- return {};
-}
-
-template<typename T> inline std::optional<T> ParseInput::takeU() {
- if (auto t = peek()) {
- if (auto n = t->getU<T>()) {
- ++lexer;
- return n;
- }
- }
- return std::nullopt;
-}
-
-template<typename T> inline std::optional<T> ParseInput::takeI() {
- if (auto t = peek()) {
- if (auto n = t->getI<T>()) {
- ++lexer;
- return n;
- }
- }
- return std::nullopt;
-}
-
-inline std::optional<uint64_t> ParseInput::takeU64() {
- return takeU<uint64_t>();
-}
-
-inline std::optional<uint64_t> ParseInput::takeI64() {
- return takeI<uint64_t>();
-}
-
-inline std::optional<uint32_t> ParseInput::takeU32() {
- return takeU<uint64_t>();
-}
-
-inline std::optional<uint32_t> ParseInput::takeI32() {
- return takeI<uint32_t>();
-}
-
-inline std::optional<uint16_t> ParseInput::takeI16() {
- return takeI<uint16_t>();
-}
-
-inline std::optional<uint8_t> ParseInput::takeU8() { return takeU<uint8_t>(); }
-
-inline std::optional<uint8_t> ParseInput::takeI8() { return takeI<uint8_t>(); }
-
-inline std::optional<double> ParseInput::takeF64() {
- if (auto t = peek()) {
- if (auto d = t->getF64()) {
- ++lexer;
- return d;
- }
- }
- return std::nullopt;
-}
-
-inline std::optional<float> ParseInput::takeF32() {
- if (auto t = peek()) {
- if (auto f = t->getF32()) {
- ++lexer;
- return f;
- }
- }
- return std::nullopt;
-}
-
-inline std::optional<std::string> ParseInput::takeString() {
- if (auto t = peek()) {
- if (auto s = t->getString()) {
- ++lexer;
- return std::string(*s);
- }
- }
- return {};
-}
-
-inline std::optional<Name> ParseInput::takeName() {
- // TODO: Move this to lexer and validate UTF.
- if (auto str = takeString()) {
- // Copy to a std::string to make sure we have a null terminator, otherwise
- // the `Name` constructor won't work correctly.
- // TODO: Update `Name` to use string_view instead of char* and/or to take
- // rvalue strings to avoid this extra copy.
- return Name(std::string(*str));
- }
- return {};
-}
-
-inline bool ParseInput::takeSExprStart(std::string_view expected) {
- auto original = lexer;
- if (takeLParen() && takeKeyword(expected)) {
- return true;
- }
- lexer = original;
- return false;
-}
-
-inline bool ParseInput::peekSExprStart(std::string_view expected) {
- auto original = lexer;
- if (!takeLParen()) {
- return false;
- }
- bool ret = takeKeyword(expected);
- lexer = original;
- return ret;
-}
-
-inline Index ParseInput::getPos() {
- if (auto t = peek()) {
- return lexer.getIndex() - t->span.size();
- }
- return lexer.getIndex();
-}
-
-inline Err ParseInput::err(Index pos, std::string reason) {
- std::stringstream msg;
- msg << lexer.position(pos) << ": error: " << reason;
- return Err{msg.str()};
-}
-
-#endif // parser_input_impl_h
diff --git a/src/parser/input.h b/src/parser/input.h
index 6086ed1a5..f83f5a40a 100644
--- a/src/parser/input.h
+++ b/src/parser/input.h
@@ -41,40 +41,47 @@ struct ParseInput {
bool empty() { return lexer.empty(); }
- std::optional<Token> peek();
- bool takeLParen();
- bool takeRParen();
- bool takeUntilParen();
- std::optional<Name> takeID();
- std::optional<std::string_view> takeKeyword();
- bool takeKeyword(std::string_view expected);
- std::optional<uint64_t> takeOffset();
- std::optional<uint32_t> takeAlign();
- std::optional<uint64_t> takeU64();
- std::optional<uint64_t> takeI64();
- std::optional<uint32_t> takeU32();
- std::optional<uint32_t> takeI32();
- std::optional<uint16_t> takeI16();
- std::optional<uint8_t> takeU8();
- std::optional<uint8_t> takeI8();
- std::optional<double> takeF64();
- std::optional<float> takeF32();
- std::optional<std::string> takeString();
- std::optional<Name> takeName();
- bool takeSExprStart(std::string_view expected);
- bool peekSExprStart(std::string_view expected);
+ // TODO: Remove this useless layer of abstraction between the Lexer and
+ // Parser.
+ std::optional<Token> peek() { return lexer.peek(); }
+ bool takeLParen() { return lexer.takeLParen(); }
+ bool takeRParen() { return lexer.takeRParen(); }
+ bool takeUntilParen() { return lexer.takeUntilParen(); }
+ std::optional<Name> takeID() { return lexer.takeID(); }
+ std::optional<std::string_view> takeKeyword() { return lexer.takeKeyword(); }
+ bool takeKeyword(std::string_view expected) {
+ return lexer.takeKeyword(expected);
+ }
+ std::optional<uint64_t> takeOffset() { return lexer.takeOffset(); }
+ std::optional<uint32_t> takeAlign() { return lexer.takeAlign(); }
+ std::optional<uint64_t> takeU64() { return lexer.takeU64(); }
+ std::optional<uint64_t> takeI64() { return lexer.takeI64(); }
+ std::optional<uint32_t> takeU32() { return lexer.takeU32(); }
+ std::optional<uint32_t> takeI32() { return lexer.takeI32(); }
+ std::optional<uint16_t> takeI16() { return lexer.takeI16(); }
+ std::optional<uint8_t> takeU8() { return lexer.takeU8(); }
+ std::optional<uint8_t> takeI8() { return lexer.takeI8(); }
+ std::optional<double> takeF64() { return lexer.takeF64(); }
+ std::optional<float> takeF32() { return lexer.takeF32(); }
+ std::optional<std::string> takeString() { return lexer.takeString(); }
+ std::optional<Name> takeName() { return lexer.takeName(); }
+ bool takeSExprStart(std::string_view expected) {
+ return lexer.takeSExprStart(expected);
+ }
+ bool peekSExprStart(std::string_view expected) {
+ return lexer.peekSExprStart(expected);
+ }
- Index getPos();
- [[nodiscard]] Err err(Index pos, std::string reason);
- [[nodiscard]] Err err(std::string reason) { return err(getPos(), reason); }
+ Index getPos() { return lexer.getPos(); }
-private:
- template<typename T> std::optional<T> takeU();
- template<typename T> std::optional<T> takeS();
- template<typename T> std::optional<T> takeI();
-};
+ [[nodiscard]] Err err(Index pos, std::string reason) {
+ std::stringstream msg;
+ msg << lexer.position(pos) << ": error: " << reason;
+ return Err{msg.str()};
+ }
-#include "input-impl.h"
+ [[nodiscard]] Err err(std::string reason) { return err(getPos(), reason); }
+};
} // namespace wasm::WATParser
diff --git a/src/parser/lexer.h b/src/parser/lexer.h
index f0da151f9..8f9bd103a 100644
--- a/src/parser/lexer.h
+++ b/src/parser/lexer.h
@@ -23,6 +23,8 @@
#include <string_view>
#include <variant>
+#include "support/name.h"
+
#ifndef parser_lexer_h
#define parser_lexer_h
@@ -147,13 +149,6 @@ struct Token {
// positions are computed on demand rather than eagerly because they are
// typically only needed when there is an error to report.
struct Lexer {
- using iterator = Lexer;
- using difference_type = std::ptrdiff_t;
- using value_type = Token;
- using pointer = const Token*;
- using reference = const Token&;
- using iterator_category = std::forward_iterator_tag;
-
private:
std::string_view buffer;
size_t index = 0;
@@ -169,51 +164,238 @@ public:
void setIndex(size_t i) {
index = i;
- skipSpace();
- lexToken();
+ advance();
}
- std::string_view next() const { return buffer.substr(index); }
- Lexer& operator++() {
- // Preincrement
- skipSpace();
- lexToken();
- return *this;
+ std::optional<Token> peek() const { return curr; }
+
+ bool takeLParen() {
+ auto t = peek();
+ if (!t || !t->isLParen()) {
+ return false;
+ }
+ advance();
+ return true;
}
- Lexer operator++(int) {
- // Postincrement
- Lexer ret = *this;
- ++(*this);
- return ret;
+ bool takeRParen() {
+ auto t = peek();
+ if (!t || !t->isRParen()) {
+ return false;
+ }
+ advance();
+ return true;
+ }
+
+ bool takeUntilParen() {
+ while (true) {
+ auto t = peek();
+ if (!t) {
+ return false;
+ }
+ if (t->isLParen() || t->isRParen()) {
+ return true;
+ }
+ advance();
+ }
+ }
+
+ std::optional<Name> takeID() {
+ if (auto t = peek()) {
+ if (auto id = t->getID()) {
+ advance();
+ // See comment on takeName.
+ return Name(std::string(*id));
+ }
+ }
+ return {};
+ }
+
+ std::optional<std::string_view> takeKeyword() {
+ if (auto t = peek()) {
+ if (auto keyword = t->getKeyword()) {
+ advance();
+ return *keyword;
+ }
+ }
+ return {};
+ }
+
+ bool takeKeyword(std::string_view expected) {
+ if (auto t = peek()) {
+ if (auto keyword = t->getKeyword()) {
+ if (*keyword == expected) {
+ advance();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ std::optional<uint64_t> takeOffset() {
+ using namespace std::string_view_literals;
+ if (auto t = peek()) {
+ if (auto keyword = t->getKeyword()) {
+ if (keyword->substr(0, 7) != "offset="sv) {
+ return {};
+ }
+ Lexer subLexer(keyword->substr(7));
+ if (subLexer.empty()) {
+ return {};
+ }
+ if (auto o = subLexer.peek()->getU<uint64_t>()) {
+ subLexer.advance();
+ if (subLexer.empty()) {
+ advance();
+ return o;
+ }
+ }
+ }
+ }
+ return std::nullopt;
+ }
+
+ std::optional<uint32_t> takeAlign() {
+ using namespace std::string_view_literals;
+ if (auto t = peek()) {
+ if (auto keyword = t->getKeyword()) {
+ if (keyword->substr(0, 6) != "align="sv) {
+ return {};
+ }
+ Lexer subLexer(keyword->substr(6));
+ if (subLexer.empty()) {
+ return {};
+ }
+ if (auto a = subLexer.peek()->getU<uint32_t>()) {
+ subLexer.advance();
+ if (subLexer.empty()) {
+ advance();
+ return a;
+ }
+ }
+ }
+ }
+ return {};
+ }
+
+ template<typename T> std::optional<T> takeU() {
+ if (auto t = peek()) {
+ if (auto n = t->getU<T>()) {
+ advance();
+ return n;
+ }
+ }
+ return std::nullopt;
+ }
+
+ template<typename T> std::optional<T> takeI() {
+ if (auto t = peek()) {
+ if (auto n = t->getI<T>()) {
+ advance();
+ return n;
+ }
+ }
+ return std::nullopt;
+ }
+
+ std::optional<uint64_t> takeU64() { return takeU<uint64_t>(); }
+
+ std::optional<uint64_t> takeI64() { return takeI<uint64_t>(); }
+
+ std::optional<uint32_t> takeU32() { return takeU<uint32_t>(); }
+
+ std::optional<uint32_t> takeI32() { return takeI<uint32_t>(); }
+
+ std::optional<uint16_t> takeI16() { return takeI<uint16_t>(); }
+
+ std::optional<uint8_t> takeU8() { return takeU<uint8_t>(); }
+
+ std::optional<uint8_t> takeI8() { return takeI<uint8_t>(); }
+
+ std::optional<double> takeF64() {
+ if (auto t = peek()) {
+ if (auto d = t->getF64()) {
+ advance();
+ return d;
+ }
+ }
+ return std::nullopt;
+ }
+
+ std::optional<float> takeF32() {
+ if (auto t = peek()) {
+ if (auto f = t->getF32()) {
+ advance();
+ return f;
+ }
+ }
+ return std::nullopt;
}
- const Token& operator*() { return *curr; }
- const Token* operator->() { return &*curr; }
+ std::optional<std::string> takeString() {
+ if (auto t = peek()) {
+ if (auto s = t->getString()) {
+ advance();
+ return std::string(*s);
+ }
+ }
+ return {};
+ }
- bool operator==(const Lexer& other) const {
- // The iterator is equal to the end sentinel when there is no current token.
- if (!curr && !other.curr) {
+ std::optional<Name> takeName() {
+ // TODO: Move this to lexer and validate UTF.
+ if (auto str = takeString()) {
+ // Copy to a std::string to make sure we have a null terminator, otherwise
+ // the `Name` constructor won't work correctly.
+ // TODO: Update `Name` to use string_view instead of char* and/or to take
+ // rvalue strings to avoid this extra copy.
+ return Name(std::string(*str));
+ }
+ return {};
+ }
+
+ bool takeSExprStart(std::string_view expected) {
+ auto original = *this;
+ if (takeLParen() && takeKeyword(expected)) {
return true;
}
- // Otherwise they are equivalent when they are at the same position.
- return index == other.index;
+ *this = original;
+ return false;
}
- bool operator!=(const Lexer& other) const { return !(*this == other); }
+ bool peekSExprStart(std::string_view expected) {
+ auto original = *this;
+ if (!takeLParen()) {
+ return false;
+ }
+ bool ret = takeKeyword(expected);
+ *this = original;
+ return ret;
+ }
- Lexer begin() { return *this; }
+ std::string_view next() const { return buffer.substr(index); }
- Lexer end() const { return Lexer(); }
+ void advance() {
+ skipSpace();
+ lexToken();
+ }
- bool empty() const { return *this == end(); }
+ bool empty() const { return !curr; }
TextPos position(const char* c) const;
TextPos position(size_t i) const { return position(buffer.data() + i); }
TextPos position(std::string_view span) const {
return position(span.data());
}
- TextPos position(Token tok) const { return position(tok.span); }
+ TextPos position() const { return position(getPos()); }
+
+ size_t getPos() const {
+ if (auto t = peek()) {
+ return getIndex() - t->span.size();
+ }
+ return getIndex();
+ }
private:
void skipSpace();
diff --git a/test/gtest/wat-lexer.cpp b/test/gtest/wat-lexer.cpp
index b62644682..8e31b9ab9 100644
--- a/test/gtest/wat-lexer.cpp
+++ b/test/gtest/wat-lexer.cpp
@@ -23,76 +23,57 @@ using namespace wasm::WATParser;
using namespace std::string_view_literals;
TEST(LexerTest, LexWhitespace) {
- Token one{"1"sv, IntTok{1, NoSign}};
- Token two{"2"sv, IntTok{2, NoSign}};
- Token three{"3"sv, IntTok{3, NoSign}};
- Token four{"4"sv, IntTok{4, NoSign}};
- Token five{"5"sv, IntTok{5, NoSign}};
-
Lexer lexer(" 1\t2\n3\r4 \n\n\t 5 "sv);
- auto it = lexer.begin();
- ASSERT_NE(it, lexer.end());
- Token t1 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t2 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t3 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t4 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t5 = *it++;
- EXPECT_EQ(it, lexer.end());
-
- EXPECT_EQ(t1, one);
- EXPECT_EQ(t2, two);
- EXPECT_EQ(t3, three);
- EXPECT_EQ(t4, four);
- EXPECT_EQ(t5, five);
-
- EXPECT_EQ(lexer.position(t1), (TextPos{1, 1}));
- EXPECT_EQ(lexer.position(t2), (TextPos{1, 3}));
- EXPECT_EQ(lexer.position(t3), (TextPos{2, 0}));
- EXPECT_EQ(lexer.position(t4), (TextPos{2, 2}));
- EXPECT_EQ(lexer.position(t5), (TextPos{4, 2}));
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{1, 1}));
+ EXPECT_EQ(lexer.takeI32(), 1);
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{1, 3}));
+ EXPECT_EQ(lexer.takeI32(), 2);
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{2, 0}));
+ EXPECT_EQ(lexer.takeI32(), 3);
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{2, 2}));
+ EXPECT_EQ(lexer.takeI32(), 4);
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{4, 2}));
+ EXPECT_EQ(lexer.takeI32(), 5);
+
+ ASSERT_TRUE(lexer.empty());
}
TEST(LexerTest, LexLineComment) {
- Token one{"1"sv, IntTok{1, NoSign}};
- Token six{"6"sv, IntTok{6, NoSign}};
-
Lexer lexer("1;; whee! 2 3\t4\r5\n6"sv);
- auto it = lexer.begin();
- Token t1 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t2 = *it++;
- EXPECT_EQ(it, lexer.end());
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{1, 0}));
+ EXPECT_EQ(lexer.takeI32(), 1);
- EXPECT_EQ(t1, one);
- EXPECT_EQ(t2, six);
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{2, 0}));
+ EXPECT_EQ(lexer.takeI32(), 6);
- EXPECT_EQ(lexer.position(t1), (TextPos{1, 0}));
- EXPECT_EQ(lexer.position(t2), (TextPos{2, 0}));
+ EXPECT_TRUE(lexer.empty());
}
TEST(LexerTest, LexBlockComment) {
- Token one{"1"sv, IntTok{1, NoSign}};
- Token six{"6"sv, IntTok{6, NoSign}};
-
Lexer lexer("1(; whoo! 2\n (; \n3\n ;) 4 (;) 5 ;) \n;)6"sv);
- auto it = lexer.begin();
- Token t1 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t2 = *it++;
- EXPECT_EQ(it, lexer.end());
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{1, 0}));
+ EXPECT_EQ(lexer.takeI32(), 1);
- EXPECT_EQ(t1, one);
- EXPECT_EQ(t2, six);
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_EQ(lexer.position(), (TextPos{5, 2}));
+ EXPECT_EQ(lexer.takeI32(), 6);
- EXPECT_EQ(lexer.position(t1), (TextPos{1, 0}));
- EXPECT_EQ(lexer.position(t2), (TextPos{5, 2}));
+ EXPECT_TRUE(lexer.empty());
}
TEST(LexerTest, LexParens) {
@@ -101,1446 +82,864 @@ TEST(LexerTest, LexParens) {
Lexer lexer("(())"sv);
- auto it = lexer.begin();
- ASSERT_NE(it, lexer.end());
- Token t1 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t2 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t3 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t4 = *it++;
- EXPECT_EQ(it, lexer.end());
-
- EXPECT_EQ(t1, left);
- EXPECT_EQ(t2, left);
- EXPECT_EQ(t3, right);
- EXPECT_EQ(t4, right);
- EXPECT_TRUE(left.isLParen());
- EXPECT_TRUE(right.isRParen());
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_TRUE(lexer.takeLParen());
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_TRUE(lexer.takeLParen());
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_TRUE(lexer.takeRParen());
+
+ ASSERT_FALSE(lexer.empty());
+ EXPECT_TRUE(lexer.takeRParen());
+
+ EXPECT_TRUE(lexer.empty());
}
TEST(LexerTest, LexInt) {
- {
- Lexer lexer("0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0"sv, IntTok{0, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0"sv, IntTok{0, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0"sv, IntTok{0, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"1"sv, IntTok{1, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+1"sv, IntTok{1, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-1"sv, IntTok{-1ull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0010"sv, IntTok{10, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0010"sv, IntTok{10, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0010"sv, IntTok{-10ull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("9999"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"9999"sv, IntTok{9999, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+9999"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+9999"sv, IntTok{9999, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-9999"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-9999"sv, IntTok{-9999ull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("12_34"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"12_34"sv, IntTok{1234, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("1_2_3_4"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"1_2_3_4"sv, IntTok{1234, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("_1234"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("1234_"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("12__34"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("12cd56"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("18446744073709551615"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"18446744073709551615"sv, IntTok{-1ull, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- // 64-bit unsigned overflow!
- Lexer lexer("18446744073709551616"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"18446744073709551616"sv,
- FloatTok{{}, 18446744073709551616.}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+9223372036854775807"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+9223372036854775807"sv, IntTok{INT64_MAX, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+9223372036854775808"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+9223372036854775808"sv,
- IntTok{uint64_t(INT64_MAX) + 1, Pos}};
- ;
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-9223372036854775808"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-9223372036854775808"sv, IntTok{uint64_t(INT64_MIN), Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-9223372036854775809"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-9223372036854775809"sv,
- IntTok{uint64_t(INT64_MIN) - 1, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
+ EXPECT_EQ(Lexer("0"sv).takeU8(), uint8_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeI8(), uint8_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeI16(), uint16_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeU32(), uint32_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeI32(), uint32_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeU64(), uint64_t(0));
+ EXPECT_EQ(Lexer("0"sv).takeI64(), uint64_t(0));
+
+ EXPECT_FALSE(Lexer("+0"sv).takeU8());
+ EXPECT_EQ(Lexer("+0"sv).takeI8(), uint8_t(0));
+
+ EXPECT_FALSE(Lexer("-0"sv).takeU8());
+ EXPECT_EQ(Lexer("-0"sv).takeI8(), uint8_t(0));
+
+ EXPECT_EQ(Lexer("1"sv).takeU8(), uint8_t(1));
+ EXPECT_EQ(Lexer("1"sv).takeI8(), uint8_t(1));
+
+ EXPECT_FALSE(Lexer("+1"sv).takeU8());
+ EXPECT_EQ(Lexer("+1"sv).takeI8(), uint8_t(1));
+
+ EXPECT_FALSE(Lexer("-1"sv).takeU8());
+ EXPECT_EQ(Lexer("-1").takeI8(), uint8_t(-1));
+
+ EXPECT_EQ(Lexer("0010"sv).takeU8(), uint8_t(10));
+ EXPECT_EQ(Lexer("0010"sv).takeI8(), uint8_t(10));
+
+ EXPECT_FALSE(Lexer("+0010"sv).takeU8());
+ EXPECT_EQ(Lexer("+0010"sv).takeI8(), uint8_t(10));
+
+ EXPECT_FALSE(Lexer("-0010"sv).takeU8());
+ EXPECT_EQ(Lexer("-0010"sv).takeI8(), uint8_t(-10));
+
+ EXPECT_FALSE(Lexer("9999"sv).takeU8());
+ EXPECT_EQ(Lexer("9999"sv).takeI16(), uint16_t(9999));
+ EXPECT_EQ(Lexer("9999"sv).takeU32(), uint32_t(9999));
+ EXPECT_EQ(Lexer("9999"sv).takeI32(), uint32_t(9999));
+
+ EXPECT_FALSE(Lexer("+9999"sv).takeU32());
+ EXPECT_EQ(Lexer("+9999"sv).takeI32(), uint32_t(9999));
+
+ EXPECT_FALSE(Lexer("-9999"sv).takeU32());
+ EXPECT_EQ(Lexer("-9999"sv).takeI32(), uint32_t(-9999));
+
+ EXPECT_EQ(Lexer("12_34"sv).takeU32(), uint32_t(1234));
+ EXPECT_EQ(Lexer("12_34"sv).takeI32(), uint32_t(1234));
+
+ EXPECT_EQ(Lexer("1_2_3_4"sv).takeU32(), uint32_t(1234));
+ EXPECT_EQ(Lexer("1_2_3_4"sv).takeI32(), uint32_t(1234));
+
+ EXPECT_FALSE(Lexer("_1234"sv).takeU32());
+ EXPECT_FALSE(Lexer("_1234"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("1234_"sv).takeU32());
+ EXPECT_FALSE(Lexer("1234_"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("12__34"sv).takeU32());
+ EXPECT_FALSE(Lexer("12__34"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("12cd56"sv).takeU32());
+ EXPECT_FALSE(Lexer("12cd56"sv).takeI32());
+
+ EXPECT_EQ(Lexer("18446744073709551615"sv).takeU64(), uint64_t(-1));
+ EXPECT_EQ(Lexer("18446744073709551615"sv).takeI64(), uint64_t(-1));
+
+ // 64-bit overflow!
+ EXPECT_FALSE(Lexer("18446744073709551616"sv).takeU64());
+ EXPECT_FALSE(Lexer("18446744073709551616"sv).takeI64());
+
+ EXPECT_FALSE(Lexer("+9223372036854775807"sv).takeU64());
+ EXPECT_EQ(Lexer("+9223372036854775807"sv).takeI64(), INT64_MAX);
+
+ EXPECT_EQ(Lexer("9223372036854775808"sv).takeU64(), uint64_t(INT64_MAX) + 1);
+ EXPECT_EQ(Lexer("9223372036854775808"sv).takeI64(), uint64_t(INT64_MAX) + 1);
+
+ EXPECT_FALSE(Lexer("+9223372036854775808"sv).takeU64());
+ EXPECT_FALSE(Lexer("+9223372036854775808"sv).takeI64());
+
+ EXPECT_FALSE(Lexer("-9223372036854775808"sv).takeU64());
+ EXPECT_EQ(Lexer("-9223372036854775808"sv).takeI64(), uint64_t(INT64_MIN));
+
+ EXPECT_FALSE(Lexer("-9223372036854775809"sv).takeU64());
+ EXPECT_FALSE(Lexer("-9223372036854775809"sv).takeI64());
}
TEST(LexerTest, LexHexInt) {
- {
- Lexer lexer("0x0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x0"sv, IntTok{0, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0x0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0x0"sv, IntTok{0, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0x0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0x0"sv, IntTok{0, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x1"sv, IntTok{1, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0x1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0x1"sv, IntTok{1, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0x1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0x1"sv, IntTok{-1ull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x0010"sv, IntTok{16, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0x0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0x0010"sv, IntTok{16, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0x0010"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0x0010"sv, IntTok{-16ull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0xabcdef"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0xabcdef"sv, IntTok{0xabcdef, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0xABCDEF"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0xABCDEF"sv, IntTok{0xabcdef, Pos}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0xAbCdEf"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0xAbCdEf"sv, IntTok{-0xabcdefull, Neg}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x12_34"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x12_34"sv, IntTok{0x1234, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x1_2_3_4"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x1_2_3_4"sv, IntTok{0x1234, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("_0x1234"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x_1234"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x1234_"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x12__34"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0xg"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x120x34"sv);
- EXPECT_TRUE(lexer.empty());
- }
+ EXPECT_EQ(Lexer("0x0"sv).takeU8(), uint8_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeI8(), uint8_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeI16(), uint16_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeU32(), uint32_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeI32(), uint32_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeU64(), uint64_t(0));
+ EXPECT_EQ(Lexer("0x0"sv).takeI64(), uint64_t(0));
+
+ EXPECT_FALSE(Lexer("+0x0"sv).takeU8());
+ EXPECT_EQ(Lexer("+0x0"sv).takeI8(), uint8_t(0));
+
+ EXPECT_FALSE(Lexer("-0x0"sv).takeU8());
+ EXPECT_EQ(Lexer("-0x0"sv).takeI8(), uint8_t(0));
+
+ EXPECT_EQ(Lexer("0x1"sv).takeU8(), uint8_t(1));
+ EXPECT_EQ(Lexer("0x1"sv).takeI8(), uint8_t(1));
+
+ EXPECT_FALSE(Lexer("+0x1"sv).takeU8());
+ EXPECT_EQ(Lexer("+0x1"sv).takeI8(), uint8_t(1));
+
+ EXPECT_FALSE(Lexer("-0x1"sv).takeU8());
+ EXPECT_EQ(Lexer("-0x1").takeI8(), uint8_t(-1));
+
+ EXPECT_EQ(Lexer("0x0010"sv).takeU8(), uint8_t(16));
+ EXPECT_EQ(Lexer("0x0010"sv).takeI8(), uint8_t(16));
+
+ EXPECT_FALSE(Lexer("+0x0010"sv).takeU8());
+ EXPECT_EQ(Lexer("+0x0010"sv).takeI8(), uint8_t(16));
+
+ EXPECT_FALSE(Lexer("-0x0010"sv).takeU8());
+ EXPECT_EQ(Lexer("-0x0010"sv).takeI8(), uint8_t(-16));
+
+ EXPECT_FALSE(Lexer("0xabcdef"sv).takeU8());
+ EXPECT_EQ(Lexer("0xabcdef"sv).takeU32(), uint32_t(0xabcdef));
+ EXPECT_EQ(Lexer("0xabcdef"sv).takeI32(), uint32_t(0xabcdef));
+
+ EXPECT_FALSE(Lexer("+0xABCDEF"sv).takeU32());
+ EXPECT_EQ(Lexer("+0xABCDEF"sv).takeI32(), uint32_t(0xabcdef));
+
+ EXPECT_FALSE(Lexer("-0xAbCdEf"sv).takeU32());
+ EXPECT_EQ(Lexer("-0xAbCdEf"sv).takeI32(), uint32_t(-0xabcdef));
+
+ EXPECT_EQ(Lexer("0x12_34"sv).takeU32(), uint32_t(0x1234));
+ EXPECT_EQ(Lexer("0x12_34"sv).takeI32(), uint32_t(0x1234));
+
+ EXPECT_EQ(Lexer("0x1_2_3_4"sv).takeU32(), uint32_t(0x1234));
+ EXPECT_EQ(Lexer("0x1_2_3_4"sv).takeI32(), uint32_t(0x1234));
+
+ EXPECT_FALSE(Lexer("_0x1234"sv).takeU32());
+ EXPECT_FALSE(Lexer("_0x1234"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("0x_1234"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x_1234"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("0x1234_"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x1234_"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("0x12__34"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x12__34"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("0xg"sv).takeU32());
+ EXPECT_FALSE(Lexer("0xg"sv).takeI32());
+
+ EXPECT_FALSE(Lexer("0x120x34"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x120x34"sv).takeI32());
}
TEST(LexerTest, ClassifyInt) {
- {
- Lexer lexer("0"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- ASSERT_TRUE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0ull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0ull);
- EXPECT_EQ(*lexer->getU<uint32_t>(), 0u);
- EXPECT_EQ(*lexer->getS<int32_t>(), 0);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0u);
- EXPECT_EQ(*lexer->getF64(), 0.0);
- EXPECT_EQ(*lexer->getF32(), 0.0);
- EXPECT_FALSE(std::signbit(*lexer->getF64()));
- EXPECT_FALSE(std::signbit(*lexer->getF32()));
- }
- {
- Lexer lexer("+0"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0ull);
- EXPECT_EQ(*lexer->getS<int32_t>(), 0);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0u);
- EXPECT_EQ(*lexer->getF64(), 0.0);
- EXPECT_EQ(*lexer->getF32(), 0.0);
- EXPECT_FALSE(std::signbit(*lexer->getF64()));
- EXPECT_FALSE(std::signbit(*lexer->getF32()));
- }
- {
- Lexer lexer("-0"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0ull);
- EXPECT_EQ(*lexer->getS<int32_t>(), 0);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0u);
- EXPECT_EQ(*lexer->getF64(), -0.0);
- EXPECT_EQ(*lexer->getF32(), -0.0);
- ASSERT_TRUE(std::signbit(*lexer->getF64()));
- ASSERT_TRUE(std::signbit(*lexer->getF32()));
- }
- {
- Lexer lexer("0x7fff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- ASSERT_TRUE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0x7fffffffull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x7fffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x7fffffffull);
- EXPECT_EQ(*lexer->getU<uint32_t>(), 0x7fffffffu);
- EXPECT_EQ(*lexer->getS<int32_t>(), 0x7fffffff);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0x7fffffffu);
- EXPECT_EQ(*lexer->getF64(), 0x7fffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0x7fffffff.p0f);
- }
- {
- Lexer lexer("0x8000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- ASSERT_TRUE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0x80000000ull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x80000000ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x80000000ull);
- EXPECT_EQ(*lexer->getU<uint32_t>(), 0x80000000u);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0x80000000u);
- EXPECT_EQ(*lexer->getF64(), 0x80000000.p0);
- EXPECT_EQ(*lexer->getF32(), 0x80000000.p0f);
- }
- {
- Lexer lexer("+0x7fff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x7fffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x7fffffffull);
- EXPECT_EQ(*lexer->getS<int32_t>(), 0x7fffffff);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0x7fffffffu);
- EXPECT_EQ(*lexer->getF64(), 0x7fffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0x7fffffff.p0f);
- }
- {
- Lexer lexer("+0x8000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x80000000ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x80000000ull);
- EXPECT_EQ(*lexer->getF64(), 0x80000000.p0);
- EXPECT_EQ(*lexer->getF32(), 0x80000000.p0f);
- }
- {
- Lexer lexer("-0x8000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- ASSERT_TRUE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), -0x80000000ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), -0x80000000ull);
- EXPECT_EQ(*lexer->getS<int32_t>(), -0x7fffffffll - 1);
- EXPECT_EQ(*lexer->getI<uint32_t>(), -0x80000000u);
- EXPECT_EQ(*lexer->getF64(), -0x80000000.p0);
- EXPECT_EQ(*lexer->getF32(), -0x80000000.p0f);
- }
- {
- Lexer lexer("-0x8000_0001"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), -0x80000001ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), -0x80000001ull);
- EXPECT_EQ(*lexer->getF64(), -0x80000001.p0);
- EXPECT_EQ(*lexer->getF32(), -0x80000001.p0f);
- }
- {
- Lexer lexer("0xffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- ASSERT_TRUE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- ASSERT_TRUE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0xffffffffull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0xffffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0xffffffffull);
- EXPECT_EQ(*lexer->getU<uint32_t>(), 0xffffffffu);
- EXPECT_EQ(*lexer->getI<uint32_t>(), 0xffffffffu);
- EXPECT_EQ(*lexer->getF64(), 0xffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0xffffffff.p0f);
- }
- {
- Lexer lexer("0x1_0000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0x100000000ull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x100000000ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x100000000ull);
- EXPECT_EQ(*lexer->getF64(), 0x100000000.p0);
- EXPECT_EQ(*lexer->getF32(), 0x100000000.p0f);
- }
- {
- Lexer lexer("+0xffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0xffffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0xffffffffull);
- EXPECT_EQ(*lexer->getF64(), 0xffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0xffffffff.p0f);
- }
- {
- Lexer lexer("+0x1_0000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x100000000ll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x100000000ull);
- EXPECT_EQ(*lexer->getF64(), 0x100000000.p0);
- EXPECT_EQ(*lexer->getF32(), 0x100000000.p0f);
- }
- {
- Lexer lexer("0x7fff_ffff_ffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0x7fffffffffffffffull);
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x7fffffffffffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x7fffffffffffffffull);
- EXPECT_EQ(*lexer->getF64(), 0x7fffffffffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0x7fffffffffffffff.p0f);
- }
- {
- Lexer lexer("+0x7fff_ffff_ffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), 0x7fffffffffffffffll);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0x7fffffffffffffffull);
- EXPECT_EQ(*lexer->getF64(), 0x7fffffffffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0x7fffffffffffffff.p0f);
- }
- {
- Lexer lexer("-0x8000_0000_0000_0000"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- ASSERT_TRUE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getS<int64_t>(), -0x7fffffffffffffffll - 1);
- EXPECT_EQ(*lexer->getI<uint64_t>(), -0x8000000000000000ull);
- EXPECT_EQ(*lexer->getF64(), -0x8000000000000000.p0);
- EXPECT_EQ(*lexer->getF32(), -0x8000000000000000.p0f);
- }
- {
- Lexer lexer("0xffff_ffff_ffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- ASSERT_TRUE(lexer->getU<uint64_t>());
- EXPECT_FALSE(lexer->getS<int64_t>());
- ASSERT_TRUE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getU<uint64_t>(), 0xffffffffffffffffull);
- EXPECT_EQ(*lexer->getI<uint64_t>(), 0xffffffffffffffffull);
- EXPECT_EQ(*lexer->getF64(), 0xffffffffffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0xffffffffffffffff.p0f);
- }
- {
- Lexer lexer("+0xffff_ffff_ffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
-
- EXPECT_FALSE(lexer->getU<uint64_t>());
- EXPECT_FALSE(lexer->getS<int64_t>());
- EXPECT_FALSE(lexer->getI<uint64_t>());
- EXPECT_FALSE(lexer->getU<uint32_t>());
- EXPECT_FALSE(lexer->getS<int32_t>());
- EXPECT_FALSE(lexer->getI<uint32_t>());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
-
- EXPECT_EQ(*lexer->getF64(), 0xffffffffffffffff.p0);
- EXPECT_EQ(*lexer->getF32(), 0xffffffffffffffff.p0f);
- }
+ ASSERT_FALSE(Lexer("0"sv).empty());
+ ASSERT_TRUE(Lexer("0"sv).takeU64());
+ ASSERT_TRUE(Lexer("0"sv).takeI64());
+ ASSERT_TRUE(Lexer("0"sv).takeU32());
+ ASSERT_TRUE(Lexer("0"sv).takeI32());
+ ASSERT_TRUE(Lexer("0"sv).takeF64());
+ ASSERT_TRUE(Lexer("0"sv).takeF32());
+ EXPECT_EQ(*Lexer("0"sv).takeU64(), 0ull);
+ EXPECT_EQ(*Lexer("0"sv).takeI64(), 0ull);
+ EXPECT_EQ(*Lexer("0"sv).takeU32(), 0u);
+ EXPECT_EQ(*Lexer("0"sv).takeI32(), 0u);
+ EXPECT_EQ(*Lexer("0"sv).takeF64(), 0.0);
+ EXPECT_EQ(*Lexer("0"sv).takeF32(), 0.0);
+ EXPECT_FALSE(std::signbit(*Lexer("0"sv).takeF64()));
+ EXPECT_FALSE(std::signbit(*Lexer("0"sv).takeF32()));
+
+ ASSERT_FALSE(Lexer("+0"sv).empty());
+ EXPECT_FALSE(Lexer("+0"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0"sv).takeU32());
+ ASSERT_TRUE(Lexer("+0"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0"sv).takeI64(), 0ull);
+ EXPECT_EQ(*Lexer("+0"sv).takeI32(), 0u);
+ EXPECT_EQ(*Lexer("+0"sv).takeF64(), 0.0);
+ EXPECT_EQ(*Lexer("+0"sv).takeF32(), 0.0);
+ EXPECT_FALSE(std::signbit(*Lexer("+0"sv).takeF64()));
+ EXPECT_FALSE(std::signbit(*Lexer("+0"sv).takeF32()));
+
+ ASSERT_FALSE(Lexer("-0"sv).empty());
+ EXPECT_FALSE(Lexer("-0"sv).takeU64());
+ ASSERT_TRUE(Lexer("-0"sv).takeI64());
+ EXPECT_FALSE(Lexer("-0"sv).takeU32());
+ ASSERT_TRUE(Lexer("-0"sv).takeI32());
+ ASSERT_TRUE(Lexer("-0"sv).takeF64());
+ ASSERT_TRUE(Lexer("-0"sv).takeF32());
+ EXPECT_EQ(*Lexer("-0"sv).takeI64(), 0ull);
+ EXPECT_EQ(*Lexer("-0"sv).takeI32(), 0u);
+ EXPECT_EQ(*Lexer("-0"sv).takeF64(), -0.0);
+ EXPECT_EQ(*Lexer("-0"sv).takeF32(), -0.0);
+ ASSERT_TRUE(std::signbit(*Lexer("-0"sv).takeF64()));
+ ASSERT_TRUE(std::signbit(*Lexer("-0"sv).takeF32()));
+
+ ASSERT_FALSE(Lexer("0x7fff_ffff"sv).empty());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeI64());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeU32());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("0x7fff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeU64(), 0x7fffffffull);
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeI64(), 0x7fffffffull);
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeU32(), 0x7fffffffu);
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeI32(), 0x7fffffffu);
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeF64(), 0x7fffffff.p0);
+ EXPECT_EQ(*Lexer("0x7fff_ffff"sv).takeF32(), 0x7fffffff.p0f);
+
+ ASSERT_FALSE(Lexer("0x8000_0000"sv).empty());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeI64());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeU32());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("0x8000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeU64(), 0x80000000ull);
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeI64(), 0x80000000ull);
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeU32(), 0x80000000u);
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeI32(), 0x80000000u);
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeF64(), 0x80000000.p0);
+ EXPECT_EQ(*Lexer("0x8000_0000"sv).takeF32(), 0x80000000.p0f);
+
+ ASSERT_FALSE(Lexer("+0x7fff_ffff"sv).empty());
+ EXPECT_FALSE(Lexer("+0x7fff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0x7fff_ffff"sv).takeU32());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0x7fff_ffff"sv).takeI64(), 0x7fffffffull);
+ EXPECT_EQ(*Lexer("+0x7fff_ffff"sv).takeI32(), 0x7fffffffu);
+ EXPECT_EQ(*Lexer("+0x7fff_ffff"sv).takeF64(), 0x7fffffff.p0);
+ EXPECT_EQ(*Lexer("+0x7fff_ffff"sv).takeF32(), 0x7fffffff.p0f);
+
+ ASSERT_FALSE(Lexer("+0x8000_0000"sv).empty());
+ EXPECT_FALSE(Lexer("+0x8000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0x8000_0000"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0x8000_0000"sv).takeU32());
+ EXPECT_FALSE(Lexer("+0x8000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0x8000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0x8000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0x8000_0000"sv).takeI64(), 0x80000000ull);
+ EXPECT_EQ(*Lexer("+0x8000_0000"sv).takeF64(), 0x80000000.p0);
+ EXPECT_EQ(*Lexer("+0x8000_0000"sv).takeF32(), 0x80000000.p0f);
+
+ ASSERT_FALSE(Lexer("-0x8000_0000"sv).empty());
+ EXPECT_FALSE(Lexer("-0x8000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("-0x8000_0000"sv).takeI64());
+ EXPECT_FALSE(Lexer("-0x8000_0000"sv).takeU32());
+ ASSERT_TRUE(Lexer("-0x8000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("-0x8000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("-0x8000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("-0x8000_0000"sv).takeI64(), -0x80000000ull);
+ EXPECT_EQ(*Lexer("-0x8000_0000"sv).takeI32(), -0x80000000u);
+ EXPECT_EQ(*Lexer("-0x8000_0000"sv).takeF64(), -0x80000000.p0);
+ EXPECT_EQ(*Lexer("-0x8000_0000"sv).takeF32(), -0x80000000.p0f);
+
+ ASSERT_FALSE(Lexer("-0x8000_0001"sv).empty());
+ EXPECT_FALSE(Lexer("-0x8000_0001"sv).takeU64());
+ ASSERT_TRUE(Lexer("-0x8000_0001"sv).takeI64());
+ EXPECT_FALSE(Lexer("-0x8000_0001"sv).takeU32());
+ EXPECT_FALSE(Lexer("-0x8000_0001"sv).takeI32());
+ ASSERT_TRUE(Lexer("-0x8000_0001"sv).takeF64());
+ ASSERT_TRUE(Lexer("-0x8000_0001"sv).takeF32());
+ EXPECT_EQ(*Lexer("-0x8000_0001"sv).takeI64(), -0x80000001ull);
+ EXPECT_EQ(*Lexer("-0x8000_0001"sv).takeF64(), -0x80000001.p0);
+ EXPECT_EQ(*Lexer("-0x8000_0001"sv).takeF32(), -0x80000001.p0f);
+
+ ASSERT_FALSE(Lexer("0xffff_ffff"sv).empty());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeI64());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeU32());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("0xffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeU64(), 0xffffffffull);
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeI64(), 0xffffffffull);
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeU32(), 0xffffffffu);
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeI32(), 0xffffffffu);
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeF64(), 0xffffffff.p0);
+ EXPECT_EQ(*Lexer("0xffff_ffff"sv).takeF32(), 0xffffffff.p0f);
+
+ ASSERT_FALSE(Lexer("0x1_0000_0000"sv).empty());
+ ASSERT_TRUE(Lexer("0x1_0000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("0x1_0000_0000"sv).takeI64());
+ EXPECT_FALSE(Lexer("0x1_0000_0000"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x1_0000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("0x1_0000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("0x1_0000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("0x1_0000_0000"sv).takeU64(), 0x100000000ull);
+ EXPECT_EQ(*Lexer("0x1_0000_0000"sv).takeI64(), 0x100000000ull);
+ EXPECT_EQ(*Lexer("0x1_0000_0000"sv).takeF64(), 0x100000000.p0);
+ EXPECT_EQ(*Lexer("0x1_0000_0000"sv).takeF32(), 0x100000000.p0f);
+
+ ASSERT_FALSE(Lexer("+0xffff_ffff"sv).empty());
+ EXPECT_FALSE(Lexer("+0xffff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0xffff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0xffff_ffff"sv).takeU32());
+ EXPECT_FALSE(Lexer("+0xffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0xffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0xffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0xffff_ffff"sv).takeI64(), 0xffffffffull);
+ EXPECT_EQ(*Lexer("+0xffff_ffff"sv).takeF64(), 0xffffffff.p0);
+ EXPECT_EQ(*Lexer("+0xffff_ffff"sv).takeF32(), 0xffffffff.p0f);
+
+ ASSERT_FALSE(Lexer("+0x1_0000_0000"sv).empty());
+ EXPECT_FALSE(Lexer("+0x1_0000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0x1_0000_0000"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0x1_0000_0000"sv).takeU32());
+ EXPECT_FALSE(Lexer("+0x1_0000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0x1_0000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0x1_0000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0x1_0000_0000"sv).takeI64(), 0x100000000ull);
+ EXPECT_EQ(*Lexer("+0x1_0000_0000"sv).takeF64(), 0x100000000.p0);
+ EXPECT_EQ(*Lexer("+0x1_0000_0000"sv).takeF32(), 0x100000000.p0f);
+
+ ASSERT_FALSE(Lexer("0x7fff_ffff_ffff_ffff"sv).empty());
+ ASSERT_TRUE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeU32());
+ EXPECT_FALSE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("0x7fff_ffff_ffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("0x7fff_ffff_ffff_ffff"sv).takeU64(), 0x7fffffffffffffffull);
+ EXPECT_EQ(*Lexer("0x7fff_ffff_ffff_ffff"sv).takeI64(), 0x7fffffffffffffffull);
+ EXPECT_EQ(*Lexer("0x7fff_ffff_ffff_ffff"sv).takeF64(), 0x7fffffffffffffff.p0);
+ EXPECT_EQ(*Lexer("0x7fff_ffff_ffff_ffff"sv).takeF32(),
+ 0x7fffffffffffffff.p0f);
+
+ ASSERT_FALSE(Lexer("+0x7fff_ffff_ffff_ffff"sv).empty());
+ EXPECT_FALSE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeU32());
+ EXPECT_FALSE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0x7fff_ffff_ffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0x7fff_ffff_ffff_ffff"sv).takeI64(),
+ 0x7fffffffffffffffull);
+ EXPECT_EQ(*Lexer("+0x7fff_ffff_ffff_ffff"sv).takeF64(),
+ 0x7fffffffffffffff.p0);
+ EXPECT_EQ(*Lexer("+0x7fff_ffff_ffff_ffff"sv).takeF32(),
+ 0x7fffffffffffffff.p0f);
+
+ ASSERT_FALSE(Lexer("-0x8000_0000_0000_0000"sv).empty());
+ EXPECT_FALSE(Lexer("-0x8000_0000_0000_0000"sv).takeU64());
+ ASSERT_TRUE(Lexer("-0x8000_0000_0000_0000"sv).takeI64());
+ EXPECT_FALSE(Lexer("-0x8000_0000_0000_0000"sv).takeU32());
+ EXPECT_FALSE(Lexer("-0x8000_0000_0000_0000"sv).takeI32());
+ ASSERT_TRUE(Lexer("-0x8000_0000_0000_0000"sv).takeF64());
+ ASSERT_TRUE(Lexer("-0x8000_0000_0000_0000"sv).takeF32());
+ EXPECT_EQ(*Lexer("-0x8000_0000_0000_0000"sv).takeI64(),
+ -0x8000000000000000ull);
+ EXPECT_EQ(*Lexer("-0x8000_0000_0000_0000"sv).takeF64(),
+ -0x8000000000000000.p0);
+ EXPECT_EQ(*Lexer("-0x8000_0000_0000_0000"sv).takeF32(),
+ -0x8000000000000000.p0f);
+
+ ASSERT_FALSE(Lexer("0xffff_ffff_ffff_ffff"sv).empty());
+ ASSERT_TRUE(Lexer("0xffff_ffff_ffff_ffff"sv).takeU64());
+ ASSERT_TRUE(Lexer("0xffff_ffff_ffff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("0xffff_ffff_ffff_ffff"sv).takeU32());
+ EXPECT_FALSE(Lexer("0xffff_ffff_ffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("0xffff_ffff_ffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("0xffff_ffff_ffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("0xffff_ffff_ffff_ffff"sv).takeU64(), 0xffffffffffffffffull);
+ EXPECT_EQ(*Lexer("0xffff_ffff_ffff_ffff"sv).takeI64(), 0xffffffffffffffffull);
+ EXPECT_EQ(*Lexer("0xffff_ffff_ffff_ffff"sv).takeF64(), 0xffffffffffffffff.p0);
+ EXPECT_EQ(*Lexer("0xffff_ffff_ffff_ffff"sv).takeF32(),
+ 0xffffffffffffffff.p0f);
+
+ ASSERT_FALSE(Lexer("+0xffff_ffff_ffff_ffff"sv).empty());
+ EXPECT_FALSE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeU64());
+ EXPECT_FALSE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeI64());
+ EXPECT_FALSE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeU32());
+ EXPECT_FALSE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeI32());
+ ASSERT_TRUE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeF64());
+ ASSERT_TRUE(Lexer("+0xffff_ffff_ffff_ffff"sv).takeF32());
+ EXPECT_EQ(*Lexer("+0xffff_ffff_ffff_ffff"sv).takeF64(),
+ 0xffffffffffffffff.p0);
+ EXPECT_EQ(*Lexer("+0xffff_ffff_ffff_ffff"sv).takeF32(),
+ 0xffffffffffffffff.p0f);
}
TEST(LexerTest, LexFloat) {
- {
- Lexer lexer("42"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42"sv, IntTok{42, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42."sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42."sv, FloatTok{{}, 42.}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.5"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.5"sv, FloatTok{{}, 42.5}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42e0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42e0"sv, FloatTok{{}, 42e0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.e1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.e1"sv, FloatTok{{}, 42.e1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42E1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42E1"sv, FloatTok{{}, 42E1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42e+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42e+2"sv, FloatTok{{}, 42e+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.E-02"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.E-02"sv, FloatTok{{}, 42.E-02}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.0e0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.0e0"sv, FloatTok{{}, 42.0e0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.0E1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.0E1"sv, FloatTok{{}, 42.0E1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.0e+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.0e+2"sv, FloatTok{{}, 42.0e+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("42.0E-2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"42.0E-2"sv, FloatTok{{}, 42.0E-2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+42.0e+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+42.0e+2"sv, FloatTok{{}, +42.0e+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-42.0e+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-42.0e+2"sv, FloatTok{{}, -42.0e+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("4_2.0_0e+0_2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"4_2.0_0e+0_2"sv, FloatTok{{}, 42.00e+02}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42.junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42.0junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42.Ejunk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42.e-junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42.e-10junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("+"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42e"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42eABC"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42e0xABC"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("+-42"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("-+42"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42e+-0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42e-+0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42p0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("42P0"sv);
- EXPECT_TRUE(lexer.empty());
- }
+ EXPECT_EQ(Lexer("42"sv).takeF32(), 42.0f);
+ EXPECT_EQ(Lexer("42"sv).takeF64(), 42.0);
+
+ EXPECT_EQ(Lexer("42.5"sv).takeF32(), 42.5f);
+ EXPECT_EQ(Lexer("42.5"sv).takeF64(), 42.5);
+
+ EXPECT_EQ(Lexer("42e0"sv).takeF32(), 42e0f);
+ EXPECT_EQ(Lexer("42e0"sv).takeF64(), 42e0);
+
+ EXPECT_EQ(Lexer("42.e1"sv).takeF32(), 42.e1f);
+ EXPECT_EQ(Lexer("42.e1"sv).takeF64(), 42.e1);
+
+ EXPECT_EQ(Lexer("42E1"sv).takeF32(), 42E1f);
+ EXPECT_EQ(Lexer("42E1"sv).takeF64(), 42E1);
+
+ EXPECT_EQ(Lexer("42e+2"sv).takeF32(), 42e+2f);
+ EXPECT_EQ(Lexer("42e+2"sv).takeF64(), 42e+2);
+
+ EXPECT_EQ(Lexer("42.E-02"sv).takeF32(), 42.E-02f);
+ EXPECT_EQ(Lexer("42.E-02"sv).takeF64(), 42.E-02);
+
+ EXPECT_EQ(Lexer("42.0e0"sv).takeF32(), 42.0e0f);
+ EXPECT_EQ(Lexer("42.0e0"sv).takeF64(), 42.0e0);
+
+ EXPECT_EQ(Lexer("42.0E1"sv).takeF32(), 42.0E1f);
+ EXPECT_EQ(Lexer("42.0E1"sv).takeF64(), 42.0E1);
+
+ EXPECT_EQ(Lexer("42.0e+2"sv).takeF32(), 42.0e+2f);
+ EXPECT_EQ(Lexer("42.0e+2"sv).takeF64(), 42.0e+2);
+
+ EXPECT_EQ(Lexer("42.0E-2"sv).takeF32(), 42.0E-2f);
+ EXPECT_EQ(Lexer("42.0E-2"sv).takeF64(), 42.0E-2);
+
+ EXPECT_EQ(Lexer("+42.0e+2"sv).takeF32(), +42.0e+2f);
+ EXPECT_EQ(Lexer("+42.0e+2"sv).takeF64(), +42.0e+2);
+
+ EXPECT_EQ(Lexer("-42.0e+2"sv).takeF32(), -42.0e+2f);
+ EXPECT_EQ(Lexer("-42.0e+2"sv).takeF64(), -42.0e+2);
+
+ EXPECT_EQ(Lexer("4_2.0_0e+0_2"sv).takeF32(), 42.00e+02f);
+ EXPECT_EQ(Lexer("4_2.0_0e+0_2"sv).takeF64(), 42.00e+02);
+
+ EXPECT_FALSE(Lexer("+junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("+junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42.junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42.junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42.0junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42.0junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42.Ejunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42.Ejunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42.e-junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42.e-junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42.e-10junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("42.e-10junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("+"sv).takeF32());
+ EXPECT_FALSE(Lexer("+"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42e"sv).takeF32());
+ EXPECT_FALSE(Lexer("42e"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42eABC"sv).takeF32());
+ EXPECT_FALSE(Lexer("42eABC"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42e0xABC"sv).takeF32());
+ EXPECT_FALSE(Lexer("42e0xABC"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("+-42"sv).takeF32());
+ EXPECT_FALSE(Lexer("+-42"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("-+42"sv).takeF32());
+ EXPECT_FALSE(Lexer("-+42"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42e+-0"sv).takeF32());
+ EXPECT_FALSE(Lexer("42e+-0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42e-+0"sv).takeF32());
+ EXPECT_FALSE(Lexer("42e-+0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42p0"sv).takeF32());
+ EXPECT_FALSE(Lexer("42p0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("42P0"sv).takeF32());
+ EXPECT_FALSE(Lexer("42P0"sv).takeF64());
}
TEST(LexerTest, LexHexFloat) {
- {
- Lexer lexer("0x4B"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B"sv, IntTok{0x4B, NoSign}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B."sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B."sv, FloatTok{{}, 0x4Bp0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.5"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.5"sv, FloatTok{{}, 0x4B.5p0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4Bp0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4Bp0"sv, FloatTok{{}, 0x4Bp0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.p1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.p1"sv, FloatTok{{}, 0x4B.p1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4BP1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4BP1"sv, FloatTok{{}, 0x4BP1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4Bp+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4Bp+2"sv, FloatTok{{}, 0x4Bp+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.P-02"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.P-02"sv, FloatTok{{}, 0x4B.P-02}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.0p0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.0p0"sv, FloatTok{{}, 0x4B.0p0}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.0P1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.0P1"sv, FloatTok{{}, 0x4B.0P1}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.0p+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.0p+2"sv, FloatTok{{}, 0x4B.0p+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4B.0P-2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4B.0P-2"sv, FloatTok{{}, 0x4B.0P-2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+0x4B.0p+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+0x4B.0p+2"sv, FloatTok{{}, +0x4B.0p+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-0x4B.0p+2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-0x4B.0p+2"sv, FloatTok{{}, -0x4B.0p+2}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4_2.0_0p+0_2"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"0x4_2.0_0p+0_2"sv, FloatTok{{}, 0x42.00p+02}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("0x4Bjunk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.0junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.Pjunk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.p-junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.p-10junk"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("+0x"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4Bp"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4BpABC"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4Bp0xABC"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x+0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("+-0x4B"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("-+0x4B"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4Bp+-0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4Bp-+0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.e+0"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("0x4B.E-0"sv);
- EXPECT_TRUE(lexer.empty());
- }
+
+ EXPECT_EQ(Lexer("0x4B"sv).takeF32(), 0x4Bp0f);
+ EXPECT_EQ(Lexer("0x4B"sv).takeF64(), 0x4Bp0);
+
+ EXPECT_EQ(Lexer("0x4B."sv).takeF32(), 0x4B.p0f);
+ EXPECT_EQ(Lexer("0x4B."sv).takeF64(), 0x4B.p0);
+
+ EXPECT_EQ(Lexer("0x4B.5"sv).takeF32(), 0x4B.5p0f);
+ EXPECT_EQ(Lexer("0x4B.5"sv).takeF64(), 0x4B.5p0);
+
+ EXPECT_EQ(Lexer("0x4Bp0"sv).takeF32(), 0x4Bp0f);
+ EXPECT_EQ(Lexer("0x4Bp0"sv).takeF64(), 0x4Bp0);
+
+ EXPECT_EQ(Lexer("0x4B.p1"sv).takeF32(), 0x4B.p1f);
+ EXPECT_EQ(Lexer("0x4B.p1"sv).takeF64(), 0x4B.p1);
+
+ EXPECT_EQ(Lexer("0x4BP1"sv).takeF32(), 0x4BP1f);
+ EXPECT_EQ(Lexer("0x4BP1"sv).takeF64(), 0x4BP1);
+
+ EXPECT_EQ(Lexer("0x4Bp+2"sv).takeF32(), 0x4Bp+2f);
+ EXPECT_EQ(Lexer("0x4Bp+2"sv).takeF64(), 0x4Bp+2);
+
+ EXPECT_EQ(Lexer("0x4B.P-02"sv).takeF32(), 0x4B.P-02f);
+ EXPECT_EQ(Lexer("0x4B.P-02"sv).takeF64(), 0x4B.P-02);
+
+ EXPECT_EQ(Lexer("0x4B.0p0"sv).takeF32(), 0x4B.0p0f);
+ EXPECT_EQ(Lexer("0x4B.0p0"sv).takeF64(), 0x4B.0p0);
+
+ EXPECT_EQ(Lexer("0x4B.0P1"sv).takeF32(), 0x4B.0P1f);
+ EXPECT_EQ(Lexer("0x4B.0P1"sv).takeF64(), 0x4B.0P1);
+
+ EXPECT_EQ(Lexer("0x4B.0p+2"sv).takeF32(), 0x4B.0p+2f);
+ EXPECT_EQ(Lexer("0x4B.0p+2"sv).takeF64(), 0x4B.0p+2);
+
+ EXPECT_EQ(Lexer("0x4B.0P-2"sv).takeF32(), 0x4B.0P-2f);
+ EXPECT_EQ(Lexer("0x4B.0P-2"sv).takeF64(), 0x4B.0P-2);
+
+ EXPECT_EQ(Lexer("+0x4B.0p+2"sv).takeF32(), +0x4B.0p+2f);
+ EXPECT_EQ(Lexer("+0x4B.0p+2"sv).takeF64(), +0x4B.0p+2);
+
+ EXPECT_EQ(Lexer("-0x4B.0p+2"sv).takeF32(), -0x4B.0p+2f);
+ EXPECT_EQ(Lexer("-0x4B.0p+2"sv).takeF64(), -0x4B.0p+2);
+
+ EXPECT_EQ(Lexer("0x4_2.0_0p+0_2"sv).takeF32(), 0x42.00p+02f);
+ EXPECT_EQ(Lexer("0x4_2.0_0p+0_2"sv).takeF64(), 0x42.00p+02);
+
+ EXPECT_FALSE(Lexer("0x4Bjunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4Bjunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.0junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.0junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.Pjunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.Pjunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.p-junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.p-junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.p-10junk"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.p-10junk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("+0x"sv).takeF32());
+ EXPECT_FALSE(Lexer("+0x"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4Bp"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4Bp"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4BpABC"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4BpABC"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4Bp0xABC"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4Bp0xABC"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x+0"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x+0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("+-0x4B"sv).takeF32());
+ EXPECT_FALSE(Lexer("+-0x4B"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("-+0x4B"sv).takeF32());
+ EXPECT_FALSE(Lexer("-+0x4B"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4Bp+-0"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4Bp+-0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4Bp-+0"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4Bp-+0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.e+0"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.e+0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("0x4B.E-0"sv).takeF32());
+ EXPECT_FALSE(Lexer("0x4B.E-0"sv).takeF64());
}
TEST(LexerTest, LexInfinity) {
- {
- Lexer lexer("inf"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"inf"sv, FloatTok{{}, INFINITY}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+inf"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+inf"sv, FloatTok{{}, INFINITY}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-inf"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-inf"sv, FloatTok{{}, -INFINITY}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("infjunk"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"infjunk"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("Inf"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("INF"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("infinity"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"infinity"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
+ EXPECT_EQ(Lexer("inf"sv).takeF32(), INFINITY);
+ EXPECT_EQ(Lexer("inf"sv).takeF64(), INFINITY);
+
+ EXPECT_EQ(Lexer("+inf"sv).takeF32(), INFINITY);
+ EXPECT_EQ(Lexer("+inf"sv).takeF64(), INFINITY);
+
+ EXPECT_EQ(Lexer("-inf"sv).takeF32(), -INFINITY);
+ EXPECT_EQ(Lexer("-inf"sv).takeF64(), -INFINITY);
+
+ EXPECT_FALSE(Lexer("infjunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("infjunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("Inf"sv).takeF32());
+ EXPECT_FALSE(Lexer("Inf"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("INF"sv).takeF32());
+ EXPECT_FALSE(Lexer("INF"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("infinity"sv).takeF32());
+ EXPECT_FALSE(Lexer("infinity"sv).takeF64());
}
TEST(LexerTest, LexNan) {
- const double posNan = std::copysign(NAN, 1.0);
- const double negNan = std::copysign(NAN, -1.0);
- {
- Lexer lexer("nan"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan"sv, FloatTok{{}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+nan"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+nan"sv, FloatTok{{}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-nan"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-nan"sv, FloatTok{{}, negNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x01"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x01"sv, FloatTok{{1}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("+nan:0x01"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"+nan:0x01"sv, FloatTok{{1}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("-nan:0x01"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"-nan:0x01"sv, FloatTok{{1}, negNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x1234"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x1234"sv, FloatTok{{0x1234}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0xf_ffff_ffff_ffff"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0xf_ffff_ffff_ffff"sv,
- FloatTok{{0xfffffffffffff}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nanjunk"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nanjunk", KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0xjunk"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0xjunk"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:-0x1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:-0x1"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:+0x1"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:+0x1"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x0"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x0"sv, FloatTok{{0}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x10_0000_0000_0000"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x10_0000_0000_0000"sv,
- FloatTok{{0x10000000000000}, posNan}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("nan:0x1_0000_0000_0000_0000"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"nan:0x1_0000_0000_0000_0000"sv, KeywordTok{}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("NAN"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("NaN"sv);
- EXPECT_TRUE(lexer.empty());
- }
+ ASSERT_TRUE(Lexer("nan"sv).takeF32());
+ ASSERT_TRUE(Lexer("nan"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("+nan"sv).takeF32());
+ ASSERT_TRUE(Lexer("+nan"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("-nan"sv).takeF32());
+ ASSERT_TRUE(Lexer("-nan"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("nan:0x01"sv).takeF32());
+ ASSERT_TRUE(Lexer("nan:0x01"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("+nan:0x01"sv).takeF32());
+ ASSERT_TRUE(Lexer("+nan:0x01"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("-nan:0x01"sv).takeF64());
+ ASSERT_TRUE(Lexer("-nan:0x01"sv).takeF64());
+
+ ASSERT_TRUE(Lexer("nan:0x1234"sv).takeF64());
+ ASSERT_TRUE(Lexer("nan:0x1234"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0xf_ffff_ffff_ffff"sv).takeF32());
+ EXPECT_TRUE(Lexer("nan:0xf_ffff_ffff_ffff"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nanjunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("nanjunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0x"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:0x"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0xjunk"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:0xjunk"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:-0x1"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:-0x1"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:+0x1"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:+0x1"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0x0"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:0x0"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0x10_0000_0000_0000"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:0x10_0000_0000_0000"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("nan:0x1_0000_0000_0000_0000"sv).takeF32());
+ EXPECT_FALSE(Lexer("nan:0x1_0000_0000_0000_0000"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("NAN"sv).takeF32());
+ EXPECT_FALSE(Lexer("NAN"sv).takeF64());
+
+ EXPECT_FALSE(Lexer("NaN"sv).takeF32());
+ EXPECT_FALSE(Lexer("NaN"sv).takeF64());
}
-TEST(LexerTest, ClassifyFloat) {
- constexpr int signif64 = 52;
- constexpr int signif32 = 23;
- constexpr uint64_t payloadMask64 = (1ull << signif64) - 1;
- constexpr uint32_t payloadMask32 = (1u << signif32) - 1;
- constexpr uint64_t dnanDefault = 1ull << (signif64 - 1);
- constexpr uint32_t fnanDefault = 1u << (signif32 - 1);
- {
- Lexer lexer("340282346638528859811704183484516925440."sv);
- ASSERT_FALSE(lexer.empty());
- ASSERT_TRUE(lexer->getF64());
- EXPECT_TRUE(lexer->getF32());
- EXPECT_EQ(*lexer->getF64(), FLT_MAX);
- EXPECT_EQ(*lexer->getF32(), FLT_MAX);
- }
- {
- Lexer lexer("17976931348623157081452742373170435679807056752584499659891747"
- "68031572607800285387605895586327668781715404589535143824642343"
- "21326889464182768467546703537516986049910576551282076245490090"
- "38932894407586850845513394230458323690322294816580855933212334"
- "8274797826204144723168738177180919299881250404026184124858368"
- "."sv);
- ASSERT_FALSE(lexer.empty());
- ASSERT_TRUE(lexer->getF64());
- ASSERT_TRUE(lexer->getF32());
- EXPECT_EQ(*lexer->getF64(), DBL_MAX);
- EXPECT_EQ(*lexer->getF32(), INFINITY);
- }
- {
- Lexer lexer("nan");
- ASSERT_FALSE(lexer.empty());
+constexpr int signif32 = 23;
+constexpr int signif64 = 52;
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
- EXPECT_TRUE(std::isnan(d));
- EXPECT_FALSE(std::signbit(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, dnanDefault);
+uint32_t payload(float f) {
+ uint32_t x;
+ static_assert(sizeof(f) == sizeof(x));
+ memcpy(&x, &f, sizeof(f));
+ return x & ((1u << signif32) - 1);
+}
+
+uint64_t payload(double d) {
+ uint64_t x;
+ static_assert(sizeof(d) == sizeof(x));
+ memcpy(&x, &d, sizeof(d));
+ return x & ((1ull << signif64) - 1);
+}
- ASSERT_TRUE(lexer->getF32());
- float f = *lexer->getF32();
+constexpr uint32_t fnanDefault = 1u << (signif32 - 1);
+constexpr uint64_t dnanDefault = 1ull << (signif64 - 1);
+
+TEST(LexerTest, ClassifyFloat) {
+ auto flt_max = "340282346638528859811704183484516925440."sv;
+ EXPECT_EQ(Lexer(flt_max).takeF32(), FLT_MAX);
+ EXPECT_EQ(Lexer(flt_max).takeF64(), FLT_MAX);
+
+ auto dbl_max =
+ "17976931348623157081452742373170435679807056752584499659891747"
+ "68031572607800285387605895586327668781715404589535143824642343"
+ "21326889464182768467546703537516986049910576551282076245490090"
+ "38932894407586850845513394230458323690322294816580855933212334"
+ "8274797826204144723168738177180919299881250404026184124858368"
+ "."sv;
+ EXPECT_EQ(Lexer(dbl_max).takeF32(), INFINITY);
+ EXPECT_EQ(Lexer(dbl_max).takeF64(), DBL_MAX);
+
+ {
+ auto nan = "nan"sv;
+ ASSERT_TRUE(Lexer(nan).takeF32());
+ float f = *Lexer(nan).takeF32();
EXPECT_TRUE(std::isnan(f));
EXPECT_FALSE(std::signbit(f));
- uint32_t fbits;
- memcpy(&fbits, &f, sizeof(fbits));
- EXPECT_EQ(fbits & payloadMask32, fnanDefault);
+ EXPECT_EQ(payload(f), fnanDefault);
+
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
+ EXPECT_TRUE(std::isnan(d));
+ EXPECT_FALSE(std::signbit(d));
+ EXPECT_EQ(payload(d), dnanDefault);
}
{
- Lexer lexer("-nan");
- ASSERT_FALSE(lexer.empty());
+ auto nan = "-nan"sv;
+ ASSERT_TRUE(Lexer(nan).takeF32());
+ float f = *Lexer(nan).takeF32();
+ EXPECT_TRUE(std::isnan(f));
+ EXPECT_TRUE(std::signbit(f));
+ EXPECT_EQ(payload(f), fnanDefault);
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
EXPECT_TRUE(std::isnan(d));
EXPECT_TRUE(std::signbit(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, dnanDefault);
-
- ASSERT_TRUE(lexer->getF32());
- float f = *lexer->getF32();
- EXPECT_TRUE(std::isnan(f));
- EXPECT_TRUE(std::signbit(f));
- uint32_t fbits;
- memcpy(&fbits, &f, sizeof(fbits));
- EXPECT_EQ(fbits & payloadMask32, fnanDefault);
+ EXPECT_EQ(payload(d), dnanDefault);
}
{
- Lexer lexer("+nan");
- ASSERT_FALSE(lexer.empty());
+ auto nan = "+nan"sv;
+ ASSERT_TRUE(Lexer(nan).takeF32());
+ float f = *Lexer(nan).takeF32();
+ EXPECT_TRUE(std::isnan(f));
+ EXPECT_FALSE(std::signbit(f));
+ EXPECT_EQ(payload(f), fnanDefault);
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
EXPECT_TRUE(std::isnan(d));
EXPECT_FALSE(std::signbit(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, dnanDefault);
-
- ASSERT_TRUE(lexer->getF32());
- float f = *lexer->getF32();
- EXPECT_TRUE(std::isnan(f));
- EXPECT_FALSE(std::signbit(f));
- uint32_t fbits;
- memcpy(&fbits, &f, sizeof(fbits));
- EXPECT_EQ(fbits & payloadMask32, fnanDefault);
+ EXPECT_EQ(payload(d), dnanDefault);
}
{
- Lexer lexer("nan:0x1234");
- ASSERT_FALSE(lexer.empty());
+ auto nan = "nan:0x1234"sv;
+ ASSERT_TRUE(Lexer(nan).takeF32());
+ float f = *Lexer(nan).takeF32();
+ EXPECT_TRUE(std::isnan(f));
+ EXPECT_FALSE(std::signbit(f));
+ EXPECT_EQ(payload(f), uint32_t(0x1234));
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
EXPECT_TRUE(std::isnan(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, 0x1234ull);
-
- ASSERT_TRUE(lexer->getF32());
- float f = *lexer->getF32();
- EXPECT_TRUE(std::isnan(f));
- uint32_t fbits;
- memcpy(&fbits, &f, sizeof(fbits));
- EXPECT_EQ(fbits & payloadMask32, 0x1234u);
+ EXPECT_FALSE(std::signbit(d));
+ EXPECT_EQ(payload(d), uint64_t(0x1234));
}
{
- Lexer lexer("nan:0x7FFFFF");
- ASSERT_FALSE(lexer.empty());
+ auto nan = "nan:0x7FFFFF"sv;
+ ASSERT_TRUE(Lexer(nan).takeF32());
+ float f = *Lexer(nan).takeF32();
+ EXPECT_TRUE(std::isnan(f));
+ EXPECT_FALSE(std::signbit(f));
+ EXPECT_EQ(payload(f), uint32_t(0x7FFFFF));
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
EXPECT_TRUE(std::isnan(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, 0x7fffffull);
-
- ASSERT_TRUE(lexer->getF32());
- float f = *lexer->getF32();
- EXPECT_TRUE(std::isnan(f));
- uint32_t fbits;
- memcpy(&fbits, &f, sizeof(fbits));
- EXPECT_EQ(fbits & payloadMask32, 0x7fffffu);
+ EXPECT_FALSE(std::signbit(d));
+ EXPECT_EQ(payload(d), uint64_t(0x7FFFFF));
}
{
- Lexer lexer("nan:0x800000");
- ASSERT_FALSE(lexer.empty());
+ auto nan = "nan:0x800000"sv;
+ EXPECT_FALSE(Lexer(nan).takeF32());
- ASSERT_TRUE(lexer->getF64());
- double d = *lexer->getF64();
+ ASSERT_TRUE(Lexer(nan).takeF64());
+ double d = *Lexer(nan).takeF64();
EXPECT_TRUE(std::isnan(d));
- uint64_t dbits;
- memcpy(&dbits, &d, sizeof(dbits));
- EXPECT_EQ(dbits & payloadMask64, 0x800000ull);
-
- ASSERT_FALSE(lexer->getF32());
+ EXPECT_FALSE(std::signbit(d));
+ EXPECT_EQ(payload(d), uint64_t(0x800000));
}
- {
- Lexer lexer("nan:0x0");
- ASSERT_FALSE(lexer.empty());
- ASSERT_FALSE(lexer->getF64());
- ASSERT_FALSE(lexer->getF32());
+ {
+ auto nan = "nan:0x0"sv;
+ EXPECT_FALSE(Lexer(nan).takeF32());
+ EXPECT_FALSE(Lexer(nan).takeF64());
}
}
TEST(LexerTest, LexIdent) {
- {
- Lexer lexer("$09azAZ!#$%&'*+-./:<=>?@\\^_`|~"sv);
- ASSERT_FALSE(lexer.empty());
- Token expected{"$09azAZ!#$%&'*+-./:<=>?@\\^_`|~"sv, IdTok{}};
- EXPECT_EQ(*lexer, expected);
- EXPECT_TRUE(lexer->getID());
- EXPECT_EQ(*lexer->getID(), "09azAZ!#$%&'*+-./:<=>?@\\^_`|~"sv);
- }
- {
- Lexer lexer("$[]{}"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("$abc[]"sv);
- EXPECT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("$"sv);
- EXPECT_TRUE(lexer.empty());
- }
+ EXPECT_EQ(Lexer("$09azAZ!#$%&'*+-./:<=>?@\\^_`|~"sv).takeID(),
+ wasm::Name("09azAZ!#$%&'*+-./:<=>?@\\^_`|~"sv));
+ EXPECT_FALSE(Lexer("$[]{}"sv).takeID());
+ EXPECT_FALSE(Lexer("$abc[]"sv).takeID());
+ EXPECT_FALSE(Lexer("$"sv).takeID());
// String IDs
- {
- Lexer lexer("$\"\"");
- ASSERT_FALSE(lexer.empty());
- Token expected{"$\"\""sv, IdTok{true, std::nullopt}};
- EXPECT_EQ(*lexer, expected);
- EXPECT_TRUE(lexer->getID());
- EXPECT_EQ(*lexer->getID(), ""sv);
- }
- {
- Lexer lexer("$\"hello\"");
- ASSERT_FALSE(lexer.empty());
- Token expected{"$\"hello\""sv, IdTok{true, std::nullopt}};
- EXPECT_EQ(*lexer, expected);
- EXPECT_TRUE(lexer->getID());
- EXPECT_EQ(*lexer->getID(), "hello"sv);
- }
- {
- // _$_£_€_𐍈_
- auto unicode = "$\"_\\u{24}_\\u{00a3}_\\u{20AC}_\\u{10348}_\""sv;
- Lexer lexer(unicode);
- ASSERT_FALSE(lexer.empty());
- std::string escaped{"_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_"};
- Token expected{unicode, IdTok{true, {escaped}}};
- EXPECT_EQ(*lexer, expected);
- }
+ EXPECT_EQ(Lexer("$\"\""sv).takeID(), wasm::Name(""sv));
+ EXPECT_EQ(Lexer("$\"hello\""sv).takeID(), wasm::Name("hello"sv));
+ // _$_£_€_𐍈_
+ EXPECT_EQ(Lexer("$\"_\\u{24}_\\u{00a3}_\\u{20AC}_\\u{10348}_\""sv).takeID(),
+ wasm::Name("_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_"sv));
}
TEST(LexerTest, LexString) {
- {
- auto pangram = "\"The quick brown fox jumps over the lazy dog\""sv;
- Lexer lexer(pangram);
- ASSERT_FALSE(lexer.empty());
- Token expected{pangram, StringTok{{}}};
- EXPECT_EQ(*lexer, expected);
- EXPECT_TRUE(lexer->getString());
- EXPECT_EQ(*lexer->getString(),
- "The quick brown fox jumps over the lazy dog"sv);
- }
- {
- auto chars = "\"`~!@#$%^&*()_-+0123456789|,.<>/?;:'\""sv;
- Lexer lexer(chars);
- ASSERT_FALSE(lexer.empty());
- Token expected{chars, StringTok{{}}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- auto escapes = "\"_\\t_\\n_\\r_\\\\_\\\"_\\'_\""sv;
- Lexer lexer(escapes);
- ASSERT_FALSE(lexer.empty());
- Token expected{escapes, StringTok{{"_\t_\n_\r_\\_\"_'_"}}};
- EXPECT_EQ(*lexer, expected);
- EXPECT_TRUE(lexer->getString());
- EXPECT_EQ(*lexer->getString(), "_\t_\n_\r_\\_\"_'_"sv);
- }
- {
- auto escapes = "\"_\\00_\\07_\\20_\\5A_\\7F_\\ff_\\ffff_\""sv;
- Lexer lexer(escapes);
- ASSERT_FALSE(lexer.empty());
- std::string escaped{"_\0_\7_ _Z_\x7f_\xff_\xff"
- "ff_"sv};
- Token expected{escapes, StringTok{{escaped}}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- // _$_£_€_𐍈_
- auto unicode = "\"_\\u{24}_\\u{00a3}_\\u{20AC}_\\u{10348}_\""sv;
- Lexer lexer(unicode);
- ASSERT_FALSE(lexer.empty());
- std::string escaped{"_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_"};
- Token expected{unicode, StringTok{{escaped}}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- // _$_£_€_𐍈_
- auto unicode = "\"_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_\""sv;
- Lexer lexer(unicode);
- ASSERT_FALSE(lexer.empty());
- Token expected{unicode, StringTok{{}}};
- EXPECT_EQ(*lexer, expected);
- }
- {
- Lexer lexer("\"unterminated"sv);
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"unescaped nul\0\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"unescaped U+19\x19\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"unescaped U+7f\x7f\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"\\ stray backslash\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"short \\f hex escape\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"bad hex \\gg\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"empty unicode \\u{}\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"not unicode \\u{abcdefg}\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"extra chars \\u{123(}\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"unpaired surrogate unicode crimes \\u{d800}\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"more surrogate unicode crimes \\u{dfff}\"");
- ASSERT_TRUE(lexer.empty());
- }
- {
- Lexer lexer("\"too big \\u{110000}\"");
- ASSERT_TRUE(lexer.empty());
- }
+ using namespace std::string_literals;
+ EXPECT_EQ(
+ Lexer("\"The quick brown fox jumps over the lazy dog\""sv).takeString(),
+ "The quick brown fox jumps over the lazy dog");
+ EXPECT_EQ(Lexer("\"`~!@#$%^&*()_-+0123456789|,.<>/?;:'\""sv).takeString(),
+ "`~!@#$%^&*()_-+0123456789|,.<>/?;:'");
+ EXPECT_EQ(Lexer("\"_\\t_\\n_\\r_\\\\_\\\"_\\'_\""sv).takeString(),
+ "_\t_\n_\r_\\_\"_\'_");
+ EXPECT_EQ(Lexer("\"_\\00_\\07_\\20_\\5A_\\7F_\\ff_\\ffff_\""sv).takeString(),
+ "_\0_\7_ _Z_\x7f_\xff_\xff"s + "ff_"s);
+ // _$_£_€_𐍈_
+ EXPECT_EQ(
+ Lexer("\"_\\u{24}_\\u{00a3}_\\u{20AC}_\\u{10348}_\""sv).takeString(),
+ "_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_"s);
+ EXPECT_EQ(
+ Lexer("\"_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_\""sv).takeString(),
+ "_$_\xC2\xA3_\xE2\x82\xAC_\xF0\x90\x8D\x88_"s);
+
+ EXPECT_FALSE(Lexer("\"unterminated"sv).takeString());
+ EXPECT_FALSE(Lexer("\"unescaped nul\0\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"unescaped U+19\x19\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"unescaped U+7f\x7f\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"\\ stray backslash\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"short \\f hex escape\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"bad hex \\gg\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"empty unicode \\u{}\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"not unicode \\u{abcdefg}\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"extra chars \\u{123(}\""sv).takeString());
+ EXPECT_FALSE(
+ Lexer("\"unpaired surrogate unicode crimes \\u{d800}\""sv).takeString());
+ EXPECT_FALSE(
+ Lexer("\"more surrogate unicode crimes \\u{dfff}\""sv).takeString());
+ EXPECT_FALSE(Lexer("\"too big \\u{110000}\""sv).takeString());
}
TEST(LexerTest, LexKeywords) {
- Token module{"module"sv, KeywordTok{}};
- Token type{"type"sv, KeywordTok{}};
- Token func{"func"sv, KeywordTok{}};
- Token import{"import"sv, KeywordTok{}};
- Token reserved{"rEsErVeD"sv, KeywordTok{}};
-
Lexer lexer("module type func import rEsErVeD");
-
- auto it = lexer.begin();
- ASSERT_NE(it, lexer.end());
- Token t1 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t2 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t3 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t4 = *it++;
- ASSERT_NE(it, lexer.end());
- Token t5 = *it++;
- EXPECT_EQ(it, lexer.end());
-
- EXPECT_EQ(t1, module);
- EXPECT_EQ(t2, type);
- EXPECT_EQ(t3, func);
- EXPECT_EQ(t4, import);
- EXPECT_EQ(t5, reserved);
-
- EXPECT_TRUE(t1.getKeyword());
- EXPECT_EQ(*t1.getKeyword(), "module"sv);
+ ASSERT_EQ(lexer.takeKeyword(), "module"sv);
+ ASSERT_EQ(lexer.takeKeyword(), "type"sv);
+ ASSERT_EQ(lexer.takeKeyword(), "func"sv);
+ ASSERT_EQ(lexer.takeKeyword(), "import"sv);
+ ASSERT_EQ(lexer.takeKeyword(), "rEsErVeD"sv);
+ ASSERT_TRUE(lexer.empty());
}