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()); } } AST.States.State state = current?.GetState(stateName); if (state == null) { throw handler.MissingDeclaration(stateNameContext.state, "state", stateName); } PLanguageType expectedType = state.Entry?.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null; IPExpr[] rvaluesList = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToArray(); foreach (IPExpr 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); } PLanguageType 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)); }
private State FindState(PParser.StateNameContext context) { var scope = CurrentMachine.Scope; foreach (var groupToken in context._groups) { if (!scope.Get(groupToken.GetText(), out StateGroup group)) { throw Handler.MissingDeclaration(groupToken, "group", groupToken.GetText()); } scope = group.Scope; } if (!scope.Get(context.state.GetText(), out State state)) { throw Handler.MissingDeclaration(context.state, "state", context.state.GetText()); } return(state); }