Example #1
0
        public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
        {
            var oldV = vp[Variable];

            if (oldV is ArrayValue)
            {
                var av = (ArrayValue)oldV;

                //TODO: Immutability checks

                if (av.IsString)
                {

                }
                else
                {
                    var at = av.RepresentedType as ArrayType;
                    var newElements = new ISymbolValue[av.Elements.Length + (ItemNumber<0 ? 1:0)];
                    av.Elements.CopyTo(newElements, 0);

                    if (!ResultComparer.IsImplicitlyConvertible(value.RepresentedType, at.ValueType))
                        throw new EvaluationException(BaseExpression, value.ToCode() + " must be implicitly convertible to the array's value type!", value);

                    // Add..
                    if (ItemNumber < 0)
                        av.Elements[av.Elements.Length - 1] = value;
                    else // or set the new value
                        av.Elements[ItemNumber] = value;

                    vp[Variable] = new ArrayValue(at, newElements);
                }
            }
            else
                throw new EvaluationException(BaseExpression, "Type of accessed item must be an array", oldV);
        }
		/// <summary>
		/// http://dlang.org/operatoroverloading.html#Dispatch
		/// Check for the existence of an opDispatch overload.
		/// Important: Because static opDispatches are allowed as well, do check whether we can access non-static overloads from non-instance expressions or such
		/// </summary>
		public static IEnumerable<AbstractType> TryResolveFurtherIdViaOpDispatch (ResolutionContext ctxt, int nextIdentifierHash, UserDefinedType b, ISyntaxRegion typeBase = null)
		{
			// The usual SO prevention
			if (nextIdentifierHash == opDispatchId || b == null)
				yield break;

			AbstractType[] overloads;

			var opt = ctxt.CurrentContext.ContextDependentOptions;
			// Look for opDispatch-Members inside b's Definition
			using (ctxt.Push(b))
			{
				ctxt.CurrentContext.ContextDependentOptions = opt; // Mainly required for not resolving opDispatch's return type, as this will be performed later on in higher levels
				overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(opDispatchId, b, ctxt, typeBase, false);
			}

			if (overloads == null || overloads.Length < 0)
				yield break;

			var av = new ArrayValue (Evaluation.GetStringType(ctxt), Strings.TryGet(nextIdentifierHash));

			foreach (DSymbol o in overloads) {
				var dn = o.Definition;
				if (dn.TemplateParameters != null && dn.TemplateParameters.Length > 0 && 
					dn.TemplateParameters[0] is TemplateValueParameter)
				{
					//TODO: Test parameter types for being a string value
					o.SetDeducedTypes(new[]{ new TemplateParameterSymbol(dn.TemplateParameters[0], av) });
					yield return o;
				}
			}
		}
        /// <summary>
        /// http://dlang.org/operatoroverloading.html#Dispatch
        /// Check for the existence of an opDispatch overload.
        /// Important: Because static opDispatches are allowed as well, do check whether we can access non-static overloads from non-instance expressions or such
        /// </summary>
        public static IEnumerable<AbstractType> TryResolveFurtherIdViaOpDispatch(ResolutionContext ctxt, int nextIdentifierHash, UserDefinedType b)
        {
            // The usual SO prevention
            if (nextIdentifierHash == opDispatchId || b == null)
                yield break;

            var pop = ctxt.ScopedBlock != b.Definition;
            if (pop) {
                // Mainly required for not resolving opDispatch's return type, as this will be performed later on in higher levels
                var opt = ctxt.CurrentContext.ContextDependentOptions;
                ctxt.PushNewScope (b.Definition as IBlockNode);
                ctxt.CurrentContext.IntroduceTemplateParameterTypes (b);
                ctxt.CurrentContext.ContextDependentOptions = opt;
            }

            // Look for opDispatch-Members inside b's Definition
            var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier (opDispatchId, new[]{b}, ctxt);

            if(pop)
                ctxt.Pop ();

            if (overloads == null || overloads.Length < 0)
                yield break;

            var av = new ArrayValue (Evaluation.GetStringType(ctxt), Strings.TryGet(nextIdentifierHash));

            foreach (DSymbol o in overloads) {
                var dn = o.Definition;
                if (dn.TemplateParameters != null && dn.TemplateParameters.Length > 0 &&
                    dn.TemplateParameters[0] is TemplateValueParameter)
                {
                    //TODO: Test parameter types for being a string value
                    o.DeducedTypes = new System.Collections.ObjectModel.ReadOnlyCollection<TemplateParameterSymbol> (
                        new[]{ new TemplateParameterSymbol(dn.TemplateParameters[0], av) } );
                    yield return o;
                }
            }
        }