/// <summary> /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection. /// </summary> /// <param name="Variables">Variables collection.</param> /// <returns>Result.</returns> public override IElement Evaluate(Variables Variables) { IElement Left = this.left.Evaluate(Variables); IElement Index = this.middle.Evaluate(Variables); IElement Value = this.right.Evaluate(Variables); if (Left is IVector V) { double d; if (!(Index is DoubleNumber IE) || (d = IE.Value) < 0 || d > int.MaxValue || d != Math.Truncate(d)) { throw new ScriptRuntimeException("Index must be a non-negative integer.", this); } V.SetElement((int)d, Value); return(Value); } else if (Left.IsScalar) { object Object = Left.AssociatedObjectValue; if (Object is null) { throw new ScriptRuntimeException("Vector is null.", this); } if (Object is IDictionary <string, IElement> ObjExNihilo) { ObjExNihilo[Index.AssociatedObjectValue?.ToString()] = Value; } else { Type T = Object.GetType(); if (!VectorIndex.TryGetIndexProperty(T, out PropertyInfo ItemProperty, out ParameterInfo[] Parameters)) { throw new ScriptRuntimeException("Vector element assignment operates on vectors.", this); } if (Index.TryConvertTo(Parameters[0].ParameterType, out object IndexValue)) { ItemProperty.SetValue(Object, Value.AssociatedObjectValue, new object[] { IndexValue }); } else { throw new ScriptRuntimeException("Provided index value not compatible with expected index type.", this); } } return(Value); } else { throw new ScriptRuntimeException("Vector element assignment can only be performed on vectors or on objects with a suitable index property defined.", this); } }