public override IPStmt VisitReceiveStmt(PParser.ReceiveStmtContext context) { // TODO: can receive statements have event variables as their cases? var cases = new Dictionary <PEvent, Function>(); foreach (PParser.RecvCaseContext caseContext in context.recvCase()) { var recvHandler = new Function(caseContext.anonEventHandler()) { Scope = table.MakeChildScope(), Owner = method.Owner, Role = FunctionRole.ReceiveHandler }; if (caseContext.anonEventHandler().funParam() is PParser.FunParamContext param) { Variable paramVar = recvHandler.Scope.Put(param.name.GetText(), param, VariableRole.Param); paramVar.Type = TypeResolver.ResolveType(param.type(), recvHandler.Scope, handler); recvHandler.Signature.Parameters.Add(paramVar); } FunctionBodyVisitor.PopulateMethod(handler, recvHandler); foreach (PParser.EventIdContext eventIdContext in caseContext.eventList().eventId()) { if (!table.Lookup(eventIdContext.GetText(), out PEvent pEvent)) { throw handler.MissingDeclaration(eventIdContext, "event", eventIdContext.GetText()); } if (cases.ContainsKey(pEvent)) { throw handler.IssueError(eventIdContext, $"duplicate case for event {pEvent.Name} in receive"); } PLanguageType expectedType = recvHandler.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null; if (!expectedType.IsAssignableFrom(pEvent.PayloadType)) { throw handler.TypeMismatch(caseContext.anonEventHandler().funParam(), expectedType, pEvent.PayloadType); } cases.Add(pEvent, recvHandler); } } return(new ReceiveStmt(context, cases)); }