summaryrefslogtreecommitdiff
path: root/src/parser/parsers.h
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-01-02 12:36:30 -0800
committerGitHub <noreply@github.com>2024-01-02 12:36:30 -0800
commit5e3f81ceb1259de752bb61d80b26381ff1448828 (patch)
tree68324fc0ad0980b40196b87e82f604fe7d5a5473 /src/parser/parsers.h
parent95ed4f3f0bf0a463cee88a63c5becde4d28692ff (diff)
downloadbinaryen-5e3f81ceb1259de752bb61d80b26381ff1448828.tar.gz
binaryen-5e3f81ceb1259de752bb61d80b26381ff1448828.tar.bz2
binaryen-5e3f81ceb1259de752bb61d80b26381ff1448828.zip
[Parser] Support standalone import definitions (#6191)
We previously support the in-line import abbreviation, but now add support for explicit, non-abbreviated imports as well.
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r--src/parser/parsers.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 7f4005c3d..6dd617309 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -191,6 +191,7 @@ template<typename Ctx> Result<> strtype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::ModuleNameT> subtype(Ctx&);
template<typename Ctx> MaybeResult<> deftype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx&);
+template<typename Ctx> MaybeResult<> import_(Ctx&);
template<typename Ctx> MaybeResult<> func(Ctx&);
template<typename Ctx> MaybeResult<> table(Ctx&);
template<typename Ctx> MaybeResult<> memory(Ctx&);
@@ -2168,6 +2169,71 @@ template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx& ctx) {
return {};
}
+// import ::= '(' 'import' mod:name nm:name importdesc ')'
+// importdesc ::= '(' 'func' id? typeuse ')'
+// | '(' 'table' id? tabletype ')'
+// | '(' 'memory' id? memtype ')'
+// | '(' 'global' id? globaltype ')'
+// | '(' 'tag' id? typeuse ')'
+template<typename Ctx> MaybeResult<> import_(Ctx& ctx) {
+ auto pos = ctx.in.getPos();
+
+ if (!ctx.in.takeSExprStart("import"sv)) {
+ return {};
+ }
+
+ auto mod = ctx.in.takeName();
+ if (!mod) {
+ return ctx.in.err("expected import module name");
+ }
+
+ auto nm = ctx.in.takeName();
+ if (!nm) {
+ return ctx.in.err("expected import name");
+ }
+ ImportNames names{*mod, *nm};
+
+ if (ctx.in.takeSExprStart("func"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = typeuse(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(
+ ctx.addFunc(name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
+ } else if (ctx.in.takeSExprStart("table"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = tabletype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addTable(name ? *name : Name{}, {}, &names, *type, pos));
+ } else if (ctx.in.takeSExprStart("memory"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = memtype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addMemory(name ? *name : Name{}, {}, &names, *type, pos));
+ } else if (ctx.in.takeSExprStart("global"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = globaltype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addGlobal(
+ name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
+ } else if (ctx.in.takeSExprStart("tag"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = typeuse(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addTag(name ? *name : Name{}, {}, &names, *type, pos));
+ } else {
+ return ctx.in.err("expected import description");
+ }
+
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of import description");
+ }
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of import");
+ }
+
+ return Ok{};
+}
+
// func ::= '(' 'func' id? ('(' 'export' name ')')*
// x,I:typeuse t*:vec(local) (in:instr)* ')'
// | '(' 'func' id? ('(' 'export' name ')')*
@@ -2651,6 +2717,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
CHECK_ERR(res);
return Ok{};
}
+ if (auto res = import_(ctx)) {
+ CHECK_ERR(res);
+ return Ok{};
+ }
if (auto res = func(ctx)) {
CHECK_ERR(res);
return Ok{};