summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/input-impl.h66
-rw-r--r--src/parser/input.h11
-rw-r--r--src/parser/lexer.cpp71
-rw-r--r--src/parser/lexer.h10
4 files changed, 50 insertions, 108 deletions
diff --git a/src/parser/input-impl.h b/src/parser/input-impl.h
index 0f8fc2e86..3ffce07f8 100644
--- a/src/parser/input-impl.h
+++ b/src/parser/input-impl.h
@@ -100,7 +100,7 @@ inline std::optional<uint64_t> ParseInput::takeOffset() {
if (subLexer == subLexer.end()) {
return {};
}
- if (auto o = subLexer->getU64()) {
+ if (auto o = subLexer->getU<uint64_t>()) {
++subLexer;
if (subLexer == subLexer.end()) {
++lexer;
@@ -122,7 +122,7 @@ inline std::optional<uint32_t> ParseInput::takeAlign() {
if (subLexer == subLexer.end()) {
return {};
}
- if (auto a = subLexer->getU32()) {
+ if (auto a = subLexer->getU<uint32_t>()) {
++subLexer;
if (subLexer == subLexer.end()) {
++lexer;
@@ -134,9 +134,9 @@ inline std::optional<uint32_t> ParseInput::takeAlign() {
return {};
}
-inline std::optional<uint64_t> ParseInput::takeU64() {
+template<typename T> inline std::optional<T> ParseInput::takeU() {
if (auto t = peek()) {
- if (auto n = t->getU64()) {
+ if (auto n = t->getU<T>()) {
++lexer;
return n;
}
@@ -144,67 +144,33 @@ inline std::optional<uint64_t> ParseInput::takeU64() {
return std::nullopt;
}
-inline std::optional<int64_t> ParseInput::takeS64() {
+template<typename T> inline std::optional<T> ParseInput::takeI() {
if (auto t = peek()) {
- if (auto n = t->getS64()) {
+ if (auto n = t->getI<T>()) {
++lexer;
return n;
}
}
- return {};
+ return std::nullopt;
}
-inline std::optional<int64_t> ParseInput::takeI64() {
- if (auto t = peek()) {
- if (auto n = t->getI64()) {
- ++lexer;
- return n;
- }
- }
- return {};
+inline std::optional<uint64_t> ParseInput::takeU64() {
+ return takeU<uint64_t>();
}
-inline std::optional<uint32_t> ParseInput::takeU32() {
- if (auto t = peek()) {
- if (auto n = t->getU32()) {
- ++lexer;
- return n;
- }
- }
- return std::nullopt;
+inline std::optional<uint64_t> ParseInput::takeI64() {
+ return takeI<uint64_t>();
}
-inline std::optional<int32_t> ParseInput::takeS32() {
- if (auto t = peek()) {
- if (auto n = t->getS32()) {
- ++lexer;
- return n;
- }
- }
- return {};
+inline std::optional<uint32_t> ParseInput::takeU32() {
+ return takeU<uint64_t>();
}
-inline std::optional<int32_t> ParseInput::takeI32() {
- if (auto t = peek()) {
- if (auto n = t->getI32()) {
- ++lexer;
- return n;
- }
- }
- return {};
+inline std::optional<uint32_t> ParseInput::takeI32() {
+ return takeI<uint32_t>();
}
-inline std::optional<uint8_t> ParseInput::takeU8() {
- if (auto t = peek()) {
- if (auto n = t->getU32()) {
- if (n <= std::numeric_limits<uint8_t>::max()) {
- ++lexer;
- return uint8_t(*n);
- }
- }
- }
- return {};
-}
+inline std::optional<uint8_t> ParseInput::takeU8() { return takeU<uint8_t>(); }
inline std::optional<double> ParseInput::takeF64() {
if (auto t = peek()) {
diff --git a/src/parser/input.h b/src/parser/input.h
index dbf3e4868..d4fdde1bd 100644
--- a/src/parser/input.h
+++ b/src/parser/input.h
@@ -51,11 +51,9 @@ struct ParseInput {
std::optional<uint64_t> takeOffset();
std::optional<uint32_t> takeAlign();
std::optional<uint64_t> takeU64();
- std::optional<int64_t> takeS64();
- std::optional<int64_t> takeI64();
+ std::optional<uint64_t> takeI64();
std::optional<uint32_t> takeU32();
- std::optional<int32_t> takeS32();
- std::optional<int32_t> takeI32();
+ std::optional<uint32_t> takeI32();
std::optional<uint8_t> takeU8();
std::optional<double> takeF64();
std::optional<float> takeF32();
@@ -67,6 +65,11 @@ struct ParseInput {
Index getPos();
[[nodiscard]] Err err(Index pos, std::string reason);
[[nodiscard]] Err err(std::string reason) { return err(getPos(), reason); }
+
+private:
+ template<typename T> std::optional<T> takeU();
+ template<typename T> std::optional<T> takeS();
+ template<typename T> std::optional<T> takeI();
};
#include "input-impl.h"
diff --git a/src/parser/lexer.cpp b/src/parser/lexer.cpp
index 0796013fe..288660c76 100644
--- a/src/parser/lexer.cpp
+++ b/src/parser/lexer.cpp
@@ -767,77 +767,52 @@ std::optional<LexResult> keyword(std::string_view in) {
} // anonymous namespace
-std::optional<uint64_t> Token::getU64() const {
+template<typename T> std::optional<T> Token::getU() const {
+ static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>);
if (auto* tok = std::get_if<IntTok>(&data)) {
- if (tok->sign == NoSign) {
- return tok->n;
- }
- }
- return {};
-}
-
-std::optional<int64_t> Token::getS64() const {
- if (auto* tok = std::get_if<IntTok>(&data)) {
- if (tok->sign == Neg) {
- if (uint64_t(INT64_MIN) <= tok->n || tok->n == 0) {
- return int64_t(tok->n);
- }
- // TODO: Add error production for signed underflow.
- } else {
- if (tok->n <= uint64_t(INT64_MAX)) {
- return int64_t(tok->n);
- }
- // TODO: Add error production for signed overflow.
- }
- }
- return {};
-}
-
-std::optional<uint64_t> Token::getI64() const {
- if (auto n = getU64()) {
- return *n;
- }
- if (auto n = getS64()) {
- return *n;
- }
- return {};
-}
-
-std::optional<uint32_t> Token::getU32() const {
- if (auto* tok = std::get_if<IntTok>(&data)) {
- if (tok->sign == NoSign && tok->n <= UINT32_MAX) {
- return int32_t(tok->n);
+ if (tok->sign == NoSign && tok->n <= std::numeric_limits<T>::max()) {
+ return T(tok->n);
}
// TODO: Add error production for unsigned overflow.
}
return {};
}
-std::optional<int32_t> Token::getS32() const {
+template<typename T> std::optional<T> Token::getS() const {
+ static_assert(std::is_integral_v<T> && std::is_signed_v<T>);
if (auto* tok = std::get_if<IntTok>(&data)) {
if (tok->sign == Neg) {
- if (uint64_t(INT32_MIN) <= tok->n || tok->n == 0) {
- return int32_t(tok->n);
+ if (uint64_t(std::numeric_limits<T>::min()) <= tok->n || tok->n == 0) {
+ return T(tok->n);
}
} else {
- if (tok->n <= uint64_t(INT32_MAX)) {
- return int32_t(tok->n);
+ if (tok->n <= uint64_t(std::numeric_limits<T>::max())) {
+ return T(tok->n);
}
}
}
return {};
}
-std::optional<uint32_t> Token::getI32() const {
- if (auto n = getU32()) {
+template<typename T> std::optional<T> Token::getI() const {
+ static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>);
+ if (auto n = getU<T>()) {
return *n;
}
- if (auto n = getS32()) {
- return uint32_t(*n);
+ if (auto n = getS<std::make_signed_t<T>>()) {
+ return T(*n);
}
return {};
}
+template std::optional<uint64_t> Token::getU<uint64_t>() const;
+template std::optional<int64_t> Token::getS<int64_t>() const;
+template std::optional<uint64_t> Token::getI<uint64_t>() const;
+template std::optional<uint32_t> Token::getU<uint32_t>() const;
+template std::optional<int32_t> Token::getS<int32_t>() const;
+template std::optional<uint32_t> Token::getI<uint32_t>() const;
+template std::optional<uint8_t> Token::getU<uint8_t>() const;
+
std::optional<double> Token::getF64() const {
constexpr int signif = 52;
constexpr uint64_t payloadMask = (1ull << signif) - 1;
diff --git a/src/parser/lexer.h b/src/parser/lexer.h
index 67d29b002..42b18508e 100644
--- a/src/parser/lexer.h
+++ b/src/parser/lexer.h
@@ -125,12 +125,10 @@ struct Token {
}
return {};
}
- std::optional<uint64_t> getU64() const;
- std::optional<int64_t> getS64() const;
- std::optional<uint64_t> getI64() const;
- std::optional<uint32_t> getU32() const;
- std::optional<int32_t> getS32() const;
- std::optional<uint32_t> getI32() const;
+
+ template<typename T> std::optional<T> getU() const;
+ template<typename T> std::optional<T> getS() const;
+ template<typename T> std::optional<T> getI() const;
std::optional<double> getF64() const;
std::optional<float> getF32() const;
std::optional<std::string_view> getString() const;