public override IPStmt VisitGotoStmt(PParser.GotoStmtContext context) { var stateNameContext = context.stateName(); var stateName = stateNameContext.state.GetText(); IStateContainer current = machine; foreach (var token in stateNameContext._groups) { current = current?.GetGroup(token.GetText()); if (current == null) { throw handler.MissingDeclaration(token, "group", token.GetText()); } } var state = current?.GetState(stateName); if (state == null) { throw handler.MissingDeclaration(stateNameContext.state, "state", stateName); } var expectedType = state.Entry?.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null; var rvaluesList = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToArray(); foreach (var arg in rvaluesList) { if (arg is LinearAccessRefExpr linearArg && linearArg.LinearType == LinearType.Swap) { throw handler.InvalidSwap(linearArg, "swap not allowed on goto"); } } IPExpr payload; if (rvaluesList.Length == 0) { payload = null; } else if (rvaluesList.Length == 1) { payload = rvaluesList[0]; } else { payload = new UnnamedTupleExpr(context, rvaluesList); } var payloadType = payload?.Type ?? PrimitiveType.Null; if (!expectedType.IsAssignableFrom(payloadType)) { throw handler.TypeMismatch(context, payloadType, expectedType); } method.CanChangeState = true; return(new GotoStmt(context, state, payload)); }
public override IPStmt VisitGotoStmt(PParser.GotoStmtContext context) { PParser.StateNameContext stateNameContext = context.stateName(); string stateName = stateNameContext.state.GetText(); IStateContainer current = machine; foreach (PParser.IdenContext token in stateNameContext._groups) { current = current?.GetGroup(token.GetText()); if (current == null) { throw handler.MissingDeclaration(token, "group", token.GetText()); } } State state = current?.GetState(stateName); if (state == null) { throw handler.MissingDeclaration(stateNameContext.state, "state", stateName); } IPExpr payload = null; PLanguageType expectedType = state.Entry.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null; if (context.rvalueList()?.rvalue() is PParser.RvalueContext[] rvalues) { if (rvalues.Length == 1) { payload = exprVisitor.Visit(rvalues[0]); } else { IPExpr[] tupleFields = rvalues.Select(exprVisitor.Visit).ToArray(); payload = new UnnamedTupleExpr(context, tupleFields, new TupleType(tupleFields.Select(f => f.Type).ToList())); } } PLanguageType payloadType = payload?.Type ?? PrimitiveType.Null; if (!expectedType.IsAssignableFrom(payloadType)) { throw handler.TypeMismatch(context, payloadType, expectedType); } return(new GotoStmt(context, state, payload)); }