summaryrefslogtreecommitdiff
path: root/src/parser/input-impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/input-impl.h')
-rw-r--r--src/parser/input-impl.h273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/parser/input-impl.h b/src/parser/input-impl.h
new file mode 100644
index 000000000..35a39b2f3
--- /dev/null
+++ b/src/parser/input-impl.h
@@ -0,0 +1,273 @@
+/*
+ * 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->getU64()) {
+ ++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->getU32()) {
+ ++subLexer;
+ if (subLexer == subLexer.end()) {
+ ++lexer;
+ return a;
+ }
+ }
+ }
+ }
+ return {};
+}
+
+inline std::optional<uint64_t> ParseInput::takeU64() {
+ if (auto t = peek()) {
+ if (auto n = t->getU64()) {
+ ++lexer;
+ return n;
+ }
+ }
+ return std::nullopt;
+}
+
+inline std::optional<int64_t> ParseInput::takeS64() {
+ if (auto t = peek()) {
+ if (auto n = t->getS64()) {
+ ++lexer;
+ return n;
+ }
+ }
+ return {};
+}
+
+inline std::optional<int64_t> ParseInput::takeI64() {
+ if (auto t = peek()) {
+ if (auto n = t->getI64()) {
+ ++lexer;
+ return n;
+ }
+ }
+ return {};
+}
+
+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<int32_t> ParseInput::takeS32() {
+ if (auto t = peek()) {
+ if (auto n = t->getS32()) {
+ ++lexer;
+ return n;
+ }
+ }
+ return {};
+}
+
+inline std::optional<int32_t> ParseInput::takeI32() {
+ if (auto t = peek()) {
+ if (auto n = t->getI32()) {
+ ++lexer;
+ return n;
+ }
+ }
+ return {};
+}
+
+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<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_view> ParseInput::takeString() {
+ if (auto t = peek()) {
+ if (auto s = t->getString()) {
+ ++lexer;
+ return 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 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