Beispiel #1
0
 public static async Task <IBifoqlObject> Eval(Location location, QueryContext context, IBifoqlExpression expr)
 {
     return(await expr.Evaluate(context));
 }
Beispiel #2
0
        public static async Task <IBifoqlObject> ToMap(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyExpr, IBifoqlExpression valueExpr)
        {
            var dict = new Dictionary <string, IBifoqlObject>();

            foreach (var item in list)
            {
                var target = await item();

                var currContext = context.ReplaceTarget(target);
                var key         = await keyExpr.Evaluate(currContext) as IBifoqlString;

                if (key == null)
                {
                    return(new AsyncError(location, "Result of to_map's key expression must be a string"));
                }

                var value = await valueExpr.Evaluate(currContext);

                dict.Add(await key.Value, value);
            }

            return(dict.ToBifoqlMap());
        }
Beispiel #3
0
        private static async Task <IBifoqlObject> MaxMin(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyQuery, bool max)
        {
            var pairs = new List <KeyValuePair <IBifoqlObject, IBifoqlObject> >();

            foreach (var value in list)
            {
                var val = await value();

                var newContext = context.ReplaceTarget(val);

                var key = keyQuery == null ? val : await keyQuery.Evaluate(newContext);

                pairs.Add(new KeyValuePair <IBifoqlObject, IBifoqlObject>(key, val));
            }

            var           resultNum = max ? double.MinValue : double.MaxValue;
            string        resultStr = null;
            bool          first     = true;
            bool          isNum     = false;
            IBifoqlObject result    = null;

            foreach (var val in pairs)
            {
                var curr = val.Key;
                if (first)
                {
                    first = false;
                    isNum = curr is IBifoqlNumber;
                }

                if (isNum)
                {
                    var currNumObj = curr as IBifoqlNumber;
                    if (currNumObj == null)
                    {
                        return(new AsyncError(location, "To take max, all members of the list must be a number or string"));
                    }
                    var currNum = await currNumObj.Value;

                    if ((max && currNum > resultNum) || (!max && currNum < resultNum))
                    {
                        resultNum = currNum;
                        result    = val.Value;
                    }
                }
                else
                {
                    var currStrObj = curr as IBifoqlString;
                    if (currStrObj == null)
                    {
                        return(new AsyncError(location, "To take max, all members of the list must be a number or string"));
                    }
                    var currStr = await currStrObj.Value;

                    if (resultStr == null || currStr.CompareTo(resultStr) == (max ? 1 : -1))
                    {
                        resultStr = currStr;
                        result    = val.Value;
                    }
                }
            }

            return(result);
        }
Beispiel #4
0
        public static async Task <IBifoqlObject> SortBy(Location location, QueryContext context, IBifoqlArrayInternal array, IBifoqlExpression keyExpr)
        {
            var pairs  = new List <Tuple <IBifoqlObject, IBifoqlObject> >();
            var values = new List <IBifoqlObject>();

            foreach (var obj in array)
            {
                var currObj = await obj();

                var keyObj = keyExpr == null
                    ? currObj
                    : await keyExpr.Evaluate(context.ReplaceTarget(currObj));

                pairs.Add(Tuple.Create(keyObj, currObj));
            }

            if (pairs.All(p => p.Item1 is IBifoqlString))
            {
                var pairsByString = new List <Tuple <string, IBifoqlObject> >();
                foreach (var item in pairs)
                {
                    pairsByString.Add(Tuple.Create(await((IBifoqlString)item.Item1).Value, item.Item2));
                }
                return(pairsByString.OrderBy(p => p.Item1).Select(p => p.Item2).ToList().ToBifoqlObject());
            }
            else if (pairs.All(p => p.Item1 is IBifoqlNumber))
            {
                var pairsByNumber = new List <Tuple <double, IBifoqlObject> >();
                foreach (var item in pairs)
                {
                    pairsByNumber.Add(Tuple.Create(await((IBifoqlNumber)item.Item1).Value, item.Item2));
                }
                return(pairsByNumber.OrderBy(p => p.Item1).Select(p => p.Item2).ToList().ToBifoqlObject());
            }
            else
            {
                return(new AsyncError("sort must be sorted either by number or string"));
            }
        }
Beispiel #5
0
 public static Task <IBifoqlObject> MinBy(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyExpr)
 {
     return(MaxMin(location, context, list, keyExpr, max: false));
 }