Used to parse identifier expressions
예제 #1
0
        ///
        /// <summary>
        ///		Parses assignment expressions. This method basically just prepares
        ///		the parameters for a call to IdentifierExp.Assign(). Reference that
        ///		method for more information on this method's parameters.
        /// </summary>
        ///
        /// <param name="envChain">
        ///		List of CseObjects from the chain expression of the lhs.
        ///		This makes up the list of environment objects.
        ///	</param>
        /// <param name="envNames">List of field/property names in the lhs chain expression.</param>
        /// <param name="envIndices">
        ///		List of array indices for each array in the lhs chain expression.
        ///		For each non-array, the envIndices at that index is null.
        ///	</param>
        /// <param name="rhs">Rhs expression</param>
        ///
        /// <returns>The rhs parameter</returns>
        ///
        public static CseObject Parse(List <CseObject> envChain, List <string> envNames, List <CseObject> envIndices, CseObject rhs)
        {
            Type envType;

            while (envChain.Count > 1)
            {
                envType = envChain[1].Value.GetType();
                if (!envType.IsValueType)
                {
                    envChain.RemoveAt(0);
                    envNames.RemoveAt(0);
                    envIndices.RemoveAt(0);
                }
                else
                {
                    break;
                }
            }

            IdentifierExp.Assign(envChain, envNames, envIndices, rhs);
            return(rhs);
        }
예제 #2
0
        ///
        /// <summary>
        ///		Assigns a value to the specified identifier (field or property).
        ///		Since any field or property that is a ValueType will not have its
        ///		value changed without explicitly being set, this method is given the
        ///		entire list of objects of the lhs chain expression and uses recursion to
        ///		set them right to left.
        /// </summary>
        ///
        /// <example>
        ///		<c language="C#">x.y.z = 3</c>
        ///		This will set z = 3, then y = z (the newly changed z), then x = y.
        ///		If the expression is simply <c language="C#">x = 3</c>, then that is the only assignment
        ///		performed and all List arguments contain only a single value.
        /// </example>
        ///
        /// <param name="envChain">
        ///		List of CseObjects from the chain expression of the lhs. This makes up the
        ///		list of environment objects. In the case of x = 3, envChain would contain
        ///		x's value.
        ///	</param>
        /// <param name="envNames">List of field/property names in the lhs chain expression. In the case of x = 3, envNames would contain "x".</param>
        /// <param name="envIndices">
        ///		List of array indices for each array in the lhs chain expression. For each non-array, the
        ///		envIndices at that index is null. In the case of x = 3, envIndices would contain null.
        ///		In the case of x[2] = 3, envIndices would contain 2.
        ///	</param>
        /// <param name="xrhs">Rhs expression</param>
        ///
        /// <returns>xrhs's Value property</returns>
        ///
        /// <exception cref="CseLogicExceptionType.ARRAY_INDEX_NOT_INT" />
        /// <exception cref="CseLogicExceptionType.CANT_FIND_IDENT_IN_ENV" />
        ///
        internal static object Assign(List <CseObject> envChain, List <string> envNames, List <CseObject> envIndices, CseObject xrhs)
        {
            object rhs = (xrhs == null ? null : xrhs.Value);

            if (envChain.Count == 0)
            {
                return(rhs);
            }

            CseObject env      = envChain[envChain.Count - 1];
            string    envName  = envNames[envNames.Count - 1];
            CseObject envIndex = envIndices[envIndices.Count - 1];

            //Type instanceType = TypeExp.GetTypeObj(env.Value);
            Type instanceType = env.ValueType;

            // Arrays
            if (envIndex != null)
            {
                MemberInfo  member;
                ICollection arrMember;

                member = instanceType.GetField(envName, defaultFlags | BindingFlags.GetField);
                if (member != null)
                {
                    arrMember = (ICollection)((FieldInfo)member).GetValue(env.Value);
                }
                else
                {
                    member = instanceType.GetProperty(envName, defaultFlags | BindingFlags.GetProperty);
                    if (member != null)
                    {
                        arrMember = (ICollection)((PropertyInfo)member).GetValue(env.Value, null);
                    }
                    else
                    {
                        throw new CseLogicException(CseLogicExceptionType.CANT_FIND_IDENT_IN_ENV, envName, env.Value.ToString());
                    }
                }

                Array       arrMemberAsArray = arrMember as Array;
                IDictionary arrMemberAsIDict = arrMember as IDictionary;

                if (arrMemberAsArray != null)
                {
                    int index;
                    if (int.TryParse(envIndex.Value.ToString(), out index))
                    {
                        arrMemberAsArray.SetValue(rhs, index);
                    }
                    else
                    {
                        throw new CseLogicException(CseLogicExceptionType.ARRAY_INDEX_NOT_INT);
                    }
                }
                else if (arrMemberAsIDict != null)
                {
                    arrMemberAsIDict[envIndex.Value] = rhs;
                }
            }
            // Nonarrays
            else
            {
                if (env == CsEval.EvalEnvironment)
                {
                    CseObject tempLookup = TempIdentifierExp.Lookup(envName);
                    if (tempLookup != null)
                    {
                        TempIdentifierExp.Assign(envName, rhs);
                        return(tempLookup);
                    }
                }

                FieldInfo fieldInfo = instanceType.GetField(envName, defaultFlags | BindingFlags.GetField);
                if (fieldInfo != null)
                {
                    fieldInfo.SetValue(env.Value, rhs);
                }
                else
                {
                    PropertyInfo propertyInfo = instanceType.GetProperty(envName, defaultFlags | BindingFlags.GetProperty);
                    if (propertyInfo != null)
                    {
                        propertyInfo.SetValue(env.Value, rhs, null);
                    }
                    else
                    {
                        throw new CseLogicException(CseLogicExceptionType.CANT_FIND_IDENT_IN_ENV, envName, env.Value.ToString());
                    }
                }
            }

            envChain.RemoveAt(envChain.Count - 1);
            envNames.RemoveAt(envNames.Count - 1);
            envIndices.RemoveAt(envIndices.Count - 1);

            return(IdentifierExp.Assign(envChain, envNames, envIndices, env));
        }