Beispiel #1
0
        FunctionEvaluation(MemberSymbol method, AbstractSymbolValueProvider baseValueProvider, Dictionary<DVariable, ISymbolValue> args)
        {
            vp = new InterpretationContext(baseValueProvider);

            foreach (var kv in args)
                vp[kv.Key] = kv.Value;
        }
Beispiel #2
0
        public static ISymbolValue EvaluateValue(VariableValue v, AbstractSymbolValueProvider vp)
        {
            if (v.RepresentedType is TemplateParameterSymbol)
            {
                var tps = v.RepresentedType as TemplateParameterSymbol;
                if (tps.ParameterValue != null)
                {
                    return(tps.ParameterValue);
                }
            }

            var bt   = v.Member;
            var ctxt = vp.ResolutionContext;

            if (bt != null)
            {
                //TODO: This is not tested entirely - but it makes test passing successfully!
                ctxt.PushNewScope(bt.Definition.Parent as Dom.IBlockNode);
                ctxt.CurrentContext.IntroduceTemplateParameterTypes(bt);
            }

            var val = vp[v.Variable];

            if (bt != null)
            {
                ctxt.Pop();
            }

            return(val ?? v);
        }
Beispiel #3
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (vp == null)
                vp = new StandardValueProvider(null);

            return new Evaluation(vp).E(x) as ISymbolValue;
        }
		public static PrimitiveValue GetPrimitiveValue(string literalCode,AbstractSymbolValueProvider vp=null)
		{
			var v = E(literalCode,vp ?? GetDefaultSymbolVP());

			Assert.That(v,Is.TypeOf(typeof(PrimitiveValue)));
			return (PrimitiveValue)v;
		}
		public static void TestPrimitive(string literal, int btToken, object val, AbstractSymbolValueProvider vp=null)
		{
			var pv = GetPrimitiveValue(literal, vp ?? GetDefaultSymbolVP());

			Assert.That(pv.BaseTypeToken, Is.EqualTo(btToken));
			Assert.That(pv.Value, Is.EqualTo(val));
		}
        static ISemantic HandleCallDelegateType(AbstractSymbolValueProvider ValueProvider, DelegateType dg, List <AbstractType> methodOverloads, bool returnBaseTypeOnly)
        {
            if (returnBaseTypeOnly)
            {
                return(ValueProvider != null ? new TypeValue(dg.Base) as ISemantic : dg.Base);
            }

            /*
             * int a = delegate(x) { return x*2; } (12); // a is 24 after execution
             * auto dg=delegate(x) {return x*3;};
             * int b = dg(4);
             */

            if (ValueProvider == null)
            {
                methodOverloads.Add(dg);
                return(null);
            }
            else
            {
                // If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method.
                //EvalError(dg.DeclarationOrExpressionBase as IExpression, "TODO", dg);
                ValueProvider.LogError(dg.DeclarationOrExpressionBase, "Ctfe not implemented yet");
                return(null);
            }
        }
Beispiel #7
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);
        }
Beispiel #8
0
 public CTFEOrValueRefsVisitor(AbstractSymbolValueProvider vp, IExpression idOrTemplateInstance, bool ImplicitlyExecute = true, ISymbolValue[] executionArguments = null)
 {
     this.ValueProvider        = vp;
     this.ImplicitlyExecute    = ImplicitlyExecute;
     this.idOrTemplateInstance = idOrTemplateInstance;
     this.executionArguments   = executionArguments;
 }
Beispiel #9
0
 Evaluation(AbstractSymbolValueProvider vp)
 {
     this.ValueProvider = vp;
     if(vp!=null)
         vp.ev = this;
     this.eval = true;
     this.ctxt = vp.ResolutionContext;
 }
Beispiel #10
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     if (vp != null && vp.ev != null)
     {
         vp.ev.EvalError(null, "Cannot assign a value to a static property.", new[] { this, value });
     }
     //TODO: What about array.length?
 }
Beispiel #11
0
        /// <summary>
        /// Removes all variable references by resolving them via the given value provider.
        /// Useful when only the value is of interest, not its container or other things.
        /// </summary>
        public static ISymbolValue GetVariableContents(ISymbolValue v, AbstractSymbolValueProvider vp)
        {
            while (v is VariableValue)
            {
                v = vp[((VariableValue)v).Variable];
            }

            return(v);
        }
Beispiel #12
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (vp == null)
            {
                vp = new StandardValueProvider(null);
            }

            return(new Evaluation(vp).E(x) as ISymbolValue);
        }
        public static string EvaluateMixinExpressionContent(AbstractSymbolValueProvider vp,MixinExpression x)
        {
            var ev = new Evaluation(vp);
            ev.resolveConstOnly = true;

            var v = x.AssignExpression != null ? x.AssignExpression.Accept(ev) as ArrayValue : null;

            return v != null && v.IsString ? v.StringValue : null;
        }
        public static string EvaluateMixinExpressionContent(AbstractSymbolValueProvider vp, MixinExpression x)
        {
            var ev = new Evaluation(vp);

            ev.resolveConstOnly = true;

            var v = x.AssignExpression != null?x.AssignExpression.Accept(ev) as ArrayValue : null;

            return(v != null && v.IsString ? v.StringValue : null);
        }
		public static bool IsEqual(IExpression ex, IExpression ex2, AbstractSymbolValueProvider vp)
		{
			var val_x1 = Evaluation.EvaluateValue(ex, vp);
			var val_x2 = Evaluation.EvaluateValue(ex2, vp);

			//TEMPORARILY: Remove the string comparison
			if (val_x1 == null && val_x2 == null)
				return ex.ToString() == ex2.ToString();

			return IsEqual(val_x1, val_x2);
		}
Beispiel #16
0
        public static bool IsEqual(IExpression ex, IExpression ex2, AbstractSymbolValueProvider vp)
        {
            var val_x1 = Evaluation.EvaluateValue(ex, vp);
            var val_x2 = Evaluation.EvaluateValue(ex2, vp);

            //TEMPORARILY: Remove the string comparison
            if (val_x1 == null && val_x2 == null)
                return ex.ToString() == ex2.ToString();

            return IsEqual(val_x1, val_x2);
        }
Beispiel #17
0
        public static void TestBool(string literal, bool v = true, AbstractSymbolValueProvider vp =null)
        {
            var pv = GetPrimitiveValue(literal, vp);

            Assert.AreEqual(DTokens.Bool, pv.BaseTypeToken);

            if (v)
                Assert.AreEqual(1M, pv.Value,  literal +" must be true");
            else
                Assert.AreEqual(0M, pv.Value, literal + " must be false");
        }
Beispiel #18
0
        public static bool EvalIsExpression(string IsExpressionCode, AbstractSymbolValueProvider vp)
        {
            var e = DParser.ParseExpression("is("+IsExpressionCode+")");

            var v = Evaluation.EvaluateValue(e, vp);

            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            var pv = (PrimitiveValue)v;
            Assert.AreEqual(pv.BaseTypeToken, DTokens.Bool, "Type of 'is(" + IsExpressionCode + ")' result must be bool");
            return pv.Value == 1M;
        }
Beispiel #19
0
        public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
        {
            var oldV = vp[Variable];

            if (oldV is AssociativeArrayValue)
            {
                if (Key != null)
                {
                    var aa = (AssociativeArrayValue)oldV;

                    int itemToReplace = -1;

                    for (int i = 0; i < aa.Elements.Count; i++)
                    {
                        if (SymbolValueComparer.IsEqual(aa.Elements[i].Key, Key))
                        {
                            itemToReplace = i;
                            break;
                        }
                    }

                    // If we haven't found a matching key, add it to the array
                    var newElements = new KeyValuePair <ISymbolValue, ISymbolValue> [aa.Elements.Count + (itemToReplace == -1 ? 1: 0)];
                    aa.Elements.CopyTo(newElements, 0);

                    if (itemToReplace != -1)
                    {
                        newElements[itemToReplace] = new KeyValuePair <ISymbolValue, ISymbolValue>(newElements[itemToReplace].Key, value);
                    }
                    else
                    {
                        newElements[newElements.Length - 1] = new KeyValuePair <ISymbolValue, ISymbolValue>(Key, value);
                    }

                    // Finally, make a new associative array containing the new elements
                    vp[Variable] = new AssociativeArrayValue(aa.RepresentedType as AssocArrayType, newElements);
                }
                else
                {
                    if (vp.ev != null)
                    {
                        vp.ev.EvalError(null, "Key expression must not be null", Key);
                    }
                }
            }
            else
            {
                if (vp.ev != null)
                {
                    vp.ev.EvalError(null, "Type of accessed item must be an associative array", oldV);
                }
            }
        }
Beispiel #20
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))
                    {
                        if (vp.ev != null)
                        {
                            vp.ev.EvalError(null, value.ToCode() + " must be implicitly convertible to the array's value type!", value);
                        }
                        return;
                    }

                    // 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
            {
                if (vp.ev != null)
                {
                    vp.ev.EvalError(null, "Type of accessed item must be an array", oldV);
                }
            }
        }
Beispiel #21
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (vp == null)
            {
                vp = new StandardValueProvider(null);
            }

            var ev = new Evaluation(vp);

            var v = x.Accept(ev);

            if (v == null && ev.Errors.Count != 0)
            {
                return(new ErrorValue(ev.Errors.ToArray()));
            }

            return(v);
        }
Beispiel #22
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (x == null)
            {
                return(null);
            }

            if (vp == null)
            {
                throw new ArgumentNullException("vp");
            }
            ISymbolValue v;

            if (vp.ResolutionContext != null)
            {
                if (vp.ResolutionContext.CancelOperation)
                {
                    return(new TypeValue(new UnknownType(x)));
                }

                /*
                 * if (vp is StandardValueProvider) // only for read-only/immutable expression value states
                 * {
                 *      v = vp.ResolutionContext.ValueCache.TryGetType(x);
                 *      if (v != null)
                 *              return v;
                 * }*/
            }

            var ev = new Evaluation(vp);

            v = x.Accept(ev);

            if (v == null && ev.Errors.Count != 0)
            {
                return(new ErrorValue(ev.Errors.ToArray()));
            }

            /*
             * if(vp.ResolutionContext != null && vp is StandardValueProvider)
             *      vp.ResolutionContext.ValueCache.Add(v, x);
             */
            return(v);
        }
Beispiel #23
0
        public static ISymbolValue EvaluateValue(VariableValue v, AbstractSymbolValueProvider vp)
        {
            if (vp.ResolutionContext != null && vp.ResolutionContext.CancelOperation)
            {
                return(v);
            }

            if (v.RepresentedType is TemplateParameterSymbol)
            {
                var tps = v.RepresentedType as TemplateParameterSymbol;
                if (tps.ParameterValue != null)
                {
                    return(tps.ParameterValue);
                }
            }

            using (vp.ResolutionContext.Push(v.Member))
                return(vp[v.Variable] ?? v);
        }
Beispiel #24
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dm"></param>
        /// <param name="args"></param>
        /// <param name="baseValueProvider">Required for evaluating missing default parameters.</param>
        public static bool AssignCallArgumentsToIC(DMethod dm, ISymbolValue[] args, AbstractSymbolValueProvider baseValueProvider,
			out Dictionary<DVariable,ISymbolValue> targetArgs)
        {
            targetArgs = new Dictionary<DVariable, ISymbolValue>();
            var argsRemaining = args != null ? args.Length : 0;
            int argu = 0;

            for (int para = 0; para < dm.Parameters.Count; para++)
            {
                var par = dm.Parameters[para] as DVariable;

                if (par.Type is VarArgDecl && argsRemaining > 0)
                {
                    var va_args = new ISemantic[argsRemaining];
                    args.CopyTo(va_args, argu);
                    argsRemaining=0;
                    //TODO: Assign a value tuple to par
                    if (++para < dm.Parameters.Count)
                        return false;
                }

                if (argsRemaining > 0)
                {
                    targetArgs[par] = args[argu++];
                    argsRemaining--;
                }
                else if (par.Initializer != null)
                {
                    targetArgs[par] = Evaluation.EvaluateValue(par.Initializer, baseValueProvider);
                }
                else
                    return false;
            }

            return argsRemaining == 0;
        }
Beispiel #25
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     throw new EvaluationException(BaseExpression, "Cannot assign a value to a static property.", value);
     //TODO: What about array.length?
 }
Beispiel #26
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (vp == null)
                vp = new StandardValueProvider(null);

            var ev = new Evaluation(vp);

            var v = ev.E(x) as ISymbolValue;

            if(v == null && ev.Errors.Count != 0)
                return new ErrorValue(ev.Errors.ToArray());

            return v;
        }
Beispiel #27
0
		public static ISymbolValue E(string expression, AbstractSymbolValueProvider vp=null)
		{
			return Evaluation.EvaluateValue(DParser.ParseExpression(expression), vp ?? GetDefaultSymbolVP());
		}
Beispiel #28
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     vp[Variable] = value;
 }
 public static ISymbolValue Execute(DMethod method, ISymbolValue[] arguments, AbstractSymbolValueProvider vp)
 {
     throw new NotImplementedException("CTFE is not implemented yet.");
 }
Beispiel #30
0
 Evaluation(AbstractSymbolValueProvider vp)
 {
     this.ValueProvider = vp;
     vp.ev     = this;
     this.ctxt = vp.ResolutionContext;
 }
Beispiel #31
0
 public abstract void Set(AbstractSymbolValueProvider vp, ISymbolValue value);
Beispiel #32
0
 public static ISymbolValue Execute(MemberSymbol method, ISymbolValue[] arguments, AbstractSymbolValueProvider vp)
 {
     return new ErrorValue(new EvaluationException("CTFE is not implemented yet."));
 }
Beispiel #33
0
        /// <summary>
        /// Removes all variable references by resolving them via the given value provider.
        /// Useful when only the value is of interest, not its container or other things.
        /// </summary>
        public static ISymbolValue GetVariableContents(ISymbolValue v, AbstractSymbolValueProvider vp)
        {
            while (v is VariableValue)
                v = vp[(v as VariableValue).Variable];

            return v;
        }
Beispiel #34
0
 private Evaluation(AbstractSymbolValueProvider vp)
 {
     this.ValueProvider = vp;
     this.eval          = true;
     this.ctxt          = vp.ResolutionContext;
 }
        /// <summary>
        /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b).
        /// if <param name="EvalAndFilterOverloads"></param> is false.
        /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned
        /// which stores the return value of the property function b that is executed without arguments.
        /// Also handles UFCS - so if filtering is wanted, the function becom
        /// </summary>
        public static R[] EvalPostfixAccessExpression <R>(ExpressionVisitor <R> vis, ResolutionContext ctxt, PostfixExpression_Access acc,
                                                          ISemantic resultBase = null, bool EvalAndFilterOverloads = true, bool ResolveImmediateBaseType = true, AbstractSymbolValueProvider ValueProvider = null)
            where R : class, ISemantic
        {
            if (acc == null)
            {
                return(null);
            }

            var baseExpression = resultBase ?? (acc.PostfixForeExpression != null ? acc.PostfixForeExpression.Accept(vis) as ISemantic : null);

            if (acc.AccessExpression is NewExpression)
            {
                /*
                 * This can be both a normal new-Expression as well as an anonymous class declaration!
                 */
                //TODO!
                return(null);
            }


            AbstractType[] overloads;
            var            optBackup = ctxt.CurrentContext.ContextDependentOptions;

            if (acc.AccessExpression is TemplateInstanceExpression)
            {
                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                var tix = (TemplateInstanceExpression)acc.AccessExpression;
                // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments!
                overloads = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }

            else if (acc.AccessExpression is IdentifierExpression)
            {
                var id = acc.AccessExpression as IdentifierExpression;

                if (ValueProvider != null && EvalAndFilterOverloads && baseExpression != null)
                {
                    var staticPropResult = StaticProperties.TryEvalPropertyValue(ValueProvider, baseExpression, id.ValueStringHash);
                    if (staticPropResult != null)
                    {
                        return new[] { (R)staticPropResult }
                    }
                    ;
                }

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                overloads = ExpressionTypeEvaluation.GetOverloads(id, ctxt, AmbiguousType.TryDissolve(AbstractType.Get(baseExpression)), EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }
            else
            {            /*
                          *     if (eval){
                          *             EvalError(acc, "Invalid access expression");
                          *             return null;
                          *     }*/
                ctxt.LogError(acc, "Invalid post-dot expression");
                return(null);
            }

            // If evaluation active and the access expression is stand-alone, return a single item only.
            if (EvalAndFilterOverloads && ValueProvider != null)
            {
                return new[] { (R) new Evaluation(ValueProvider).TryDoCTFEOrGetValueRefs(AmbiguousType.Get(overloads, acc.AccessExpression), acc.AccessExpression) }
            }
            ;

            return(overloads as R[]);
        }

        ISymbolValue EvalForeExpression(PostfixExpression ex)
        {
            return(ex.PostfixForeExpression != null?ex.PostfixForeExpression.Accept(this) : null);
        }
Beispiel #36
0
        public static ISymbolValue Execute(MemberSymbol method, Dictionary<DVariable, ISymbolValue> arguments, AbstractSymbolValueProvider vp)
        {
            var dm = method.Definition as DMethod;
            var eval = new FunctionEvaluation(method,vp,arguments);

            var ctxt = vp.ResolutionContext;
            ctxt.PushNewScope(dm, dm.Body);

            try
            {
                dm.Body.Accept(eval);
            }
            catch (CtfeException ex)
            {
                vp.LogError(dm, "Can't execute function at precompile time: " + ex.Message);
            }

            var ret = Evaluation.GetVariableContents(eval.returnedValue, eval.vp);

            ctxt.Pop();

            return ret;

            //return new ErrorValue(new EvaluationException("CTFE is not implemented yet."));
        }
Beispiel #37
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     vp[Variable] = value;
 }
Beispiel #38
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     if(vp != null && vp.ev != null)
         vp.ev.EvalError(null,"Cannot assign a value to a static property.", new[]{this, value});
     //TODO: What about array.length?
 }
Beispiel #39
0
 private Evaluation(AbstractSymbolValueProvider vp)
 {
     this.ValueProvider = vp;
     this.eval = true;
     this.ctxt = vp.ResolutionContext;
 }
Beispiel #40
0
 public abstract void Set(AbstractSymbolValueProvider vp, ISymbolValue value);
        /// <summary>
        /// Used when evaluating traits.
        /// Evaluates the first argument to <param name="t">t</param>,
        /// takes the second traits argument, tries to evaluate it to a string, and puts it + the first arg into an postfix_access expression
        /// </summary>
        internal static PostfixExpression_Access prepareMemberTraitExpression(ResolutionContext ctxt, TraitsExpression te, out AbstractType t, AbstractSymbolValueProvider vp = null)
        {
            if (te.Arguments != null && te.Arguments.Length == 2)
            {
                var tEx = te.Arguments[0];
                t = DResolver.StripMemberSymbols(ResolveTraitArgument(ctxt, tEx));

                if (t == null)
                {
                    ctxt.LogError(te, "First argument didn't resolve to a type");
                }
                else if (te.Arguments[1].AssignExpression != null)
                {
                    var litEx = te.Arguments[1].AssignExpression;
                    var v     = vp != null?Evaluation.EvaluateValue(litEx, vp) : Evaluation.EvaluateValue(litEx, ctxt);

                    if (v is ArrayValue && (v as ArrayValue).IsString)
                    {
                        var av = v as ArrayValue;

                        // Mock up a postfix_access expression to ensure static properties & ufcs methods are checked either
                        return(new PostfixExpression_Access
                        {
                            PostfixForeExpression = tEx.AssignExpression ?? new TypeDeclarationExpression(tEx.Type),
                            AccessExpression = new IdentifierExpression(av.StringValue)
                            {
                                Location = litEx.Location,
                                EndLocation = litEx.EndLocation
                            },
                            EndLocation = litEx.EndLocation
                        });
                    }
                    else
                    {
                        ctxt.LogError(litEx, "Second traits argument must evaluate to a string literal");
                    }
                }
                else
                {
                    ctxt.LogError(te, "Second traits argument must be an expression");
                }
            }

            t = null;
            return(null);
        }
Beispiel #42
0
        public static ISymbolValue EvaluateValue(VariableValue v, AbstractSymbolValueProvider vp)
        {
            if(v.RepresentedType is TemplateParameterSymbol)
            {
                var tps = v.RepresentedType as TemplateParameterSymbol;
                if(tps.ParameterValue != null)
                    return tps.ParameterValue;
            }

            var bt = v.Member;
            var ctxt = vp.ResolutionContext;
            bool pop=false;

            if(bt != null)
            {
                //TODO: This is not tested entirely - but it makes test passing successfully!
                pop = true;
                ctxt.PushNewScope (bt.Definition.Parent as Dom.IBlockNode);
                ctxt.CurrentContext.IntroduceTemplateParameterTypes(bt);
            }

            var val = vp[v.Variable];

            if(bt != null)
            {
                if (pop)
                    ctxt.Pop ();
                vp.ResolutionContext.CurrentContext.RemoveParamTypesFromPreferredLocals(bt);
            }

            return val ?? v;
        }
        public static AbstractType EvalMethodCall(AbstractType[] baseExpression, ISymbolValue baseValue, TemplateInstanceExpression tix,
                                                  ResolutionContext ctxt,
                                                  PostfixExpression_MethodCall call, out List <ISemantic> callArguments, out ISymbolValue delegateValue,
                                                  bool returnBaseTypeOnly, AbstractSymbolValueProvider ValueProvider = null)
        {
            //TODO: Refactor this crap!

            delegateValue = null;
            callArguments = null;

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = baseExpression;
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is AmbiguousType)
                    {
                        nextResults.AddRange((b as AmbiguousType).Overloads);
                    }
                    else if (b is TemplateParameterSymbol)
                    {
                        nextResults.Add((b as TemplateParameterSymbol).Base);
                    }
                    else if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (ValueProvider != null)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    ValueProvider.LogError(call, "Variable must be a delegate, not anything else");
                                    return(null);
                                }
                            }
                            else
                            {
                                var bt = mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt);

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    var ret = HandleCallDelegateType(ValueProvider, bt as DelegateType, methodOverloads, returnBaseTypeOnly);
                                    if (ret is ISymbolValue)
                                    {
                                        delegateValue = ret as ISymbolValue;
                                        return(null);
                                    }
                                    else if (ret is AbstractType)
                                    {
                                        return(ret as AbstractType);
                                    }
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var ret = HandleCallDelegateType(ValueProvider, b as DelegateType, methodOverloads, returnBaseTypeOnly);
                        if (ret is ISymbolValue)
                        {
                            delegateValue = ret as ISymbolValue;
                            return(null);
                        }
                        else if (ret is AbstractType)
                        {
                            return(ret as AbstractType);
                        }
                    }
                    else if (b is ClassType || b is StructType)
                    {
                        var tit = (TemplateIntermediateType)b;

                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = tit.Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in ExpressionTypeEvaluation.GetOpCalls(tit, requireStaticItems))
                        {
                            methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                        }

                        /*
                         * Every struct can contain a default ctor:
                         *
                         * struct S { int a; bool b; }
                         *
                         * auto s = S(1,true); -- ok
                         * auto s2= new S(2,false); -- error, no constructor found!
                         */
                        if (b is StructType && methodOverloads.Count == 0)
                        {
                            //TODO: Deduce parameters
                            return(b);
                        }
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType)
                    {
                        methodOverloads.Add(b);
                    }
                    else if (b is PrimitiveType)                     // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal.
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            callArguments = new List <ISemantic>();

            if (call.Arguments != null)
            {
                if (ValueProvider != null)
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? Evaluation.EvaluateValue(arg, ValueProvider) : null);
                    }
                }
                else
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? ExpressionTypeEvaluation.EvaluateType(arg, ctxt) : null);
                    }
                }
            }

            #region If explicit template type args were given, try to associate them with each overload
            if (tix != null)
            {
                var args             = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt);
                var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt);
                methodOverloads.Clear();
                if (deducedOverloads != null)
                {
                    methodOverloads.AddRange(deducedOverloads);
                }
            }
            #endregion

            #region Filter by parameter-argument comparison
            var          argTypeFilteredOverloads   = new List <AbstractType>();
            bool         hasHandledUfcsResultBefore = false;
            AbstractType untemplatedMethodResult    = null;

            foreach (var ov in methodOverloads)
            {
                if (ov is MemberSymbol)
                {
                    HandleDMethodOverload(ctxt, ValueProvider != null, baseValue, callArguments, returnBaseTypeOnly, argTypeFilteredOverloads, ref hasHandledUfcsResultBefore,
                                          ov as MemberSymbol, ref untemplatedMethodResult);
                }
                else if (ov is DelegateType)
                {
                    var dg = ov as DelegateType;
                    var bt = dg.Base ?? TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                    //TODO: Param-Arg check

                    if (returnBaseTypeOnly)
                    {
                        argTypeFilteredOverloads.Add(bt);
                    }
                    else
                    {
                        if (dg.Base == null)
                        {
                            if (dg.IsFunctionLiteral)
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters);
                            }
                            else
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as DelegateDeclaration, dg.Parameters);
                            }
                        }
                        argTypeFilteredOverloads.Add(new DelegateCallSymbol(dg, call));
                    }
                }
                else if (ov is PrimitiveType)                 // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal.
                {
                    if (ValueProvider != null)
                    {
                        if (callArguments == null || callArguments.Count != 1)
                        {
                            ValueProvider.LogError(call, "Uniform construction syntax expects exactly one argument");
                        }
                        else
                        {
                            var pv = callArguments[0] as PrimitiveValue;
                            if (pv == null)
                            {
                                ValueProvider.LogError(call, "Uniform construction syntax expects one built-in scalar value as first argument");
                            }
                            else
                            {
                                delegateValue = new PrimitiveValue(pv.Value, ov as PrimitiveType, pv.ImaginaryPart);
                            }
                        }
                    }

                    argTypeFilteredOverloads.Add(ov);
                }
            }

            // Prefer untemplated methods over templated ones
            if (untemplatedMethodResult != null)
            {
                return(untemplatedMethodResult);
            }
            #endregion

            return(AmbiguousType.Get(argTypeFilteredOverloads, tix));
        }
Beispiel #44
0
        public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
        {
            var oldV = vp[Variable];

            if (oldV is AssociativeArrayValue)
            {
                if (Key != null)
                {
                    var aa = (AssociativeArrayValue)oldV;

                    int itemToReplace = -1;

                    for (int i = 0; i < aa.Elements.Count; i++)
                        if (SymbolValueComparer.IsEqual(aa.Elements[i].Key, Key))
                        {
                            itemToReplace = i;
                            break;
                        }

                    // If we haven't found a matching key, add it to the array
                    var newElements = new KeyValuePair<ISymbolValue, ISymbolValue>[aa.Elements.Count + (itemToReplace == -1 ? 1 : 0)];
                    aa.Elements.CopyTo(newElements, 0);

                    if (itemToReplace != -1)
                        newElements[itemToReplace] = new KeyValuePair<ISymbolValue, ISymbolValue>(newElements[itemToReplace].Key, value);
                    else
                        newElements[newElements.Length - 1] = new KeyValuePair<ISymbolValue, ISymbolValue>(Key, value);

                    // Finally, make a new associative array containing the new elements
                    vp[Variable] = new AssociativeArrayValue(aa.RepresentedType as AssocArrayType, newElements);
                }
                else{
                    if(vp.ev !=null) vp.ev.EvalError(null,"Key expression must not be null", Key);
                }
            }
            else{
                if(vp.ev != null) vp.ev.EvalError(null,"Type of accessed item must be an associative array", oldV);
            }
        }
Beispiel #45
0
        public static ISymbolValue TryEvalPropertyValue(AbstractSymbolValueProvider vp, ISemantic baseSymbol, int propName)
        {
            var props = Properties[PropOwnerType.Generic];
            StaticPropertyInfo prop;

            if (props.TryGetValue(propName, out prop) || (Properties.TryGetValue(GetOwnerType(baseSymbol), out props) && props.TryGetValue(propName, out prop)))
            {
                if (prop.ValueGetter != null)
                    return prop.ValueGetter(vp, baseSymbol);
            }

            return null;
        }
Beispiel #46
0
 public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value)
 {
     throw new EvaluationException(BaseExpression, "Cannot assign a value to a static property.", value);
     //TODO: What about array.length?
 }