Example #1
0
        private static void PrintColumn(Value column, StringBuilder formatter)
        {
            string s = null;

            Expr.AsExpr(column).Print(ref s);
            formatter.Append(s);
        }
Example #2
0
        public Value Resolve(int index, ValueTypeEnum context = ValueTypeEnum.Void, bool isRequired = false)
        {
            if (index >= Size)
            {
                throw new CalcError(CalcError.ErrorMessageTooFewArgumentsToFunction);
            }

            Value value = ArgsList[index];

            if (value.Type == ValueTypeEnum.Any)
            {
                ContextScope scope = new ContextScope(this, context, isRequired);
                value = Expr.AsExpr(value).Calc(scope, Locus, Depth);
                if (isRequired && value.Type != context)
                {
                    throw new CalcError(String.Format(CalcError.ErrorMessageExpectedSmthForArgumentSmthButReceivedSmth, context, index, value));
                }

                // DM - update the original value (Args) with expression result. Note the difference between Sequence (List inside) and a regular value
                if (Args.Type == ValueTypeEnum.Sequence)
                {
                    Args.AsSequence[index] = value;
                }
                else
                {
                    Args = value;
                }
            }
            return(value);
        }
Example #3
0
        public PricePoint?FindPriceFromExpr(Expr expr, Commodity commodity, DateTime moment)
        {
            Logger.Current.Debug("commodity.price.find", () => String.Format("valuation expr: {0}", expr.Dump()));

            Value result = expr.Calc(Scope.DefaultScope);

            if (Expr.IsExpr(result))
            {
                Value callArgs = new Value();

                callArgs.PushBack(Value.Get(BaseSymbol));
                callArgs.PushBack(Value.Get(moment));
                if (commodity != null)
                {
                    callArgs.PushBack(Value.Get(commodity.Symbol));
                }

                result = Expr.AsExpr(result).Call(callArgs, Scope.DefaultScope);
            }

            return(new PricePoint(moment, result.AsAmount));
        }
Example #4
0
        /// <summary>
        /// Ported from value_t select_command(call_scope_t& args)
        /// </summary>
        public static Value SelectCommand(CallScope args)
        {
            string text = "select " + CallScope.JoinArgs(args);

            if (String.IsNullOrEmpty(text))
            {
                throw new LogicError(LogicError.ErrorMessageUsageSelectText);
            }

            Report report = args.FindScope <Report>();

            // Our first step is to divide the select statement into its principal
            // parts:
            //
            //   SELECT <VALEXPR-LIST>
            //   FROM <NAME>
            //   WHERE <VALEXPR>
            //   DISPLAY <VALEXPR>
            //   COLLECT <VALEXPR>
            //   GROUP BY <VALEXPR>
            //   STYLE <NAME>

            Mask selectRe = new Mask(SelectRe);

            Mask fromAccountsRe = new Mask(FromAccountsRe);
            bool accountsReport = fromAccountsRe.Match(text);

            ExprOp        reportFunctor = null;
            StringBuilder formatter     = new StringBuilder();

            foreach (var match in selectRe.Matches(text))
            {
                string keyword = match.Groups[1].Value;
                string arg     = match.Groups[2].Value;

                Logger.Current.Debug("select.parse", () => String.Format("keyword: {0}", keyword));
                Logger.Current.Debug("select.parse", () => String.Format("arg: {0}", arg));

                if (keyword == "select")
                {
                    Expr   argsExpr = new Expr(arg);
                    Value  columns  = ExprOp.SplitConsExpr(argsExpr.Op);
                    bool   first    = true;
                    string thusFar  = String.Empty;

                    int cols = 0;

                    if (report.ColumnsHandler.Handled)
                    {
                        cols = Int32.Parse(report.ColumnsHandler.Value);
                    }
                    else
                    {
                        string columnsEnv = VirtualEnvironment.GetEnvironmentVariable("COLUMNS");
                        if (!Int32.TryParse(columnsEnv, out cols))
                        {
                            cols = VirtualConsole.WindowWidth;
                            if (cols == 0)
                            {
                                cols = 80;
                            }
                        }
                    }

                    int dateWidth = report.DateWidthHandler.Handled ? Int32.Parse(report.DateWidthHandler.Str()) :
                                    Times.TimesCommon.Current.FormatDate(Times.TimesCommon.Current.CurrentDate, Times.FormatTypeEnum.FMT_PRINTED).Length;
                    int payeeWidth = report.PayeeWidthHandler.Handled ? Int32.Parse(report.PayeeWidthHandler.Str()) :
                                     (int)(((double)cols) * 0.263157);
                    int accountWidth = report.AccountWidthHandler.Handled ? Int32.Parse(report.AccountWidthHandler.Str()) :
                                       (int)(((double)cols) * 0.302631);
                    int amountWidth = report.AmountWidthHandler.Handled ? Int32.Parse(report.AmountWidthHandler.Str()) :
                                      (int)(((double)cols) * 0.157894);
                    int totalWidth = report.TotalWidthHandler.Handled ? Int32.Parse(report.TotalWidthHandler.Str()) :
                                     amountWidth;
                    int metaWidth = report.MetaWidthHandler.Handled ? Int32.Parse(report.MetaWidthHandler.Str()) :
                                    10;

                    bool sawPayee   = false;
                    bool sawAccount = false;

                    int colsNeeded = 0;
                    foreach (Value column in columns.AsSequence)
                    {
                        string ident = null;
                        if (GetPrincipalIdentifiers(Expr.AsExpr(column), ref ident))
                        {
                            if (ident == "date" || ident == "aux_date")
                            {
                                colsNeeded += dateWidth + 1;
                            }
                            else if (ident == "payee")
                            {
                                colsNeeded += payeeWidth + 1;
                                sawPayee    = true;
                            }
                            else if (ident == "account")
                            {
                                colsNeeded += accountWidth + 1;
                                sawAccount  = true;
                            }
                            else if (ident == "amount")
                            {
                                colsNeeded += amountWidth + 1;
                            }
                            else if (ident == "total")
                            {
                                colsNeeded += totalWidth + 1;
                            }
                            else
                            {
                                colsNeeded += metaWidth + 1;
                            }
                        }
                    }

                    while ((sawAccount || sawPayee) && colsNeeded < cols)
                    {
                        if (sawAccount && colsNeeded < cols)
                        {
                            ++accountWidth;
                            ++colsNeeded;
                            if (colsNeeded < cols)
                            {
                                ++accountWidth;
                                ++colsNeeded;
                            }
                        }
                        if (sawPayee && colsNeeded < cols)
                        {
                            ++payeeWidth;
                            ++colsNeeded;
                        }
                    }

                    while ((sawAccount || sawPayee) && colsNeeded > cols &&
                           accountWidth > 5 && payeeWidth > 5)
                    {
                        Logger.Current.Debug("auto.columns", () => "adjusting account down");
                        if (sawAccount && colsNeeded > cols)
                        {
                            --accountWidth;
                            --colsNeeded;
                            if (colsNeeded > cols)
                            {
                                --accountWidth;
                                --colsNeeded;
                            }
                        }
                        if (sawPayee && colsNeeded > cols)
                        {
                            --payeeWidth;
                            --colsNeeded;
                        }
                        Logger.Current.Debug("auto.columns", () => String.Format("account_width now = {0}", accountWidth));
                    }

                    if (!report.DateWidthHandler.Handled)
                    {
                        report.DateWidthHandler.Value = dateWidth.ToString();
                    }
                    if (!report.PayeeWidthHandler.Handled)
                    {
                        report.PayeeWidthHandler.Value = payeeWidth.ToString();
                    }
                    if (!report.AccountWidthHandler.Handled)
                    {
                        report.AccountWidthHandler.Value = accountWidth.ToString();
                    }
                    if (!report.AmountWidthHandler.Handled)
                    {
                        report.AmountWidthHandler.Value = amountWidth.ToString();
                    }
                    if (!report.TotalWidthHandler.Handled)
                    {
                        report.TotalWidthHandler.Value = totalWidth.ToString();
                    }

                    foreach (Value column in columns.AsSequence)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            formatter.Append(" ");
                        }

                        formatter.Append("%(");

                        string ident = null;
                        if (GetPrincipalIdentifiers(Expr.AsExpr(column), ref ident, true))
                        {
                            if (ident == "date" || ident == "aux_date")
                            {
                                formatter.Append("ansify_if(");
                                formatter.Append("ansify_if(justify(format_date(");

                                PrintColumn(column, formatter);

                                formatter.Append("), int(date_width)),");
                                formatter.Append("green if color and date > today),");
                                formatter.Append("bold if should_bold)");

                                if (!String.IsNullOrEmpty(thusFar))
                                {
                                    thusFar += " + ";
                                }
                                thusFar += "int(date_width) + 1";
                            }
                            else if (ident == "payee")
                            {
                                formatter.Append("ansify_if(");
                                formatter.Append("ansify_if(justify(truncated(");

                                PrintColumn(column, formatter);

                                formatter.Append(", int(payee_width)), int(payee_width)),");
                                formatter.Append("bold if color and !cleared and actual),");
                                formatter.Append("bold if should_bold)");

                                if (!String.IsNullOrEmpty(thusFar))
                                {
                                    thusFar += " + ";
                                }
                                thusFar += "int(payee_width) + 1";
                            }
                            else if (ident == "account")
                            {
                                formatter.Append("ansify_if(");

                                if (accountsReport)
                                {
                                    formatter.Append("ansify_if(");
                                    formatter.Append("partial_account(options.flat), blue if color),");
                                }
                                else
                                {
                                    formatter.Append("justify(truncated(");
                                    PrintColumn(column, formatter);
                                    formatter.Append(", int(account_width), int(abbrev_len)),");
                                    formatter.Append("int(account_width), -1, ");
                                    formatter.Append("false, color),");

                                    if (!String.IsNullOrEmpty(thusFar))
                                    {
                                        thusFar += " + ";
                                    }
                                    thusFar += "int(account_width) + 1";
                                }

                                formatter.Append(" bold if should_bold)");
                            }
                            else if (ident == "amount" || ident == "total")
                            {
                                formatter.Append("ansify_if(");
                                formatter.Append("justify(scrub(");

                                PrintColumn(column, formatter);

                                formatter.Append("), ");

                                if (ident == "amount")
                                {
                                    formatter.Append("int(amount_width),");
                                }
                                else
                                {
                                    formatter.Append("int(total_width),");
                                }

                                if (!String.IsNullOrEmpty(thusFar))
                                {
                                    thusFar += " + ";
                                }

                                if (ident == "amount")
                                {
                                    thusFar += "int(amount_width)";
                                }
                                else
                                {
                                    thusFar += "int(total_width)";
                                }

                                if (String.IsNullOrEmpty(thusFar))
                                {
                                    formatter.Append("-1");
                                }
                                else
                                {
                                    formatter.Append(thusFar);
                                }

                                formatter.Append(", true, color),");
                                formatter.Append(" bold if should_bold)");

                                thusFar += " + 1";
                            }
                            else
                            {
                                formatter.Append("ansify_if(");
                                formatter.Append("justify(truncated(");

                                PrintColumn(column, formatter);

                                formatter.Append(", int(meta_width or 10)), int(meta_width) or 10),");
                                formatter.Append("bold if should_bold)");

                                if (!String.IsNullOrEmpty(thusFar))
                                {
                                    thusFar += " + ";
                                }
                                thusFar += "(int(meta_width) or 10) + 1";
                            }
                        }
                        formatter.Append(")");
                    }
                    formatter.AppendLine();
                    Logger.Current.Debug("select.parse", () => String.Format("formatter: {0}", formatter.ToString()));
                }
                else if (keyword == "from")
                {
                    if (arg == "xacts" || arg == "txns" || arg == "transactions")
                    {
                        var reporter = new Reporter <Post, PostHandler>(new PrintXacts(report, report.RawHandler.Handled), report, "#select", report.PostsReport);
                        reportFunctor = ExprOp.WrapFunctor(scope => reporter.Handle((CallScope)scope));
                    }
                    else if (arg == "posts" || arg == "postings")
                    {
                        var reporter = new Reporter <Post, PostHandler>(new FormatPosts(report, formatter.ToString()), report, "#select", report.PostsReport);
                        reportFunctor = ExprOp.WrapFunctor(scope => reporter.Handle((CallScope)scope));
                    }
                    else if (arg == "accounts")
                    {
                        var reporter = new Reporter <Account, AccountHandler>(new FormatAccounts(report, formatter.ToString()), report, "#select", report.AccountsReport);
                        reportFunctor = ExprOp.WrapFunctor(scope => reporter.Handle((CallScope)scope));
                    }
                    else if (arg == "commodities")
                    {
                        var reporter = new Reporter <Post, PostHandler>(new FormatPosts(report, formatter.ToString()), report, "#select", report.CommoditiesReport);
                        reportFunctor = ExprOp.WrapFunctor(scope => reporter.Handle((CallScope)scope));
                    }
                }
                else if (keyword == "where")
                {
                    report.LimitHandler.On("#select", arg);
                }
                else if (keyword == "display")
                {
                    report.DisplayHandler.On("#select", arg);
                }
                else if (keyword == "collect")
                {
                    report.AmountHandler.On("#select", arg);
                }
                else if (keyword == "group by")
                {
                    report.GroupByHandler.On("#select", arg);
                }
                else if (keyword == "style")
                {
                    if (arg == "csv")
                    {
                    }
                    else if (arg == "xml")
                    {
                    }
                    else if (arg == "json")
                    {
                    }
                    else if (arg == "emacs")
                    {
                    }
                    else if (arg == "org")
                    {
                    }
                }
            }

            if (reportFunctor == null)
            {
                var reporter = new Reporter <Post, PostHandler>(new FormatPosts(report, formatter.ToString()), report, "#select", report.PostsReport);
                reportFunctor = ExprOp.WrapFunctor(scope => reporter.Handle((CallScope)scope));
            }

            CallScope callArgs = new CallScope(report);

            return(reportFunctor.AsFunction(callArgs));
        }