/// <summary>
        /// Returns false if the item has already been set before and if the already set item is not equal to 'r'.
        /// Inserts 'r' into the target dictionary and returns true otherwise.
        /// </summary>
        bool Set(ITemplateParameter p, ISemantic r, string name = null)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = p.Name;
            }

            TemplateParameterSymbol rl = null;

            if (!TargetDictionary.TryGetValue(name, out rl) || rl == null)
            {
                TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner);
                return(true);
            }
            else
            {
                if (rl != null)
                {
                    if (ResultComparer.IsEqual(rl.Base, r))
                    {
                        return(true);
                    }
                    else
                    {
                        // Error: Ambiguous assignment
                    }
                }

                TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner);

                return(false);
            }
        }
        public long GetCustomerAndOrdersByEmp(int empID)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Order> result;

            using (IDbConnection db = new SqlConnection(connString))
            {
                result = db.Query <Order, Employee, Customer, Order>(Constants.GET_ENTIRE_ORDER,
                                                                     (order, employee, customer) =>
                {
                    order.Employee = employee;
                    order.Customer = customer;
                    return(order);
                },
                                                                     new { EmployeeID = empID },
                                                                     splitOn: "EmployeeID, CustomerID").ToList();
            }
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetCustomerAndOrdersByEmp(result, method);

            return(elapsedTime);
        }
Пример #3
0
 protected void MaybeOnResultChanged(BindingResult<TResult> newResult)
 {
     if (!ResultComparer.Equals(newResult, Result))
     {
         OnResultChanged(newResult);
     }
 }
Пример #4
0
        public IEnumerable <DMethod> FindFitting(ResolverContextStack ctxt, CodeLocation currentLocation, ISemantic firstArgument, string nameFilter = null)
        {
            if (IsProcessing)
            {
                return(null);
            }

            var preMatchList = new List <DMethod>();

            bool dontUseNameFilter = nameFilter == null;

            lock (CachedMethods)
                foreach (var kv in CachedMethods)
                {
                    // First test if arg is matching the parameter
                    if ((dontUseNameFilter || kv.Key.Name == nameFilter) &&
                        ResultComparer.IsImplicitlyConvertible(firstArgument, kv.Value, ctxt))
                    {
                        preMatchList.Add(kv.Key);
                    }
                }

            // Then filter out methods which cannot be accessed in the current context
            // (like when the method is defined in a module that has not been imported)
            var mv = new MatchFilterVisitor <DMethod>(ctxt, preMatchList);

            mv.IterateThroughScopeLayers(currentLocation);

            return(mv.filteredList);
        }
        public long GetOrdersByCustomer(string id)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Order> customerOrders;

            using (IDbConnection db = new SqlConnection(connString))
            {
                customerOrders = db.Query <Order, Customer, Order>(Constants.GET_CUSTOMERS_ORDER,
                                                                   (order, customer) =>
                {
                    order.Customer = customer;
                    return(order);
                },
                                                                   new { CustomerID = id },
                                                                   splitOn: "CustomerID").ToList();
            }
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetOrdersByCustomer(customerOrders, method);

            return(elapsedTime);
        }
        bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r)
        {
            // Bottom-level reached
            if (id.InnerDeclaration == null && Contains(id.IdHash) && !id.ModuleScoped)
            {
                // Associate template param with r
                return(Set((p != null && id.IdHash == p.NameHash) ? p : null, r, id.IdHash));
            }

            var deducee = DResolver.StripMemberSymbols(AbstractType.Get(r)) as DSymbol;

            if (id.InnerDeclaration != null && deducee != null && deducee.Definition.NameHash == id.IdHash)
            {
                var physicalParentType = TypeDeclarationResolver.HandleNodeMatch(deducee.Definition.Parent, ctxt, null, id.InnerDeclaration);
                if (HandleDecl(p, id.InnerDeclaration, physicalParentType))
                {
                    if (Contains(id.IdHash))
                    {
                        Set((p != null && id.IdHash == p.NameHash) ? p : null, deducee, id.IdHash);
                    }
                    return(true);
                }
            }

            /*
             * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r
             */
            var _r = TypeDeclarationResolver.ResolveSingle(id, ctxt);

            return(_r != null && (EnforceTypeEqualityWhenDeducing ?
                                  ResultComparer.IsEqual(r, _r) :
                                  ResultComparer.IsImplicitlyConvertible(r, _r)));
        }
Пример #7
0
        void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
        {
            if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
            {
                var pop = ctxt.ScopedBlock != dm;
                if (pop)
                {
                    ctxt.PushNewScope(dm);
                }

                var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters [0].Type, ctxt);
                if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt))
                {
                    var res = alreadyResolvedMethod ?? new MemberSymbol(dm, null, sr);
                    res.Tag = new UfcsTag {
                        firstArgument = firstArgument
                    };
                    matches.Add(res);
                }

                if (pop)
                {
                    ctxt.Pop();
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Returns false if the item has already been set before and if the already set item is not equal to 'r'.
        /// Inserts 'r' into the target dictionary and returns true otherwise.
        /// </summary>
        bool Set(TemplateParameter p, ISemantic r, int nameHash)
        {
            if (p == null)
            {
                if (nameHash != 0 && TargetDictionary.ExpectedParameters != null)
                {
                    foreach (var tpar in TargetDictionary.ExpectedParameters)
                    {
                        if (tpar.NameHash == nameHash)
                        {
                            p = tpar;
                            break;
                        }
                    }
                }
            }

            if (p == null)
            {
                ctxt.LogError(null, "no fitting template parameter found!");
                return(false);
            }

            // void call(T)(T t) {}
            // call(myA) -- T is *not* myA but A, so only assign myA's type to T.
            if (p is TemplateTypeParameter)
            {
                var newR = Resolver.TypeResolution.DResolver.StripMemberSymbols(AbstractType.Get(r));
                if (newR != null)
                {
                    r = newR;
                }
            }

            TemplateParameterSymbol rl;

            if (!TargetDictionary.TryGetValue(p, out rl) || rl == null)
            {
                TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                return(true);
            }
            else
            {
                if (ResultComparer.IsEqual(rl.Base, r))
                {
                    TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                    return(true);
                }
                else if (rl == null)
                {
                    TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                }

                // Error: Ambiguous assignment

                return(false);
            }
        }
        bool Handle(TemplateValueParameter p, ISemantic arg)
        {
            // Handle default arg case
            if (arg == null)
            {
                if (p.DefaultExpression != null)
                {
                    var eval = Evaluation.EvaluateValue(p.DefaultExpression, ctxt);

                    if (eval == null)
                    {
                        return(false);
                    }

                    return(Set(p, eval));
                }
                else
                {
                    return(false);
                }
            }

            var valueArgument = arg as ISymbolValue;

            // There must be a constant expression given!
            if (valueArgument == null)
            {
                return(false);
            }

            // Check for param type <-> arg expression type match
            var paramType = TypeDeclarationResolver.Resolve(p.Type, ctxt);

            if (paramType == null || paramType.Length == 0)
            {
                return(false);
            }

            if (valueArgument.RepresentedType == null ||
                !ResultComparer.IsImplicitlyConvertible(paramType[0], valueArgument.RepresentedType))
            {
                return(false);
            }

            // If spec given, test for equality (only ?)
            if (p.SpecializationExpression != null)
            {
                var specVal = Evaluation.EvaluateValue(p.SpecializationExpression, ctxt);

                if (specVal == null || !SymbolValueComparer.IsEqual(specVal, valueArgument))
                {
                    return(false);
                }
            }

            return(Set(p, arg));
        }
        static bool HandleDecl(DTokenDeclaration tk, AbstractType r)
        {
            if (r is PrimitiveType)
            {
                return(ResultComparer.IsPrimitiveTypeImplicitlyConvertible(((PrimitiveType)r).TypeToken, tk.Token));
            }

            return(false);
        }
        bool HandleDecl(TypeOfDeclaration t, AbstractType r)
        {
            // Can I enter some template parameter referencing id into a typeof specialization!?
            // class Foo(T:typeof(1)) {} ?
            var t_res = TypeDeclarationResolver.Resolve(t, ctxt);

            if (t_res == null)
            {
                return(false);
            }

            return(ResultComparer.IsImplicitlyConvertible(r, t_res));
        }
Пример #12
0
        private bool evalIsExpression_NoAlias(IsExpression isExpression, AbstractType typeToCheck)
        {
            if (isExpression.TypeSpecialization != null)
            {
                var spec = DResolver.StripAliasSymbols(TypeDeclarationResolver.Resolve(isExpression.TypeSpecialization, ctxt));

                return(spec != null && spec.Length != 0 && (isExpression.EqualityTest ?
                                                            ResultComparer.IsEqual(typeToCheck, spec[0]) :
                                                            ResultComparer.IsImplicitlyConvertible(typeToCheck, spec[0], ctxt)));
            }

            return(isExpression.EqualityTest && evalIsExpression_EvalSpecToken(isExpression, typeToCheck, false).Item1);
        }
Пример #13
0
        public static void RouteMatched <TValues>(
            this Assert assert,
            RouteBuilder.IBuildRoutesWithVariablesToMatch <TValues> routeInfo,
            UrlPathDetails url,
            TValues expectedValue,
            ResultComparer <TValues> comparer)
        {
            var routeMatched = false;
            var route        = routeInfo.ToRoute(extractedValue => routeMatched = comparer(extractedValue, expectedValue));

            route.ExecuteCallbackIfUrlMatches(url);
            assert.Ok(routeMatched);
        }
Пример #14
0
            protected override bool HandleItem(INode n)
            {
                AbstractType t;

                if (n is DMethod &&
                    (nameFilterHash == 0 || n.NameHash == nameFilterHash) &&
                    cache.TryGetValue(n as DMethod, out t) &&
                    ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt))
                {
                    filteredMethods.Add(n as DMethod);
                }

                return(false);
            }
Пример #15
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);
                }
            }
        }
Пример #16
0
        public long GetOrdersByCustomer(string customerId)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            var query = from order in db.Orders
                        join customer in db.Customers on order.CustomerID equals customer.CustomerID
                        where customer.CustomerID == customerId
                        select order;

            query.ToList();
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetOrdersByCustomer(query.ToList(), method);
            return(elapsedTime);
        }
        public long GetCustomersByCountry(string countryName)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Customer> result;

            using (IDbConnection db = new SqlConnection(connString))
            {
                result = db.Query <Customer>(Constants.GET_CUSTOMERS_BY_COUNTRY, new { Country = countryName }).ToList();
            }
            clock.Stop();
            ResultComparer.getCustomerData(result, method);
            var elapsedTime = clock.ElapsedMilliseconds;

            return(elapsedTime);
        }
Пример #18
0
        public long GetCustomersByCountry(string countryName)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            var query = from c in db.Customers
                        where c.Country == countryName
                        select c;

            clock.Stop();
            query.ToList();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.getCustomerData(query.ToList(), method);

            return(elapsedTime);
        }
        public long GetCustomerAndOrdersByEmp(int empId)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Order> result;

            using (NwEntityContext context = new NwEntityContext())
            {
                result = context.Orders.Include(x => x.Customer).Include(x => x.Customer).Include(x => x.Employee).Where(x => x.Employee.EmployeeID == empId).ToList();
            }
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetCustomerAndOrdersByEmp(result, method);

            return(elapsedTime);
        }
        public long GetCustomersByCountry(string countryName)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Customer> result;

            using (NwEntityContext context = new NwEntityContext())
            {
                result = context.Customers.Where(x => x.Country == countryName).ToList();
            }
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.getCustomerData(result, method);

            return(elapsedTime);
        }
        public long GetOrdersByCustomer(string customerId)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            List <Order> result;

            using (NwEntityContext context = new NwEntityContext())
            {
                result = context.Orders.Include(x => x.Customer).Include(x => x.Customer).Where(x => x.Customer.CustomerID == customerId).ToList();
            }
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetOrdersByCustomer(result, method);

            return(elapsedTime);
        }
        bool HandleDecl(VectorDeclaration v, AbstractType r)
        {
            if (r.DeclarationOrExpressionBase is VectorDeclaration)
            {
                var v_res = ExpressionTypeEvaluation.EvaluateType(v.Id, ctxt);
                var r_res = ExpressionTypeEvaluation.EvaluateType(((VectorDeclaration)r.DeclarationOrExpressionBase).Id, ctxt);

                if (v_res == null || r_res == null)
                {
                    return(false);
                }
                else
                {
                    return(ResultComparer.IsImplicitlyConvertible(r_res, v_res));
                }
            }
            return(false);
        }
Пример #23
0
 void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
 {
     if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
     {
         var loc = dm.Body != null ? dm.Body.Location : dm.Location;
         using (alreadyResolvedMethod != null ? ctxt.Push(alreadyResolvedMethod, loc) : ctxt.Push(dm, loc))
         {
             var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters[0].Type, ctxt);
             if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt))
             {
                 var res = alreadyResolvedMethod ?? TypeDeclarationResolver.HandleNodeMatch(dm, ctxt, typeBase: sr);
                 res.Tag = new UfcsTag {
                     firstArgument = firstArgument
                 };
                 matches.Add(res);
             }
         }
     }
 }
Пример #24
0
        public long GetCustomerAndOrdersByEmp(int empId)
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();
            var query = from order in db.Orders
                        join customer in db.Customers on order.CustomerID equals customer.CustomerID
                        join employee in db.Employees on order.EmployeeID equals employee.EmployeeID
                        where employee.EmployeeID == empId
                        select order;

            query.ToList();
            clock.Stop();
            var elapsedTime = clock.ElapsedMilliseconds;

            ResultComparer.GetCustomerAndOrdersByEmp(query.ToList(), method);


            return(elapsedTime);
        }
Пример #25
0
        bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r)
        {
            // Bottom-level reached
            if (id.InnerDeclaration == null && Contains(id.Id) && !id.ModuleScoped)
            {
                // Associate template param with r
                return(Set(p, r, id.Id));
            }

            /*
             * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r
             */
            var _r = TypeDeclarationResolver.Resolve(id, ctxt);

            ctxt.CheckForSingleResult(_r, id);

            return(_r != null && _r.Length != 0 &&
                   (EnforceTypeEqualityWhenDeducing ?
                    ResultComparer.IsEqual(r, _r[0]) :
                    ResultComparer.IsImplicitlyConvertible(r, _r[0])));
        }
        internal static bool TryHandleMethodArgumentTuple(ResolutionContext ctxt, ref bool add,
                                                          List <ISemantic> callArguments,
                                                          DMethod dm,
                                                          DeducedTypeDictionary deducedTypeDict, int currentParameter, ref int currentArg)
        {
            // .. so only check if it's an identifer & if the id represents a tuple parameter
            var id                 = dm.Parameters[currentParameter].Type as IdentifierDeclaration;
            var curNode            = dm as DNode;
            TemplateParameter tpar = null;

            while (curNode != null && !curNode.TryGetTemplateParameter(id.IdHash, out tpar))
            {
                curNode = curNode.Parent as DNode;
            }

            if (!(tpar is TemplateTupleParameter))
            {
                return(false);
            }

            int lastArgumentToTake = -1;

            /*
             * Note: an expression tuple parameter can occur also somewhere in between the parameter list!
             * void write(A...)(bool b, A a, double d) {}
             *
             * can be matched by
             * write(true, 1.2) as well as
             * write(true, "asdf", 1.2) as well as
             * write(true, 123, true, 'c', [3,4,5], 3.4) !
             */

            TemplateParameterSymbol tps;
            DTuple tuple = null;

            if (deducedTypeDict.TryGetValue(tpar, out tps) && tps != null)
            {
                if (tps.Base is DTuple)
                {
                    tuple = tps.Base as DTuple;
                    lastArgumentToTake = currentParameter + (tuple.Items == null ? 0 : (tuple.Items.Length - 1));
                }
                else
                {
                    // Error: Type param must be tuple!
                }
            }
            // - Get the (amount of) arguments that shall be put into the tuple
            else if (currentParameter == dm.Parameters.Count - 1)
            {
                // The usual case: A tuple of a variable length is put at the end of a parameter list..
                // take all arguments from i until the end of the argument list..
                // ; Also accept empty tuples
                lastArgumentToTake = callArguments.Count - 1;
            }
            else
            {
                // Get the type of the next expected parameter
                var nextExpectedParameter = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(dm.Parameters[currentParameter + 1].Type, ctxt));

                // Look for the first argument whose type is equal to the next parameter's type..
                for (int k = currentArg; k < callArguments.Count; k++)
                {
                    if (ResultComparer.IsEqual(AbstractType.Get(callArguments[k]), nextExpectedParameter))
                    {
                        // .. and assume the tuple to go from i to the previous argument..
                        lastArgumentToTake = k - 1;
                        break;
                    }
                }
            }

            int argCountToHandle = lastArgumentToTake - currentArg + 1;

            if (tuple != null)
            {
                // - If there's been set an explicit type tuple, compare all arguments' types with those in the tuple
                if (tuple.Items != null)
                {
                    foreach (ISemantic item in tuple.Items)
                    {
                        if (currentArg >= callArguments.Count || !ResultComparer.IsImplicitlyConvertible(callArguments[currentArg++], AbstractType.Get(item), ctxt))
                        {
                            add = false;
                            return(true);
                        }
                    }
                }
            }
            else
            {
                // - If there was no explicit initialization, put all arguments' types into a type tuple
                var argsToTake = new ISemantic[argCountToHandle];
                callArguments.CopyTo(currentArg, argsToTake, 0, argsToTake.Length);
                currentArg += argsToTake.Length;
                var tt = new DTuple(null, argsToTake);
                tps = new TemplateParameterSymbol(tpar, tt);

                //   and set the actual template tuple parameter deduction
                deducedTypeDict[tpar] = tps;
            }
            add = true;
            return(true);
        }
        /// <summary>
        /// a + b; a - b; etc.
        /// </summary>
        ISemantic E_MathOp(OperatorBasedExpression x, ISemantic lValue = null, ISemantic rValue = null)
        {
            if (!eval)
            {
                return(lValue ?? E(x.LeftOperand));
            }

            var l = TryGetValue(lValue ?? E(x.LeftOperand));

            if (l == null)
            {
                /*
                 * In terms of adding opOverloading later on,
                 * lvalue not being a PrimitiveValue shouldn't be a problem anymore - we simply had to
                 * search the type of l for methods called opAdd etc. and call that method via ctfe.
                 * Finally, return the value the opAdd method passed back - and everything is fine.
                 */

                /*
                 * Also, pointers should be implemented later on.
                 * http://dlang.org/expression.html#AddExpression
                 */

                throw new EvaluationException(x, "Left value must evaluate to a constant scalar value. Operator overloads aren't supported yet", lValue);
            }

            //TODO: Operator overloading

            // Note: a * b + c is theoretically treated as a * (b + c), but it's needed to evaluate it as (a * b) + c !
            if (x is MulExpression || x is PowExpression)
            {
                if (x.RightOperand is OperatorBasedExpression && !(x.RightOperand is AssignExpression))                 //TODO: This must be true only if it's a math expression, so not an assign expression etc.
                {
                    var sx = (OperatorBasedExpression)x.RightOperand;

                    // Now multiply/divide/mod expression 'l' with sx.LeftOperand
                    var intermediateResult = HandleSingleMathOp(x, l, E(sx.LeftOperand), mult);

                    // afterwards, evaluate the operation between the result just returned and the sx.RightOperand.
                    return(E(sx, intermediateResult));
                }

                return(HandleSingleMathOp(x, l, rValue ?? E(x.RightOperand), mult));
            }

            var r = TryGetValue(rValue ?? E(x.RightOperand));

            if (r == null)
            {
                throw new EvaluationException(x, "Right operand must evaluate to a value", lValue);
            }

            /*
             * TODO: Handle invalid values/value ranges.
             */

            if (x is XorExpression)
            {
                return(HandleSingleMathOp(x, l, r, (a, b) => {
                    EnsureIntegralType(a); EnsureIntegralType(b);
                    return (long)a.Value ^ (long)b.Value;
                }));
            }
            else if (x is OrExpression)
            {
                return(HandleSingleMathOp(x, l, r, (a, b) =>
                {
                    EnsureIntegralType(a); EnsureIntegralType(b);
                    return (long)a.Value | (long)b.Value;
                }));
            }
            else if (x is AndExpression)
            {
                return(HandleSingleMathOp(x, l, r, (a, b) =>
                {
                    EnsureIntegralType(a); EnsureIntegralType(b);
                    return (long)a.Value & (long)b.Value;
                }));
            }
            else if (x is ShiftExpression)
            {
                return(HandleSingleMathOp(x, l, r, (a, b) =>
                {
                    EnsureIntegralType(a); EnsureIntegralType(b);
                    if (b.Value < 0 || b.Value > 31)
                    {
                        throw new EvaluationException(b.BaseExpression, "Shift operand must be between 0 and 31", b);
                    }

                    switch (x.OperatorToken)
                    {
                    case DTokens.ShiftLeft:
                        return (long)a.Value << (int)b.Value;                                 // TODO: Handle the imaginary part

                    case DTokens.ShiftRight:
                        return (long)a.Value >> (int)b.Value;

                    case DTokens.ShiftRightUnsigned:                             //TODO: Find out where's the difference between >> and >>>
                        return (ulong)a.Value >> (int)(uint)b.Value;
                    }

                    throw new EvaluationException(x, "Invalid token for shift expression", l, r);
                }));
            }
            else if (x is AddExpression)
            {
                return(HandleSingleMathOp(x, l, r, (a, b, op) =>
                {
                    switch (op.OperatorToken)
                    {
                    case DTokens.Plus:
                        return new PrimitiveValue(a.BaseTypeToken, a.Value + b.Value, x, a.ImaginaryPart + b.ImaginaryPart);

                    case DTokens.Minus:
                        return new PrimitiveValue(a.BaseTypeToken, a.Value - b.Value, x, a.ImaginaryPart - b.ImaginaryPart);
                    }

                    throw new EvaluationException(x, "Invalid token for add/sub expression", l, r);
                }));
            }
            else if (x is CatExpression)
            {
                // Notable: If one element is of the value type of the array, the element is added (either at the front or at the back) to the array

                var av_l = l as ArrayValue;
                var av_r = r as ArrayValue;

                if (av_l != null && av_r != null)
                {
                    // Ensure that both arrays are of the same type
                    if (!ResultComparer.IsEqual(av_l.RepresentedType, av_r.RepresentedType))
                    {
                        throw new EvaluationException(x, "Both arrays must be of same type", l, r);
                    }

                    // Might be a string
                    if (av_l.IsString && av_r.IsString)
                    {
                        return(new ArrayValue(av_l.RepresentedType as ArrayType, x, av_l.StringValue + av_r.StringValue));
                    }
                    else
                    {
                        var elements = new ISymbolValue[av_l.Elements.Length + av_r.Elements.Length];
                        Array.Copy(av_l.Elements, 0, elements, 0, av_l.Elements.Length);
                        Array.Copy(av_r.Elements, 0, elements, av_l.Elements.Length, av_r.Elements.Length);

                        return(new ArrayValue(av_l.RepresentedType as ArrayType, elements));
                    }
                }

                ArrayType at = null;

                // Append the right value to the array
                if (av_l != null && (at = av_l.RepresentedType as ArrayType) != null &&
                    ResultComparer.IsImplicitlyConvertible(r.RepresentedType, at.ValueType, ctxt))
                {
                    var elements = new ISymbolValue[av_l.Elements.Length + 1];
                    Array.Copy(av_l.Elements, elements, av_l.Elements.Length);
                    elements[elements.Length - 1] = r;

                    return(new ArrayValue(at, elements));
                }
                // Put the left value into the first position
                else if (av_r != null && (at = av_r.RepresentedType as ArrayType) != null &&
                         ResultComparer.IsImplicitlyConvertible(l.RepresentedType, at.ValueType, ctxt))
                {
                    var elements = new ISymbolValue[1 + av_r.Elements.Length];
                    elements[0] = l;
                    Array.Copy(av_r.Elements, 0, elements, 1, av_r.Elements.Length);

                    return(new ArrayValue(at, elements));
                }

                throw new EvaluationException(x, "At least one operand must be an (non-associative) array. If so, the other operand must be of the array's element type.", l, r);
            }

            throw new WrongEvaluationArgException();
        }
Пример #28
0
        /// <summary>
        /// Item1 - True, if isExpression returns true
        /// Item2 - If Item1 is true, it contains the type of the alias that is defined in the isExpression
        /// </summary>
        private Tuple <bool, AbstractType> evalIsExpression_EvalSpecToken(IsExpression isExpression, AbstractType typeToCheck, bool DoAliasHandling = false)
        {
            bool         r   = false;
            AbstractType res = null;

            switch (isExpression.TypeSpecializationToken)
            {
            /*
             * To handle semantic tokens like "return" or "super" it's just needed to
             * look into the current resolver context -
             * then, we'll be able to gather either the parent method or the currently scoped class definition.
             */
            case DTokens.Struct:
            case DTokens.Union:
            case DTokens.Class:
            case DTokens.Interface:
                if (r = typeToCheck is UserDefinedType &&
                        ((TemplateIntermediateType)typeToCheck).Definition.ClassType == isExpression.TypeSpecializationToken)
                {
                    res = typeToCheck;
                }
                break;

            case DTokens.Enum:
                if (!(typeToCheck is EnumType))
                {
                    break;
                }
                {
                    var tr = (UserDefinedType)typeToCheck;
                    r   = true;
                    res = tr.Base;
                }
                break;

            case DTokens.Function:
            case DTokens.Delegate:
                if (typeToCheck is DelegateType)
                {
                    var isFun = false;
                    var dgr   = (DelegateType)typeToCheck;
                    if (!dgr.IsFunctionLiteral)
                    {
                        r = isExpression.TypeSpecializationToken == (
                            (isFun = ((DelegateDeclaration)dgr.DeclarationOrExpressionBase).IsFunction) ? DTokens.Function : DTokens.Delegate);
                    }
                    // Must be a delegate otherwise
                    else
                    {
                        isFun = !(r = isExpression.TypeSpecializationToken == DTokens.Delegate);
                    }

                    if (r)
                    {
                        //TODO
                        if (isFun)
                        {
                            // TypeTuple of the function parameter types. For C- and D-style variadic functions, only the non-variadic parameters are included.
                            // For typesafe variadic functions, the ... is ignored.
                        }
                        else
                        {
                            // the function type of the delegate
                        }
                    }
                }
                else                         // Normal functions are also accepted as delegates
                {
                    r = isExpression.TypeSpecializationToken == DTokens.Delegate &&
                        typeToCheck is MemberSymbol &&
                        ((DSymbol)typeToCheck).Definition is DMethod;

                    //TODO: Alias handling, same as couple of lines above
                }
                break;

            case DTokens.Super:                     //TODO: Test this
                var dc = DResolver.SearchClassLikeAt(ctxt.ScopedBlock, isExpression.Location) as DClassLike;

                if (dc != null)
                {
                    var udt = DResolver.ResolveBaseClasses(new ClassType(dc, dc, null), ctxt, true) as ClassType;

                    if (r = udt.Base != null && ResultComparer.IsEqual(typeToCheck, udt.Base))
                    {
                        var l = new List <AbstractType>();
                        if (udt.Base != null)
                        {
                            l.Add(udt.Base);
                        }
                        if (udt.BaseInterfaces != null && udt.BaseInterfaces.Length != 0)
                        {
                            l.AddRange(udt.BaseInterfaces);
                        }

                        res = new DTuple(isExpression, l);
                    }
                }
                break;

            case DTokens.Const:
            case DTokens.Immutable:
            case DTokens.InOut:                     // TODO?
            case DTokens.Shared:
                if (r = typeToCheck.Modifier == isExpression.TypeSpecializationToken)
                {
                    res = typeToCheck;
                }
                break;

            case DTokens.Return:                     // TODO: Test
                IStatement _u = null;
                var        dm = DResolver.SearchBlockAt(ctxt.ScopedBlock, isExpression.Location, out _u) as DMethod;

                if (dm != null)
                {
                    var retType_ = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

                    if (r = retType_ != null && ResultComparer.IsEqual(typeToCheck, retType_))
                    {
                        res = retType_;
                    }
                }
                break;
            }

            return(new Tuple <bool, AbstractType>(r, res));
        }
        ISymbolValue EvalConcatenation(CatExpression x, ISymbolValue lValue)
        {
            // In the (not unusual) case that more than 2 arrays/strings shall be concat'ed - process them more efficiently
            var catQueue = new Queue <ISymbolValue>();

            var catEx = (x as CatExpression);

            catQueue.Enqueue(lValue);

            catEx = catEx.RightOperand as CatExpression;
            ISymbolValue r;

            while (catEx != null)
            {
                r = TryGetValue(E(catEx.LeftOperand));
                if (r == null)
                {
                    EvalError(catEx.LeftOperand, "Couldn't be evaluated.");
                    return(null);
                }
                catQueue.Enqueue(r);
                if (catEx.RightOperand is CatExpression)
                {
                    catEx = catEx.RightOperand as CatExpression;
                }
                else
                {
                    break;
                }
            }

            r = TryGetValue(E((catEx ?? x).RightOperand));
            if (r == null)
            {
                EvalError(catEx.LeftOperand, "Couldn't be evaluated.");
                return(null);
            }
            catQueue.Enqueue(r);

            // Notable: If one element is of the value type of the array, the element is added (either at the front or at the back) to the array
            // myString ~ 'a' will append an 'a' to the string
            // 'a' ~ myString inserts 'a' at index 0

            // Determine whether we have to build up a string OR a normal list of atomic elements
            bool      isString      = true;
            ArrayType lastArrayType = null;

            foreach (var e in catQueue)
            {
                if (e is AssociativeArrayValue)
                {
                    EvalError(x, "Can't concatenate associative arrays", e);
                    return(null);
                }
                else if (e is ArrayValue)
                {
                    if (lastArrayType != null && !ResultComparer.IsEqual(lastArrayType, e.RepresentedType))
                    {
                        EvalError(x, "Both arrays must be of same type", new[] { lastArrayType, e.RepresentedType });
                        return(null);
                    }
                    lastArrayType = e.RepresentedType as ArrayType;

                    if ((e as ArrayValue).IsString)
                    {
                        continue;
                    }
                }
                else if (e is PrimitiveValue)
                {
                    var btt = (e as PrimitiveValue).BaseTypeToken;
                    if (btt == DTokens.Char || btt == DTokens.Dchar || btt == DTokens.Wchar)
                    {
                        continue;
                    }
                }

                isString = false;
            }

            if (lastArrayType == null)
            {
                EvalError(x, "At least one operand must be an (non-associative) array. If so, the other operand must be of the array's element type.", catQueue.ToArray());
                return(null);
            }

            if (isString)
            {
                var sb = new StringBuilder();

                while (catQueue.Count != 0)
                {
                    var e = catQueue.Dequeue();
                    if (e is ArrayValue)
                    {
                        sb.Append((e as ArrayValue).StringValue);
                    }
                    else if (e is PrimitiveValue)
                    {
                        sb.Append((char)((e as PrimitiveValue).Value));
                    }
                }
                return(new ArrayValue(GetStringType(LiteralSubformat.Utf8), sb.ToString()));
            }


            var elements = new List <ISymbolValue>();

            while (catQueue.Count != 0)
            {
                var e = catQueue.Dequeue();

                var av = e as ArrayValue;
                if (av != null)
                {
                    if (av.IsString)
                    {
                        elements.Add(av);
                    }
                    else if (av.Elements != null)
                    {
                        elements.AddRange(av.Elements);
                    }
                    continue;
                }

                if (!ResultComparer.IsImplicitlyConvertible(e.RepresentedType, lastArrayType.ValueType, ctxt))
                {
                    EvalError(x, "Element with type " + e.RepresentedType.ToCode() + " doesn't fit into array with type " + lastArrayType.ToCode(), catQueue.ToArray());
                    return(null);
                }

                elements.Add(e);
            }

            return(new ArrayValue(lastArrayType, elements.ToArray()));
        }
Пример #30
0
        public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol)
        {
            DSymbol ds = null;

            mightBeLegalUnresolvableSymbol = false;

            if (string.IsNullOrWhiteSpace(symName))
            {
                return(null);
            }

            // Try to handle a probably mangled string or C function.
            if (symName.StartsWith("_"))
            {
                try{
                    ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol;
                }catch {}
            }

            // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])
            if (ds == null && Lexer.IsIdentifierPart((int)symName[0]))
            {
                mightBeLegalUnresolvableSymbol = true;
                ITypeDeclaration q;
                var method = DParser.ParseMethodDeclarationHeader(symName, out q);
                q           = Demangler.RemoveNestedTemplateRefsFromQualifier(q);
                method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type);
                var methodType       = TypeDeclarationResolver.GetMethodReturnType(method, ctxt);
                var methodParameters = new List <AbstractType>();

                if (method.Parameters != null && method.Parameters.Count != 0)
                {
                    foreach (var parm in method.Parameters)
                    {
                        methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt));
                    }
                }

                ctxt.ContextIndependentOptions |= ResolutionOptions.IgnoreAllProtectionAttributes;
                var overloads = TypeDeclarationResolver.Resolve(q, ctxt);


                if (overloads == null || overloads.Length == 0)
                {
                    return(null);
                }
                else if (overloads.Length == 1)
                {
                    ds = overloads[0] as DSymbol;
                }
                else
                {
                    foreach (var o in overloads)
                    {
                        ds = o as DSymbol;
                        if (ds == null || !(ds.Definition is DMethod))
                        {
                            continue;
                        }

                        var dm = ds.Definition as DMethod;
                        // Compare return types
                        if (dm.Type != null)
                        {
                            if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base))
                            {
                                continue;
                            }
                        }
                        else if (dm.Type == null && methodType != null)
                        {
                            return(null);
                        }

                        // Compare parameters
                        if (methodParameters.Count != dm.Parameters.Count)
                        {
                            continue;
                        }

                        for (int i = 0; i < methodParameters.Count; i++)
                        {
                            if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt)))
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            if (ds != null)
            {
                return(ds.Definition);
            }
            return(null);
        }