/// <summary> /// Get or set values in the Object or Array or its' prototype. /// </summary> public MondValue this[MondValue index] { get { if (ReferenceEquals(index, null)) { throw new ArgumentNullException(nameof(index)); } if (Type == MondValueType.Array && (index.Type == MondValueType.Number || index.Type == MondValueType.Object)) { var n = (int)index; if (n < 0) { n += ArrayValue.Count; } if (n < 0 || n >= ArrayValue.Count) { throw new MondRuntimeException(RuntimeError.IndexOutOfBounds); } return(ArrayValue[n]); } MondValue indexValue; if (Type == MondValueType.Object) { if (ObjectValue.Values.TryGetValue(index, out indexValue)) { return(CheckWrapFunction(indexValue)); } } var i = 0; var prototype = Prototype; while (prototype != null) { var currentValue = prototype; if (currentValue.Type != MondValueType.Object) { break; } var currentObjValue = currentValue.ObjectValue; if (currentObjValue.Values.TryGetValue(index, out indexValue)) { return(CheckWrapFunction(indexValue)); } prototype = currentValue.Prototype; i++; if (i > 100) { throw new MondRuntimeException(RuntimeError.CircularPrototype); } } if (Type == MondValueType.Object) { if (TryDispatch("__get", out indexValue, this, index)) { return(CheckWrapFunction(indexValue)); } } return(Undefined); } set { if (ReferenceEquals(index, null)) { throw new ArgumentNullException(nameof(index)); } if (ReferenceEquals(value, null)) { throw new ArgumentNullException(nameof(value)); } if (Type == MondValueType.Array && (index.Type == MondValueType.Number || index.Type == MondValueType.Object)) { var n = (int)index; if (n < 0) { n += ArrayValue.Count; } if (n < 0 || n >= ArrayValue.Count) { throw new MondRuntimeException(RuntimeError.IndexOutOfBounds); } ArrayValue[n] = value; return; } if (Type == MondValueType.Object && ObjectValue.Values.ContainsKey(index)) { if (ObjectValue.Locked) { throw new MondRuntimeException(RuntimeError.ObjectIsLocked); } ObjectValue.Values[index] = value; return; } var i = 0; var prototype = Prototype; while (prototype != null) { var currentValue = prototype; if (currentValue.Type != MondValueType.Object) { break; } var values = currentValue.ObjectValue.Values; if (values.ContainsKey(index)) { if (currentValue.ObjectValue.Locked) { break; // hit a wall in the prototype chain, don't continue } values[index] = value; return; } prototype = currentValue.Prototype; i++; if (i > 100) { throw new MondRuntimeException(RuntimeError.CircularPrototype); } } if (Type != MondValueType.Object) { throw new MondRuntimeException(RuntimeError.CantCreateField, Type.GetName()); } if (ObjectValue.Locked) { throw new MondRuntimeException(RuntimeError.ObjectIsLocked); } if (TryDispatch("__set", out var _, this, index, value)) { return; } ObjectValue.Values[index] = value; } }
private static void UnsupportedMondTypeError( MondValueType type ) { throw new NotSupportedException( "Unsupported MondValueType '{0}'".With( type.GetName() ) ); }
private static void UnsupportedMondTypeError(MondValueType type) => throw new NotSupportedException( $"Unsupported MondValueType '{type.GetName()}'");