@@ -191,6 +191,7 @@ template<typename Ctx> Result<> strtype(Ctx&);
191191template <typename Ctx> MaybeResult<typename Ctx::ModuleNameT> subtype (Ctx&);
192192template <typename Ctx> MaybeResult<> deftype (Ctx&);
193193template <typename Ctx> MaybeResult<typename Ctx::LocalsT> locals (Ctx&);
194+ template <typename Ctx> MaybeResult<> import_ (Ctx&);
194195template <typename Ctx> MaybeResult<> func (Ctx&);
195196template <typename Ctx> MaybeResult<> table (Ctx&);
196197template <typename Ctx> MaybeResult<> memory (Ctx&);
@@ -2168,6 +2169,71 @@ template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx& ctx) {
21682169 return {};
21692170}
21702171
2172+ // import ::= '(' 'import' mod:name nm:name importdesc ')'
2173+ // importdesc ::= '(' 'func' id? typeuse ')'
2174+ // | '(' 'table' id? tabletype ')'
2175+ // | '(' 'memory' id? memtype ')'
2176+ // | '(' 'global' id? globaltype ')'
2177+ // | '(' 'tag' id? typeuse ')'
2178+ template <typename Ctx> MaybeResult<> import_ (Ctx& ctx) {
2179+ auto pos = ctx.in .getPos ();
2180+
2181+ if (!ctx.in .takeSExprStart (" import" sv)) {
2182+ return {};
2183+ }
2184+
2185+ auto mod = ctx.in .takeName ();
2186+ if (!mod) {
2187+ return ctx.in .err (" expected import module name" );
2188+ }
2189+
2190+ auto nm = ctx.in .takeName ();
2191+ if (!nm) {
2192+ return ctx.in .err (" expected import name" );
2193+ }
2194+ ImportNames names{*mod, *nm};
2195+
2196+ if (ctx.in .takeSExprStart (" func" sv)) {
2197+ auto name = ctx.in .takeID ();
2198+ auto type = typeuse (ctx);
2199+ CHECK_ERR (type);
2200+ CHECK_ERR (
2201+ ctx.addFunc (name ? *name : Name{}, {}, &names, *type, std::nullopt , pos));
2202+ } else if (ctx.in .takeSExprStart (" table" sv)) {
2203+ auto name = ctx.in .takeID ();
2204+ auto type = tabletype (ctx);
2205+ CHECK_ERR (type);
2206+ CHECK_ERR (ctx.addTable (name ? *name : Name{}, {}, &names, *type, pos));
2207+ } else if (ctx.in .takeSExprStart (" memory" sv)) {
2208+ auto name = ctx.in .takeID ();
2209+ auto type = memtype (ctx);
2210+ CHECK_ERR (type);
2211+ CHECK_ERR (ctx.addMemory (name ? *name : Name{}, {}, &names, *type, pos));
2212+ } else if (ctx.in .takeSExprStart (" global" sv)) {
2213+ auto name = ctx.in .takeID ();
2214+ auto type = globaltype (ctx);
2215+ CHECK_ERR (type);
2216+ CHECK_ERR (ctx.addGlobal (
2217+ name ? *name : Name{}, {}, &names, *type, std::nullopt , pos));
2218+ } else if (ctx.in .takeSExprStart (" tag" sv)) {
2219+ auto name = ctx.in .takeID ();
2220+ auto type = typeuse (ctx);
2221+ CHECK_ERR (type);
2222+ CHECK_ERR (ctx.addTag (name ? *name : Name{}, {}, &names, *type, pos));
2223+ } else {
2224+ return ctx.in .err (" expected import description" );
2225+ }
2226+
2227+ if (!ctx.in .takeRParen ()) {
2228+ return ctx.in .err (" expected end of import description" );
2229+ }
2230+ if (!ctx.in .takeRParen ()) {
2231+ return ctx.in .err (" expected end of import" );
2232+ }
2233+
2234+ return Ok{};
2235+ }
2236+
21712237// func ::= '(' 'func' id? ('(' 'export' name ')')*
21722238// x,I:typeuse t*:vec(local) (in:instr)* ')'
21732239// | '(' 'func' id? ('(' 'export' name ')')*
@@ -2651,6 +2717,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
26512717 CHECK_ERR (res);
26522718 return Ok{};
26532719 }
2720+ if (auto res = import_ (ctx)) {
2721+ CHECK_ERR (res);
2722+ return Ok{};
2723+ }
26542724 if (auto res = func (ctx)) {
26552725 CHECK_ERR (res);
26562726 return Ok{};
0 commit comments