예제 #1
0
        public void Expr_Constructor_TakesExpressionsToCalculate()
        {
            Expr  expr   = new Expr("2+2");
            Value result = expr.Calc(new EmptyScope());

            Assert.AreEqual(4, result.AsLong);
        }
예제 #2
0
파일: Post.cs 프로젝트: maznabili/nledger
        public Value AddToValue(Value value, Expr expr = null)
        {
            if (HasXData && XData.Compound)
            {
                if (!Value.IsNullOrEmpty(XData.CompoundValue))
                {
                    value = Value.AddOrSetValue(value, XData.CompoundValue);
                }
            }
            else if (expr != null)
            {
                BindScope boundScope = new BindScope(expr.Context, this);
                Value     temp       = expr.Calc(boundScope);
                value = Value.AddOrSetValue(value, temp);
            }
            else if (HasXData && XData.Visited && !Value.IsNullOrEmpty(XData.VisitedValue))
            {
                value = Value.AddOrSetValue(value, XData.VisitedValue);
            }
            else
            {
                value = Value.AddOrSetValue(value, Value.Get(Amount));
            }

            return(value);
        }
예제 #3
0
        /// <summary>
        /// Ported from void transfer_details::operator()(post_t& post)
        /// </summary>
        public override void Handle(Post post)
        {
            Xact xact = Temps.CopyXact(post.Xact);

            xact.Date = post.GetDate();

            Post temp = Temps.CopyPost(post, xact);

            temp.State = post.State;

            BindScope boundScope = new BindScope(Scope, temp);
            Value     substitute = Expr.Calc(boundScope);

            if (!Value.IsNullOrEmpty(substitute))
            {
                switch (WhichElement)
                {
                case TransferDetailsElementEnum.SET_DATE:
                    temp.Date = substitute.AsDate;
                    break;

                case TransferDetailsElementEnum.SET_ACCOUNT:
                {
                    string accountName = substitute.AsString;
                    if (!String.IsNullOrEmpty(accountName) && !accountName.EndsWith(":"))
                    {
                        Account prevAccount = temp.Account;
                        temp.Account.RemovePost(temp);

                        accountName += ":" + prevAccount.FullName;

                        string[] accountNames = accountName.Split(':');
                        temp.Account = FiltersCommon.CreateTempAccountFromPath(accountNames, Temps, xact.Journal.Master);
                        temp.Account.AddPost(temp);

                        temp.Account.SetFlags(prevAccount);
                        if (prevAccount.HasXData)
                        {
                            temp.Account.XData.SetFlags(prevAccount.XData);
                        }
                    }
                    break;
                }

                case TransferDetailsElementEnum.SET_PAYEE:
                    xact.Payee = substitute.AsString;
                    break;
                }
            }

            base.Handle(temp);
        }
예제 #4
0
파일: PreCmd.cs 프로젝트: taiab/nledger
        // eval_command
        public static Value EvalCommand(CallScope args)
        {
            Report report = args.FindScope <Report>();
            Expr   expr   = new Expr(CallScope.JoinArgs(args));
            Value  result = expr.Calc(args).StripAnnotations(report.WhatToKeep());

            if (!Value.IsNullOrEmpty(result))
            {
                report.OutputStream.WriteLine(result.Print());
            }

            return(Value.Empty);
        }
예제 #5
0
파일: Post.cs 프로젝트: maznabili/nledger
        public Amount ResolveExpr(Scope scope, Expr expr)
        {
            BindScope boundScope = new BindScope(scope, this);
            Value     result     = expr.Calc(boundScope);

            if (result.Type == ValueTypeEnum.Integer)
            {
                return(result.AsAmount);
            }
            else
            {
                if (result.Type != ValueTypeEnum.Amount)
                {
                    throw new AmountError(AmountError.ErrorMessageAmountExpressionsMustResultInASimpleAmount);
                }
                return(result.AsAmount);
            }
        }
예제 #6
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));
        }
예제 #7
0
파일: PreCmd.cs 프로젝트: taiab/nledger
        // parse_command
        public static Value ParseCommand(CallScope args)
        {
            string arg = CallScope.JoinArgs(args);

            if (String.IsNullOrEmpty(arg))
            {
                throw new LogicError(LogicError.ErrorMessageUsageParseText);
            }

            Report        report = args.FindScope <Report>();
            StringBuilder sb     = new StringBuilder();

            Post post = GetSampleXact(report);

            sb.AppendLine("--- Input expression ---");
            sb.AppendLine(arg);

            sb.AppendLine("--- Text as parsed ---");
            Expr expr = new Expr(arg);

            sb.AppendLine(expr.Print());

            sb.AppendLine("--- Expression tree ---");
            sb.Append(expr.Dump());

            BindScope boundScope = new BindScope(args, post);

            expr.Compile(boundScope);
            sb.AppendLine("--- Compiled tree ---");
            sb.Append(expr.Dump());

            sb.AppendLine("--- Calculated value ---");
            Value result = expr.Calc();

            sb.AppendLine(result.StripAnnotations(report.WhatToKeep()).Dump());

            report.OutputStream.Write(sb.ToString());
            return(Value.Empty);
        }
예제 #8
0
파일: Format.cs 프로젝트: vyolbius/nledger
        protected override string RealCalc(Scope scope)
        {
            StringBuilder outStr = new StringBuilder();

            for (FormatElement elem = Elements; elem != null; elem = elem.Next)
            {
                string s;

                switch (elem.Type)
                {
                case FormatElementEnum.STRING:
                    string stringFormat = StringExtensions.GetWidthAlignFormatString(elem.MinWidth, !elem.IsElementAlignLeft);
                    s = String.Format(stringFormat, elem.Data.GetValue <string>());
                    break;

                case FormatElementEnum.EXPR:
                    Expr expr = new Expr(elem.Data.GetValue <Expr>());
                    try
                    {
                        expr.Compile(scope);

                        Value value;
                        if (expr.IsFunction)
                        {
                            CallScope args = new CallScope(scope);
                            args.PushBack(Value.Get(elem.MaxWidth));
                            value = expr.GetFunction()(args);
                        }
                        else
                        {
                            value = expr.Calc(scope);
                        }
                        Logger.Current.Debug("format.expr", () => String.Format("value = ({0})", value));

                        if (elem.MinWidth > 0)
                        {
                            s = value.Print(elem.MinWidth, -1, elem.IsElementAlignLeft ? AmountPrintEnum.AMOUNT_PRINT_NO_FLAGS : AmountPrintEnum.AMOUNT_PRINT_RIGHT_JUSTIFY);
                        }
                        else
                        {
                            s = value.ToString();
                        }
                    }
                    catch
                    {
                        string currentContext = ErrorContext.Current.GetContext();

                        ErrorContext.Current.AddErrorContext("While calculating format expression:");
                        ErrorContext.Current.AddErrorContext(expr.ContextToStr());

                        if (!String.IsNullOrEmpty(currentContext))
                        {
                            ErrorContext.Current.AddErrorContext(currentContext);
                        }

                        throw;
                    }
                    break;

                default:
                    throw new InvalidOperationException("Unknown enum item");
                }

                if (elem.MaxWidth > 0 || elem.MinWidth > 0)
                {
                    string result;

                    if (elem.MaxWidth > 0 && elem.MaxWidth < s.Length)
                    {
                        result = Truncate(s, elem.MaxWidth);
                    }
                    else
                    {
                        result = s;
                        if (elem.MinWidth > s.Length)
                        {
                            result = result + new String(' ', s.Length - elem.MinWidth);
                        }
                    }

                    outStr.Append(result);
                }
                else
                {
                    outStr.Append(s);
                }
            }

            return(outStr.ToString());
        }