예제 #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));
        }
예제 #2
0
        private void CheckFunctionCall(Function function, IEnumerable <IPExpr> arguments)
        {
            var i = 0;

            foreach (Tuple <Variable, IPExpr> pair in function.Signature.Parameters.Zip(arguments, Tuple.Create))
            {
                if (pair.Item2 is ILinearRef linearRef)
                {
                    if (linearRef.LinearType.Equals(LinearType.Swap) && allUnavailableParams.Contains(pair.Item1))
                    {
                        throw handler.InvalidSwap(linearRef,
                                                  $"function {function.Name} relinquishes argument #{i} and therefore cannot be swapped.");
                    }
                }
                i++;
            }
        }