/// /// <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); }
/// /// <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)); }