diff options
Diffstat (limited to 'src/parser/input-impl.h')
-rw-r--r-- | src/parser/input-impl.h | 273 |
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 |