예제 #1
0
파일: OPs.cs 프로젝트: WVitek/DotGlue
        public static object GetConstant(this Generator.Ctx ctx, string valueName)
        {
            int i   = ctx.IndexOf(valueName);
            var val = (i < 0) ? null : ctx[i];

            if (val == null)
            {
                return(null);
            }
            var expr = val as Expr;

            if (expr != null)
            {
                val = Generator.Generate(expr, ctx);
            }
            if (OPs.KindOf(val) == ValueKind.Const)
            {
                return(val);
            }
            else if (expr != null)
            {
                return(ctx.Error(string.Format("Constant expected as value of '{0}' // {1}", valueName, expr)));
            }
            else
            {
                return(ctx.Error(string.Format("Constant expected as value of '{0}'", valueName)));
            }
        }
예제 #2
0
        public static object SolverWeightedSumsFactory(IList args)
        {
            var periodInDays = Convert.ToDouble(args[0]);
            var startTime    = OPs.FromExcelDate(Convert.ToDouble(args[1]));
            var endTime      = OPs.FromExcelDate(Convert.ToDouble(args[2]));

            return(new WeightedSums.Factory(startTime, endTime, TimeSpan.FromDays(periodInDays)));
        }
예제 #3
0
 public static object DAY(object date)
 {
     if (W.Common.Utils.IsEmpty(date))
     {
         return(DBNull.Value);
     }
     return(OPs.FromExcelDate(OPs.xl2dbl(date)).Day);
 }
예제 #4
0
        public static object MOD(object _x, object _y)
        {
            var x = OPs.xl2dbl(_x);
            var y = OPs.xl2dbl(_y);
            var d = Math.Truncate(x / y);

            return(x - d * y);
        }
예제 #5
0
        public static object UseSqlAsFuncsFrom(CallExpr ce, Generator.Ctx ctx)
        {
            var arg0 = Generator.Generate(ce.args[0], ctx);

            if (OPs.KindOf(arg0) != ValueKind.Const)
            {
                ctx.Error("Constant value expected");
            }

            var arg1 = (ce.args.Count < 2) ? null : Generator.Generate(ce.args[1], ctx);

            var        sqlFileName = Convert.ToString(arg0);
            DbFuncType forKinds;

            if (arg1 == null)
            {
                forKinds = DbFuncType.TimeSlice | DbFuncType.TimeInterval;
            }
            else
            {
                var lst = arg1 as IList ?? new object[] { arg1 };
                forKinds = DbFuncType.None;
                foreach (var v in lst)
                {
                    forKinds |= (DbFuncType)Enum.Parse(typeof(DbFuncType), Convert.ToString(v));
                }
            }

            var dbConnName = (ce.args.Count < 3) ? DefaultDbConnName : OPs.TryAsName(ce.args[2], ctx);

            if (string.IsNullOrEmpty(dbConnName))
            {
                ctx.Error($"Connection name must be nonempty: {ce.args[2]}");
            }

            var fullFileName = Path.IsPathRooted(sqlFileName)
                ? sqlFileName
                : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Convert.ToString(sqlFileName));

            var           cacheKey = $"FuncDefs:{fullFileName}:{forKinds.ToString()}";
            Func <object> ldfsFunc = () =>
            {
                var sqlCtx = new W.Expressions.Sql.Preprocessing.PreprocessingContext()
                {
                    sqlFileName                 = fullFileName,
                    cacheSubdomain              = "DB",
                    dbConnValueName             = dbConnName,
                    forKinds                    = forKinds,
                    ctx                         = ctx,
                    cachingExpiration           = TimeSpan.FromMinutes(5),
                    defaultLocationForValueInfo = (ce.args.Count < 4) ? null : OPs.TryAsString(ce.args[3], ctx)
                };
                return(sqlCtx.LoadingFuncs());
            };
            var lfds = (IEnumerable <FuncDef>)FuncDefs_Core._Cached(cacheKey, ldfsFunc, DateTimeOffset.MaxValue, TimeSpan.FromMinutes(5));

            return(lfds);
        }
예제 #6
0
            public Task <object> Aggregate(AsyncExprCtx parent, IList data)
            {
                int i    = aggCtx.name2ndx[sData];
                var vals = new object[aggCtx.values.Count];

                aggCtx.values.CopyTo(vals, 0);
                vals[i] = data;
                var aec = new AsyncExprCtx(aggCtx, vals, parent);

                return(OPs.ConstValueOf(aec, aggCode));
            }
예제 #7
0
        public static object TIMEVALUE(object arg)
        {
            DateTime dt;

            if (!TryCastAsDateTime(arg, out dt))
            {
                return(new ArgumentException("TIMEVALUE"));
            }
            double v = OPs.ToExcelDate(dt);

            return(v - Math.Truncate(v));
        }
예제 #8
0
파일: OPs.cs 프로젝트: WVitek/DotGlue
        public static object GetConstant(this Generator.Ctx ctx, Expr expr)
        {
            var val = Generator.Generate(expr, ctx);

            if (OPs.KindOf(val) == ValueKind.Const)
            {
                return(val);
            }
            else
            {
                return(ctx.Error("Constant expected as value of " + expr.ToString()));
            }
        }
예제 #9
0
파일: Generator.cs 프로젝트: WVitek/DotGlue
 public IEnumerable <FuncDef> GetFunc(string name, int arity)
 {
     if (name == null)
     {
         var ctx = this;
         while (ctx != null)
         {
             foreach (var v in ctx.values)
             {
                 var fd = v as FuncDef;
                 if (fd != null)
                 {
                     yield return(fd);
                 }
             }
             ctx = ctx.parent;
         }
     }
     else
     {
         int i = IndexOf(name);
         if (i >= 0)
         {
             var v = this[i];
             if (v is FuncDef)
             {
                 var def = (FuncDef)v;
                 if (def.minArity <= arity && arity <= def.maxArity)
                 {
                     yield return(def);
                 }
             }
             else if (v is LazyAsync)
             {
                 AsyncFn f =
                     (ae, args) =>
                 {
                     return(OPs._call_func(ae, i, args));
                 };
                 yield return(new FuncDef(f, 0, int.MaxValue, name));
             }
         }
     }
     for (int i = externalFuncs.Count - 1; i >= 0; i--)
     {
         foreach (var fd in externalFuncs[i](name, arity))
         {
             yield return(fd);
         }
     }
 }
예제 #10
0
        public static object MAX(IList args)
        {
            double max = double.MinValue;

            foreach (object v in OPs.Flatten(args))
            {
                double?tmp = OPs.xl2dbl2(v);
                if (tmp.HasValue && tmp > max)
                {
                    max = tmp.Value;
                }
            }
            return(max);
        }
예제 #11
0
        public static object MIN(IList args)
        {
            double min = double.MaxValue;

            foreach (object v in OPs.Flatten(args))
            {
                double?tmp = OPs.xl2dbl2(v);
                if (tmp.HasValue && tmp < min)
                {
                    min = tmp.Value;
                }
            }
            return(min);
        }
예제 #12
0
파일: Generator.cs 프로젝트: WVitek/DotGlue
 public CtxValue(object valueToCalc, AsyncExprCtx context)
 {
     this.value = (LazyAsync) delegate(AsyncExprCtx ae)
     {
         if (ae != context)
         {
             return(OPs.ConstValueOf(context, valueToCalc));
         }
         else
         {
             return(OPs.ConstValueOf(ae, valueToCalc));
         }
     };
 }
예제 #13
0
        //[Arity(2, 3)]
        //public static object IF(CallExpr ce, Generator.Ctx ctx)
        //{ return FuncDefs_Core.IF(ce, ctx); }

        public static object SUM(IList args)
        {
            double sum = 0;

            foreach (object v in OPs.Flatten(args))
            {
                double?tmp = OPs.xl2dbl2(v);
                if (tmp.HasValue)
                {
                    sum += tmp.Value;
                }
            }
            return(sum);
        }
예제 #14
0
파일: OPs.cs 프로젝트: WVitek/DotGlue
        public static object GenFxyCall(FuncDef fd, object a, object b)
        {
            ValueKind kind = OPs.MaxKindOf(a, b);

            if (fd.resultCanBeLazy)
            {
                kind = ValueKind.Async;
            }
            else if (kind == ValueKind.Const && fd.isNotPure)
            {
                kind = ValueKind.Sync;
            }
            return(GenFxyCall((Fxy)fd.func, a, b, kind, fd.resultCanBeLazy));
        }
예제 #15
0
        public static object DATEVALUE(object arg)
        {
            if (arg == null)
            {
                return(null);
            }
            DateTime dt;

            if (!TryCastAsDateTime(arg, out dt))
            {
                return(new ArgumentException("DATEVALUE"));
            }

            return(OPs.ToExcelDate(dt.Date));
        }
예제 #16
0
 public static object Divide(object arg)
 {
     return(Utils.Calc(arg, 2, 1, data =>
     {
         var r = OPs.xl2dbl(data[0]) / OPs.xl2dbl(data[1]);
         if (double.IsNaN(r))
         {
             return null;
         }
         else
         {
             return OPs.WithTime(data[0], data[1], r);
         }
     }));
 }
예제 #17
0
파일: OPs.cs 프로젝트: WVitek/DotGlue
        public static string TryAsString(Expr expr, Generator.Ctx ctx)
        {
            var ce = expr as ConstExpr;

            if (ce != null)
            {
                return(Convert.ToString(ce.value));
            }
            var val = Generator.Generate(expr, ctx);

            if (OPs.KindOf(val) == ValueKind.Const && val != null)
            {
                return(Convert.ToString(val));
            }
            return(null);
        }
예제 #18
0
        public static object FindDependencies(CallExpr ce, Generator.Ctx ctx)
        {
            var arg0 = Generator.Generate(ce.args[0], ctx);

            if (OPs.KindOf(arg0) != ValueKind.Const || arg0 == null)
            {
                throw new SolverException("FindDependencies: list of source params must be constant and not null");
            }
            var arg1 = (ce.args.Count > 1) ? Generator.Generate(ce.args[1], ctx) : null;

            if (OPs.KindOf(arg1) != ValueKind.Const)
            {
                throw new SolverException("FindDependencies: optional list of dependent params must be constant");
            }
            var arg2 = (ce.args.Count > 2) ? Generator.Generate(ce.args[2], ctx) : null;

            if (OPs.KindOf(arg2) != ValueKind.Const)
            {
                throw new SolverException("FindDependencies: optional list of unusable params must be constant");
            }
            var srcPrms   = ((IList)arg0).Cast <object>().Select(o => o.ToString()).ToArray();
            var depPrms   = (arg1 == null) ? null : ((IList)arg1).Cast <object>().Select(o => o.ToString()).ToArray();
            var unusables = (arg2 == null)
                ? new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                : ((IList)arg2).Cast <object>().Select(o => o.ToString()).ToDictionary(s => s, StringComparer.OrdinalIgnoreCase);
            var aliasOf      = GetAliases(ctx);
            var funcs        = Dependecies.GetFuncInfos(ctx.GetFunc(null, 0), aliasOf, fi => !fi.inputs.Any(inp => unusables.ContainsKey(inp)));
            var dependencies = Dependecies.Find(funcs, aliasOf, int.MaxValue, srcPrms, depPrms);
            var resDict      = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);
            var resParams    = (depPrms == null)
                ? dependencies.Keys.Except(srcPrms, StringComparer.OrdinalIgnoreCase)
                : depPrms.Where(s => dependencies.ContainsKey(s));
            var res = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);

            foreach (var prmName in resParams)
            {
                var deps = dependencies[prmName];
                var srcs = srcPrms.Where(s => deps.ContainsKey(s)).ToArray();
                if (srcs.Length > 0)
                {
                    res.Add(prmName, srcs);
                }
            }
            return(res);
        }
예제 #19
0
        public static object letLookupFunc(CallExpr ce, Generator.Ctx ctx)
        {
            var    arg0 = ce.args[0];
            object name;
            var    ref0 = arg0 as ReferenceExpr;

            if (ref0 != null)
            {
                name = ref0.name;
            }
            else
            {
                name = Generator.Generate(arg0, ctx);
                if (OPs.KindOf(name) != ValueKind.Const)
                {
                    throw new SolverException("letLookupFunc(name, ...) : name must be constant");
                }
            }
            var keysDescriptorObjs = Generator.Generate(ce.args[1], ctx);
            var keysDescriptors    = keysDescriptorObjs as IList;

            if (OPs.KindOf(keysDescriptorObjs) != ValueKind.Const || keysDescriptors == null)
            {
                throw new SolverException("letLookupFunc(...,keysDescrs ...) : keysDescrs must be list of constants");
            }
            var valsDescriptorObjs = Generator.Generate(ce.args[2], ctx);
            var valsDescriptors    = valsDescriptorObjs as IList;

            if (OPs.KindOf(valsDescriptorObjs) != ValueKind.Const || valsDescriptors == null)
            {
                throw new SolverException("letLookupFunc(...,...,valuesDescrs ...) : valuesDescrs must be list of constants");
            }
            var body = ce.args[3];
            var func = (Macro)((expr, gctx) =>
                               Generator.Generate(body, gctx)
                               );
            var keys = keysDescriptors.Cast <object>().Select(Convert.ToString);
            var vals = valsDescriptors.Cast <object>().Select(Convert.ToString);
            var fd   = GetLookupFuncDef(Convert.ToString(name), keys, vals, func);

            return(Generator.Generate(CallExpr.let(ce.args[0], new ConstExpr(fd)), ctx));
        }
예제 #20
0
        public static async Task <object> ISERR(AsyncExprCtx ctx, IList args)
        {
            try
            {
                object value = await OPs.ConstValueOf(ctx, args[0]);

                var lst = value as IList;
                if (lst != null)
                {
                    var res = lst.ToArray(item => item is Exception || item is W.Common.ErrorWrapper);
                    return(res);
                }
                else
                {
                    return(value is Exception || value is W.Common.ErrorWrapper);
                }
            }
            catch (OperationCanceledException) { throw; }
            catch { return(True); }
        }
예제 #21
0
        public static object SolverTimedTabulation(IList args)
        {
            var items  = Utils.ToIList(args[0]) ?? new object[0];
            var timeA  = Convert.ToDouble(args[1]);
            var timeB  = Convert.ToDouble(args[2]);
            var nParts = Convert.ToInt32(args[3]);
            var what   = (args.Count > 4) ? Convert.ToString(args[4]) : null;
            var f      = new WeightedSums.Factory(OPs.FromExcelDate(timeA), OPs.FromExcelDate(timeB), nParts);
            var sums   = f.NewSums();

            sums.Add(items);
            var data = sums.Get(what ?? "AVGS");
            // prepare result array
            var res = new object[data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                res[i] = double.IsNaN(data[i]) ? null : (object)data[i];
            }
            return(res);
        }
예제 #22
0
파일: Generator.cs 프로젝트: WVitek/DotGlue
        public async Task <object> Get(AsyncExprCtx ae)
        {
            var s = sema;

            if (s != null)
            {
                if (s == errFlag)
                {
                    throw (Exception)value;
                }
                await s.WaitAsync(ae.Cancellation);

                try
                {
                    if (sema != null)
                    {   // enter here only once
                        if (sema == errFlag)
                        {
                            throw (Exception)value;
                        }
                        try
                        {
                            value = await OPs.VectorValueOf(ae, value);

                            sema = null;
                        }
                        catch (OperationCanceledException) { throw; }
                        catch (Exception ex)
                        {
                            value = ex;
                            var tmp = sema; sema = errFlag; //tmp.Dispose();
                            throw;
                        }
                    }
                }
                finally { s.Release(); }
            }
            return(value);
        }
예제 #23
0
        static object solverAliasImpl(CallExpr ce, Generator.Ctx ctx)
        {
            var alias = OPs.TryAsName(ce.args[0], ctx);

            if (alias == null)
            {
                throw new SolverException(string.Format(ce.funcName + "(alias ...): alias must be constant or name instead of [{0}]", ce.args[0]));
            }
            var target = (ce.args.Count > 1) ? OPs.TryAsName(ce.args[1], ctx) : string.Empty;

            if (target == null)
            {
                throw new SolverException(string.Format(ce.funcName + "(..., target ...): target must be constant or name instead of [{0}]", ce.args[0]));
            }
            int priority = (ce.args.Count > 2) ? Convert.ToInt32(ctx.GetConstant(ce.args[2])) : 255;
            int i        = ctx.GetOrCreateIndexOf(optionSolverAliases);
            var aliases  = ctx[i] as SolverAliases;

            if (aliases == null)
            {
                aliases = new SolverAliases();
                ctx[i]  = aliases;
            }
            switch (ce.funcName)
            {
            case nameof(solverAlias):
                return(aliases.Set(alias, target, priority));

            case nameof(solverAliasPush):
                return(aliases.Push(alias, target));

            case nameof(solverAliasPop):
                return(aliases.Pop(alias));

            default:
                throw new NotImplementedException(ce.funcName);
            }
        }
예제 #24
0
            public Task LoadData(AsyncExprCtx rootAec, Expr loadingExpr, CancellationToken ct)
            {
                int i = aggCtx.IndexOf(sFactory);

                if (i >= 0)
                {
                    var f = (WeightedSums.Factory)aggCtx[i];
                    foreach (var n2i in aggCtx.name2ndx)
                    {
                        if (n2i.Key.StartsWith(sAkk))
                        {
                            aggCtx[n2i.Value] = f.NewSums();
                        }
                    }
                }
                var loadingCtx = new Generator.Ctx(aggCtx.parent);

                loadingCtx.CreateValue(sUsedParamsDict, aggCtx[aggCtx.IndexOf(sUsedParamsDict)]);
                loadingCtx.CreateValue(sLoadingInfo, this);
                var loadingCode = Generator.Generate(loadingExpr, loadingCtx);
                var ae          = new AsyncExprCtx(loadingCtx, loadingCtx.values, rootAec);

                return(OPs.ConstValueOf(ae, loadingCode));
            }
예제 #25
0
 public static object LN(object x)
 {
     return(Math.Log(OPs.xl2dbl(x)));
 }
예제 #26
0
 public static object SQRT(object x)
 {
     return(Math.Sqrt(OPs.xl2dbl(x)));
 }
예제 #27
0
 public static object POWER(object x, object y)
 {
     return(Math.Pow(OPs.xl2dbl(x), OPs.xl2dbl(y)));
 }
예제 #28
0
        static IEnumerable <FuncDef> DefineProjectionFuncsImpl(CallExpr ce, Generator.Ctx ctx, bool acceptVector)
        {
            var inpParams      = ((IList)OPs.GetConstant(ctx, ce.args[0])).Cast <object>().Select(Convert.ToString).ToArray();
            var inpParamsParts = inpParams.Select(s => s.Split('_')).ToArray();
            var inpParamsMasks = inpParamsParts.Where(parts => parts.Any(string.IsNullOrEmpty)).ToArray();
            var outParams      = ((IList)OPs.GetConstant(ctx, ce.args[1])).Cast <object>().Select(Convert.ToString).ToArray();
            var outParamsMasks = outParams.Select(s => Convert.ToString(s).Split('_')).ToArray();

            var newFuncName = "@projfunc:" + ce.args[ce.args.Count - 1].ToString().Replace('(', '_').Replace(')', '_').Replace('"', '_').Replace('\'', '_');

            #region Collect suitable parameters from all functions outputs
            var suitableParams = new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase);

            foreach (var f in ctx.GetFunc(null, 0))
            {
                foreach (var prm in f.resultsInfo)
                {
                    var prmParts = prm.Parts();
                    for (int i = 0; i < inpParamsMasks.Length; i++)
                    {
                        var maskParts = inpParamsMasks[i];
                        var details   = GetDetailsIfMatched(prmParts, maskParts);
                        if (details == null)
                        {
                            continue;
                        }
                        if (!suitableParams.TryGetValue(details, out var suitables))
                        {
                            suitables = new string[inpParamsMasks.Length];
                            suitableParams.Add(details, suitables);
                        }
                        suitables[i] = details;
                    }
                }
            }
            #endregion

            #region Return FuncDef for each suitable params set
            foreach (var suitable in suitableParams.Where(prms => prms.Value.All(s => s != null)))
            {
                var details = suitable.Key;
                var inps    = new string[inpParamsParts.Length];
                for (int i = 0; i < inpParamsParts.Length; i++)
                {
                    var ip = inpParamsParts[i];
                    if (ip.Any(string.IsNullOrEmpty))
                    {   // one or more parts masked
                        inps[i] = ParamFromMaskAndDetails(details, ip);
                    }
                    else
                    {
                        inps[i] = inpParams[i];
                    }
                }

                var outs = new string[outParams.Length];
                for (int i = 0; i < outParamsMasks.Length; i++)
                {
                    outs[i] = ParamFromMaskAndDetails(details, outParamsMasks[i]);
                }

                yield return(FuncDefs_Core.macroFuncImpl(
                                 context: ctx,
                                 nameForNewFunc: new ConstExpr(newFuncName + details),
                                 inpsDescriptors: new ArrayExpr(inps.Select(ReferenceExpr.Create).Cast <Expr>().ToList()),
                                 outsDescriptors: new ArrayExpr(outs.Select(ReferenceExpr.Create).Cast <Expr>().ToList()),
                                 funcBody: ce.args[ce.args.Count - 1],
                                 inputParameterToSubstitute: (ce.args.Count > 3) ? ce.args[2] : null,
                                 funcAcceptVector: acceptVector
                                 ));
            }
            #endregion
        }
예제 #29
0
 public static object ROUND(object x, object nDigits)
 {
     return(Math.Round(OPs.xl2dbl(x), Convert.ToInt32(nDigits)));
 }
예제 #30
0
 public static object LOG(object x, object y)
 {
     return(Math.Log(OPs.xl2dbl(x), OPs.xl2dbl(y)));
 }