示例#1
0
文件: Contract.cs 项目: nsr0776/Nero
        public Contract(Arity arity, IList <Type> paramTypes)
        {
            if (!arity.Verify(paramTypes.Count))
            {
                // The Contract class is designed to be used by the primitive procedures only,
                // which means that I should take care of getting their contracts & implementation right.
                // If compound procedures are also allowed to specify their contracts, then
                // this exception should be replaced with an interpreter-handled exception.
                throw new ArgumentException("The given parameter types does not match the specified arity.");
            }

            if (paramTypes.Where((t) => !Utils.IsIValueType(t)).Count() != 0)
            {
                throw new ArgumentException("The given parameter types contain a non-IValue type.");
            }

            this.arity      = arity;
            this.paramTypes = paramTypes;
        }
示例#2
0
文件: Contract.cs 项目: nsr0776/Nero
        /// <summary>
        /// Checks the arity and types of the incoming arguments against the specification.
        /// A return value indicates whether the incoming arguments are valid. If False is
        /// returned, the out parameter will be assigned a string describing the violation.
        /// </summary>
        /// <param name="arguments">The incoming arguments to check.</param>
        /// <param name="msg">Set to null if this method returns True. Otherwise, it
        /// contains description about the violation of the contract.</param>
        /// <returns></returns>
        public bool TryVerify(IReadOnlyCollection <IValue> arguments, out string msg)
        {
            var argTypes = (from arg in arguments select arg.GetType()).ToArray();

            List <int> LocateTypeMismatches()
            {
                // Compare each argument with the corresponding parameter
                // and check their type compatibility
                // Record the index of any type mismatch

                var indices = new List <int>();

                for (int i = 0; i < arguments.Count; i++)
                {
                    Type argType   = argTypes[i];
                    Type paramType = (i < paramTypes.Count) ? paramTypes[i] : paramTypes[paramTypes.Count - 1];
                    if (!paramType.IsAssignableFrom(argType))
                    {
                        indices.Add(i);
                    }
                }

                return(indices);
            }

            (bool, string) ReportTypeMismatches(List <int> indices)
            {
                string msg1;

                // If there is any type mismatch, report with the message
                // argument and return False
                if (indices.Count != 0)
                {
                    var builder = new StringBuilder();
                    foreach (int i in indices)
                    {
                        int    paramIndex  = (i < paramTypes.Count) ? i : paramTypes.Count - 1;
                        string correctType = Utils.IValueTypeToString(paramTypes[paramIndex]);
                        string givenType   = Utils.IValueTypeToString(argTypes[i]);
                        builder.Append($"\n\t(arg #{i + 1}) Expected: {correctType}. Given: {givenType}");
                    }

                    msg1 = "Type mismatch:" + builder.ToString();
                    return(false, msg1);
                }
                else
                {
                    msg1 = null;
                    return(true, msg1);
                }
            }

            //// Part I - Verify arity
            if (!arity.Verify(arguments.Count))
            {
                msg = $"Arity mismatch. Expected: {arity.Representation}. Given: {arguments.Count}";
                return(false);
            }

            //// Part II - Verify types

            bool result;
            var  mismatchIndices = LocateTypeMismatches();

            (result, msg) = ReportTypeMismatches(mismatchIndices);
            return(result);
        }