@@ -28,6 +28,7 @@ using namespace std::string_view_literals;
2828// Types
2929template <typename Ctx> Result<typename Ctx::HeapTypeT> heaptype (Ctx&);
3030template <typename Ctx> MaybeResult<typename Ctx::RefTypeT> reftype (Ctx&);
31+ template <typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype (Ctx&);
3132template <typename Ctx> Result<typename Ctx::TypeT> valtype (Ctx&);
3233template <typename Ctx> MaybeResult<typename Ctx::ParamsT> params (Ctx&);
3334template <typename Ctx> MaybeResult<typename Ctx::ResultsT> results (Ctx&);
@@ -365,15 +366,34 @@ template<typename Ctx> MaybeResult<typename Ctx::TypeT> reftype(Ctx& ctx) {
365366 return ctx.makeRefType (*type, nullability);
366367}
367368
369+ // tupletype ::= '(' 'tuple' valtype* ')'
370+ template <typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype (Ctx& ctx) {
371+ if (!ctx.in .takeSExprStart (" tuple" sv)) {
372+ return {};
373+ }
374+ auto elems = ctx.makeTupleElemList ();
375+ size_t numElems = 0 ;
376+ while (!ctx.in .takeRParen ()) {
377+ auto elem = singlevaltype (ctx);
378+ CHECK_ERR (elem);
379+ ctx.appendTupleElem (elems, *elem);
380+ ++numElems;
381+ }
382+ if (numElems < 2 ) {
383+ return ctx.in .err (" tuples must have at least two elements" );
384+ }
385+ return ctx.makeTupleType (elems);
386+ }
387+
368388// numtype ::= 'i32' => i32
369389// | 'i64' => i64
370390// | 'f32' => f32
371391// | 'f64' => f64
372392// vectype ::= 'v128' => v128
373- // valtype ::= t:numtype => t
374- // | t:vectype => t
375- // | t:reftype => t
376- template <typename Ctx> Result<typename Ctx::TypeT> valtype (Ctx& ctx) {
393+ // singlevaltype ::= t:numtype => t
394+ // | t:vectype => t
395+ // | t:reftype => t
396+ template <typename Ctx> Result<typename Ctx::TypeT> singlevaltype (Ctx& ctx) {
377397 if (ctx.in .takeKeyword (" i32" sv)) {
378398 return ctx.makeI32 ();
379399 } else if (ctx.in .takeKeyword (" i64" sv)) {
@@ -392,6 +412,15 @@ template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx& ctx) {
392412 }
393413}
394414
415+ // valtype ::= singlevaltype | tupletype
416+ template <typename Ctx> Result<typename Ctx::TypeT> valtype (Ctx& ctx) {
417+ if (auto type = tupletype (ctx)) {
418+ CHECK_ERR (type);
419+ return *type;
420+ }
421+ return singlevaltype (ctx);
422+ }
423+
395424// param ::= '(' 'param id? t:valtype ')' => [t]
396425// | '(' 'param t*:valtype* ')' => [t*]
397426// params ::= param*
0 commit comments