@@ -25,6 +25,8 @@ using namespace std::string_view_literals;
2525
2626namespace {
2727
28+ Result<WASTCommand> command (Lexer& in);
29+
2830Result<Literal> const_ (Lexer& in) {
2931 if (in.takeSExprStart (" ref.extern" sv)) {
3032 auto n = in.takeI32 ();
@@ -496,12 +498,79 @@ MaybeResult<ModuleInstantiation> instantiation(Lexer& in) {
496498 return ModuleInstantiation{moduleId, instanceId};
497499}
498500
499- // instantiate | module | register | action | assertion
501+ // (thread name (shared (module name))? command*)
502+ MaybeResult<ThreadBlock> threadBlock (Lexer& in) {
503+ if (!in.takeSExprStart (" thread" sv)) {
504+ return {};
505+ }
506+
507+ auto name = in.takeID ();
508+ if (!name) {
509+ return in.err (" expected thread name" );
510+ }
511+
512+ std::optional<Name> sharedModule;
513+ if (in.takeSExprStart (" shared" sv)) {
514+ if (!in.takeSExprStart (" module" sv)) {
515+ return in.err (" expected module keyword in (shared ...) block" );
516+ }
517+
518+ auto modName = in.takeID ();
519+ if (!modName) {
520+ return in.err (" expected module name after (shared (module ...))" );
521+ }
522+ sharedModule = *modName;
523+
524+ if (!in.takeRParen ()) {
525+ return in.err (" expected end of shared module" );
526+ }
527+ if (!in.takeRParen ()) {
528+ return in.err (" expected end of (shared ...) expression" );
529+ }
530+ }
531+
532+ std::vector<ScriptEntry> commands;
533+ while (!in.peekRParen () && !in.empty ()) {
534+ size_t line = in.position ().line ;
535+ auto cmd = command (in);
536+ CHECK_ERR (cmd);
537+ commands.push_back ({std::move (*cmd), line});
538+ }
539+ if (!in.takeRParen ()) {
540+ return in.err (" expected end of thread" );
541+ }
542+ return ThreadBlock{*name, sharedModule, std::move (commands)};
543+ }
544+
545+ // (wait name)
546+ MaybeResult<Wait> wait (Lexer& in) {
547+ if (!in.takeSExprStart (" wait" sv)) {
548+ return {};
549+ }
550+ auto name = in.takeID ();
551+ if (!name) {
552+ return in.err (" expected thread name in wait" );
553+ }
554+ if (!in.takeRParen ()) {
555+ return in.err (" expected end of wait" );
556+ }
557+ return Wait{*name};
558+ }
559+
560+ // instantiate | module | register | action | assertion | thread | wait
500561Result<WASTCommand> command (Lexer& in) {
501562 if (auto cmd = register_ (in)) {
502563 CHECK_ERR (cmd);
503564 return *cmd;
504565 }
566+ if (auto cmd = threadBlock (in)) {
567+ CHECK_ERR (cmd);
568+ return *cmd;
569+ }
570+ if (auto cmd = wait (in)) {
571+ CHECK_ERR (cmd);
572+ return *cmd;
573+ }
505574 if (auto cmd = maybeAction (in)) {
506575 CHECK_ERR (cmd);
507576 return *cmd;
0 commit comments