Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
        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);
        }