summaryrefslogtreecommitdiff
path: root/src/parser/parsers.h
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-01-29 15:36:41 -0800
committerGitHub <noreply@github.com>2024-01-29 15:36:41 -0800
commit9a31d7e351910191af2c00a9834bcb2e81a28d12 (patch)
tree015dbbd8436df56b3bf43edcce6ca32e469c0ea7 /src/parser/parsers.h
parent053b591652865ce7959602f73eef56e6c09666b5 (diff)
downloadbinaryen-9a31d7e351910191af2c00a9834bcb2e81a28d12.tar.gz
binaryen-9a31d7e351910191af2c00a9834bcb2e81a28d12.tar.bz2
binaryen-9a31d7e351910191af2c00a9834bcb2e81a28d12.zip
[Parser] Parse tuple types (#6249)
Use the new `(tuple ...)` syntax. Enforce that tuples have a valid number of elements and are not nested to avoid assertion failures when parsing invalid input.
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r--src/parser/parsers.h37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 0c7c5550f..706c6525e 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -28,6 +28,7 @@ using namespace std::string_view_literals;
// Types
template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::RefTypeT> reftype(Ctx&);
+template<typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype(Ctx&);
template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::ParamsT> params(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::ResultsT> results(Ctx&);
@@ -365,15 +366,34 @@ template<typename Ctx> MaybeResult<typename Ctx::TypeT> reftype(Ctx& ctx) {
return ctx.makeRefType(*type, nullability);
}
+// tupletype ::= '(' 'tuple' valtype* ')'
+template<typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype(Ctx& ctx) {
+ if (!ctx.in.takeSExprStart("tuple"sv)) {
+ return {};
+ }
+ auto elems = ctx.makeTupleElemList();
+ size_t numElems = 0;
+ while (!ctx.in.takeRParen()) {
+ auto elem = singlevaltype(ctx);
+ CHECK_ERR(elem);
+ ctx.appendTupleElem(elems, *elem);
+ ++numElems;
+ }
+ if (numElems < 2) {
+ return ctx.in.err("tuples must have at least two elements");
+ }
+ return ctx.makeTupleType(elems);
+}
+
// numtype ::= 'i32' => i32
// | 'i64' => i64
// | 'f32' => f32
// | 'f64' => f64
// vectype ::= 'v128' => v128
-// valtype ::= t:numtype => t
-// | t:vectype => t
-// | t:reftype => t
-template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx& ctx) {
+// singlevaltype ::= t:numtype => t
+// | t:vectype => t
+// | t:reftype => t
+template<typename Ctx> Result<typename Ctx::TypeT> singlevaltype(Ctx& ctx) {
if (ctx.in.takeKeyword("i32"sv)) {
return ctx.makeI32();
} else if (ctx.in.takeKeyword("i64"sv)) {
@@ -392,6 +412,15 @@ template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx& ctx) {
}
}
+// valtype ::= singlevaltype | tupletype
+template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx& ctx) {
+ if (auto type = tupletype(ctx)) {
+ CHECK_ERR(type);
+ return *type;
+ }
+ return singlevaltype(ctx);
+}
+
// param ::= '(' 'param id? t:valtype ')' => [t]
// | '(' 'param t*:valtype* ')' => [t*]
// params ::= param*