summaryrefslogtreecommitdiff
path: root/src/parser/parsers.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r--src/parser/parsers.h53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 41e625657..9201314dc 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -174,6 +174,7 @@ template<typename Ctx> MaybeResult<typename Ctx::MemoryIdxT> maybeMemuse(Ctx&);
template<typename Ctx> Result<typename Ctx::GlobalIdxT> globalidx(Ctx&);
template<typename Ctx> Result<typename Ctx::LocalIdxT> localidx(Ctx&);
template<typename Ctx> Result<typename Ctx::LabelIdxT> labelidx(Ctx&);
+template<typename Ctx> Result<typename Ctx::TagIdxT> tagidx(Ctx&);
template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx&);
MaybeResult<ImportNames> inlineImport(ParseInput&);
Result<std::vector<Name>> inlineExports(ParseInput&);
@@ -186,6 +187,7 @@ template<typename Ctx> MaybeResult<> memory(Ctx&);
template<typename Ctx> MaybeResult<> global(Ctx&);
template<typename Ctx> Result<typename Ctx::DataStringT> datastring(Ctx&);
template<typename Ctx> MaybeResult<> data(Ctx&);
+template<typename Ctx> MaybeResult<> tag(Ctx&);
template<typename Ctx> MaybeResult<> modulefield(Ctx&);
template<typename Ctx> Result<> module(Ctx&);
@@ -1274,7 +1276,9 @@ Result<> makeTryOrCatchBody(Ctx& ctx, Index pos, Type type, bool isTry) {
}
template<typename Ctx> Result<> makeThrow(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto tag = tagidx(ctx);
+ CHECK_ERR(tag);
+ return ctx.makeThrow(pos, *tag);
}
template<typename Ctx> Result<> makeRethrow(Ctx& ctx, Index pos) {
@@ -1627,6 +1631,18 @@ template<typename Ctx> Result<typename Ctx::LabelIdxT> labelidx(Ctx& ctx) {
return ctx.in.err("expected label index or identifier");
}
+// tagidx ::= x:u32 => x
+// | v:id => x (if tags[x] = v)
+template<typename Ctx> Result<typename Ctx::TagIdxT> tagidx(Ctx& ctx) {
+ if (auto x = ctx.in.takeU32()) {
+ return ctx.getTagFromIdx(*x);
+ }
+ if (auto id = ctx.in.takeID()) {
+ return ctx.getTagFromName(*id);
+ }
+ return ctx.in.err("expected tag index or identifier");
+}
+
// typeuse ::= '(' 'type' x:typeidx ')' => x, []
// (if typedefs[x] = [t1*] -> [t2*]
// | '(' 'type' x:typeidx ')' ((t1,IDs):param)* (t2:result)* => x, IDs
@@ -2011,6 +2027,36 @@ template<typename Ctx> MaybeResult<> data(Ctx& ctx) {
return Ok{};
}
+// tag ::= '(' 'tag' id? ('(' 'export' name ')')*
+// ('(' 'import' mod:name nm:name ')')? typeuse ')'
+template<typename Ctx> MaybeResult<> tag(Ctx& ctx) {
+ auto pos = ctx.in.getPos();
+ if (!ctx.in.takeSExprStart("tag"sv)) {
+ return {};
+ }
+
+ Name name;
+ if (auto id = ctx.in.takeID()) {
+ name = *id;
+ }
+
+ auto exports = inlineExports(ctx.in);
+ CHECK_ERR(exports);
+
+ auto import = inlineImport(ctx.in);
+ CHECK_ERR(import);
+
+ auto type = typeuse(ctx);
+ CHECK_ERR(type);
+
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of tag");
+ }
+
+ CHECK_ERR(ctx.addTag(name, *exports, import.getPtr(), *type, pos));
+ return Ok{};
+}
+
// modulefield ::= deftype
// | import
// | func
@@ -2021,6 +2067,7 @@ template<typename Ctx> MaybeResult<> data(Ctx& ctx) {
// | start
// | elem
// | data
+// | tag
template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
if (auto t = ctx.in.peek(); !t || t->isRParen()) {
return {};
@@ -2045,6 +2092,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
CHECK_ERR(res);
return Ok{};
}
+ if (auto res = tag(ctx)) {
+ CHECK_ERR(res);
+ return Ok{};
+ }
return ctx.in.err("unrecognized module field");
}