Skip to content

[Parser] Parse tuple types #6249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct TypeUse {
struct NullTypeParserCtx {
using IndexT = Ok;
using HeapTypeT = Ok;
using TupleElemListT = Ok;
using TypeT = Ok;
using ParamsT = Ok;
using ResultsT = size_t;
Expand Down Expand Up @@ -122,6 +123,10 @@ struct NullTypeParserCtx {

TypeT makeRefType(HeapTypeT, Nullability) { return Ok{}; }

TupleElemListT makeTupleElemList() { return Ok{}; }
void appendTupleElem(TupleElemListT&, TypeT) {}
TypeT makeTupleType(TupleElemListT) { return Ok{}; }

ParamsT makeParams() { return Ok{}; }
void appendParam(ParamsT&, Name, TypeT) {}

Expand Down Expand Up @@ -219,7 +224,13 @@ template<typename Ctx> struct TypeParserCtx {
return Type(ht, nullability);
}

TypeT makeTupleType(const std::vector<Type> types) { return Tuple(types); }
std::vector<Type> makeTupleElemList() { return {}; }
void appendTupleElem(std::vector<Type>& elems, Type elem) {
elems.push_back(elem);
}
Result<TypeT> makeTupleType(const std::vector<Type>& types) {
return Tuple(types);
}

ParamsT makeParams() { return {}; }
void appendParam(ParamsT& params, Name id, TypeT type) {
Expand Down
37 changes: 33 additions & 4 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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&);
Expand Down Expand Up @@ -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)) {
Expand All @@ -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*
Expand Down
8 changes: 7 additions & 1 deletion test/lit/wat-kitchen-sink.wast
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,12 @@
;; CHECK-NEXT: )
(func $f4 (type 18) (local i32 i64) (local $l f32))

;; CHECK: (func $tuple-locals (type $void)
;; CHECK-NEXT: (local $0 (tuple i32 i32))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $tuple-locals (local (tuple i32 i32)))

;; CHECK: (func $nop-skate (type $void)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (nop)
Expand Down Expand Up @@ -3519,7 +3525,7 @@
(func $ref-func
ref.func $ref-func
drop
ref.func 151
ref.func 152
drop
)

Expand Down