diff options
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r-- | src/parser/parsers.h | 53 |
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"); } |