示例#1
0
        public override IPExpr VisitFunCallExpr(PParser.FunCallExprContext context)
        {
            string funName = context.fun.GetText();

            if (!table.Lookup(funName, out Function function))
            {
                throw handler.MissingDeclaration(context.fun, "function", funName);
            }

            // Check the arguments
            IPExpr[]        arguments       = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), this).ToArray();
            ISet <Variable> linearVariables = new HashSet <Variable>();

            if (function.Signature.Parameters.Count != arguments.Length)
            {
                throw handler.IncorrectArgumentCount(context, arguments.Length, function.Signature.Parameters.Count);
            }

            for (int i = 0; i < arguments.Length; i++)
            {
                IPExpr        argument  = arguments[i];
                PLanguageType paramType = function.Signature.Parameters[i].Type;
                if (!paramType.IsAssignableFrom(argument.Type))
                {
                    throw handler.TypeMismatch(context.rvalueList().rvalue(i), argument.Type, paramType);
                }

                if (argument is ILinearRef linearRef)
                {
                    if (linearRef.LinearType == LinearType.Swap && !linearRef.Type.IsSameTypeAs(paramType))
                    {
                        throw handler.TypeMismatch(context, linearRef.Type, paramType);
                    }

                    if (linearVariables.Contains(linearRef.Variable))
                    {
                        throw handler.RelinquishedWithoutOwnership(linearRef);
                    }

                    linearVariables.Add(linearRef.Variable);
                }
            }

            method.AddCallee(function);
            return(new FunCallExpr(context, function, arguments));
        }
示例#2
0
        public override IPExpr VisitFunCallExpr(PParser.FunCallExprContext context)
        {
            string funName = context.fun.GetText();

            if (!table.Lookup(funName, out Function function))
            {
                throw handler.MissingDeclaration(context.fun, "function", funName);
            }

            // Check the arguments
            // TODO: linearly typed arguments
            var             arguments       = (context.rvalueList()?.rvalue().Select(Visit) ?? Enumerable.Empty <IPExpr>()).ToArray();
            ISet <Variable> linearVariables = new HashSet <Variable>();

            for (var i = 0; i < arguments.Length; i++)
            {
                IPExpr        argument  = arguments[i];
                PLanguageType paramType = function.Signature.Parameters[i].Type;
                if (!paramType.IsAssignableFrom(argument.Type))
                {
                    throw handler.TypeMismatch(context.rvalueList().rvalue(i), argument.Type, paramType);
                }
                if (argument is ILinearRef linearRef)
                {
                    if (linearRef.LinearType == LinearType.Swap && !linearRef.Type.IsSameTypeAs(paramType))
                    {
                        throw handler.TypeMismatch(context, linearRef.Type, paramType);
                    }
                    if (linearVariables.Contains(linearRef.Variable))
                    {
                        throw handler.RelinquishedWithoutOwnership(linearRef);
                    }
                    linearVariables.Add(linearRef.Variable);
                }
            }

            return(new FunCallExpr(context, function, arguments));
        }
示例#3
0
        private ISet <Variable> ProcessExpr(ISet <Variable> unavailable, IPExpr expression)
        {
            Contract.Requires(expression != null);
            switch (expression)
            {
            case CloneExpr cloneExpr:
                unavailable = ProcessExpr(unavailable, cloneExpr.Term);
                break;

            case CastExpr castExpr:
                unavailable = ProcessExpr(unavailable, castExpr.SubExpr);
                break;

            case CoerceExpr coerceExpr:
                unavailable = ProcessExpr(unavailable, coerceExpr.SubExpr);
                break;

            case ContainsKeyExpr containsKeyExpr:
                unavailable = ProcessExpr(unavailable, containsKeyExpr.Map);
                unavailable = ProcessExpr(unavailable, containsKeyExpr.Key);
                break;

            case CtorExpr ctorExpr:
                unavailable = ProcessArgList(ctorExpr.Arguments, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case FunCallExpr funCallExpr:
                unavailable = ProcessArgList(funCallExpr.Arguments, unavailable);
                funCallExprs.Add(funCallExpr);
                break;

            case KeysExpr keysExpr:
                unavailable = ProcessExpr(unavailable, keysExpr.Expr);
                break;

            case LinearAccessRefExpr linearAccessRefExpr:
                if (unavailable.Contains(linearAccessRefExpr.Variable) ||
                    linearAccessRefExpr.Variable.Role.Equals(VariableRole.Field))
                {
                    throw handler.RelinquishedWithoutOwnership(linearAccessRefExpr);
                }

                if (linearAccessRefExpr.LinearType.Equals(LinearType.Move))
                {
                    unavailable.Add(linearAccessRefExpr.Variable);
                }

                break;

            case UnaryOpExpr unaryOp:
                unavailable = ProcessExpr(unavailable, unaryOp.SubExpr);
                break;

            case MapAccessExpr mapAccessExpr:
                unavailable = ProcessExpr(unavailable, mapAccessExpr.MapExpr);
                unavailable = ProcessExpr(unavailable, mapAccessExpr.IndexExpr);
                break;

            case BinOpExpr binOp:
                unavailable = ProcessExpr(unavailable, binOp.Lhs);
                unavailable = ProcessExpr(unavailable, binOp.Rhs);
                break;

            case NamedTupleAccessExpr namedTupleAccessExpr:
                unavailable = ProcessExpr(unavailable, namedTupleAccessExpr.SubExpr);
                break;

            case NamedTupleExpr namedTupleExpr:
                unavailable = ProcessArgList(namedTupleExpr.TupleFields, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case SeqAccessExpr seqAccessExpr:
                unavailable = ProcessExpr(unavailable, seqAccessExpr.SeqExpr);
                unavailable = ProcessExpr(unavailable, seqAccessExpr.IndexExpr);
                break;

            case SizeofExpr sizeofExpr:
                unavailable = ProcessExpr(unavailable, sizeofExpr.Expr);
                break;

            case TupleAccessExpr tupleAccessExpr:
                unavailable = ProcessExpr(unavailable, tupleAccessExpr.SubExpr);
                break;

            case UnnamedTupleExpr unnamedTupleExpr:
                unavailable = ProcessArgList(unnamedTupleExpr.TupleFields, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case ValuesExpr valuesExpr:
                unavailable = ProcessExpr(unavailable, valuesExpr.Expr);
                break;

            case VariableAccessExpr variableAccessExpr:
                if (unavailable.Contains(variableAccessExpr.Variable))
                {
                    throw handler.UseWithoutOwnership(variableAccessExpr);
                }

                break;

            case BoolLiteralExpr _:
            case DefaultExpr _:
            case EnumElemRefExpr _:
            case EventRefExpr _:
            case FairNondetExpr _:
            case FloatLiteralExpr _:
            case IntLiteralExpr _:
            case NondetExpr _:
            case NullLiteralExpr _:
            case ThisRefExpr _:
                // nothing to do
                break;

            default:
                throw handler.InternalError(expression.SourceLocation,
                                            new ArgumentOutOfRangeException(nameof(expression)));
            }

            return(unavailable);
        }