Exemple #1
0
        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));
        }