private static void PrintColumn(Value column, StringBuilder formatter) { string s = null; Expr.AsExpr(column).Print(ref s); formatter.Append(s); }
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); }
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)); }
/// <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)); }