private EvaluationResult Evaluate(string name, string cell, IEnumerable <ExcelFormulaToken> tokens, ExpressionScope scope, ExpressionFormat format)
        {
            var result = new EvaluationResult()
            {
                Name = name,
                Cell = cell
            };

            try
            {
                var queue           = new Queue <ExcelFormulaToken>(tokens);
                var excelExpression = new ExcelExpression();
                TraverseExpression(excelExpression, queue, scope);
                var operand = excelExpression.Evaluate(scope);
                scope.Set(cell ?? name, operand.Value);
                result.Value = operand.Value.InnerValue;
                result.Text  = operand.Value?.ToString(outputLang, format);
            }
            catch (Exception ex)
            {
                result.Error = ex.Message;
            }
            finally { }
            return(result);
        }
        private IEnumerable <ExcelExpressionPart> EvaluateFunctionArguments(ExcelExpression expression, ExpressionScope scope)
        {
            var             args      = new List <ExcelExpressionPart>();
            ExcelExpression activeArg = null;

            foreach (var item in expression)
            {
                if (item.TokenType == ExcelFormulaTokenType.Argument)
                {
                    if (activeArg == null)
                    {
                        // possible optional argument -- consecutive commas
                        args.Add(new ExcelExpressionPart(ExcelValue.NULL));
                    }
                    else
                    {
                        args.Add(activeArg.Evaluate(scope));
                    }
                    activeArg = null;
                }
                else
                {
                    if (activeArg == null)
                    {
                        activeArg = new ExcelExpression();
                    }
                    activeArg.Add(item);
                }
            }
            if (activeArg != null)
            {
                args.Add(activeArg.Evaluate(scope));
            }
            return(args);
        }
        private void TraverseExpression(ExcelExpression expression, Queue <ExcelFormulaToken> tokens, ExpressionScope scope)
        {
            while (tokens.Any())
            {
                var token = tokens.Dequeue();
                if (token.Subtype == ExcelFormulaTokenSubtype.Stop)
                {
                    return;
                }
                else if (token.Subtype == ExcelFormulaTokenSubtype.Start)
                {
                    var childExpression = new ExcelExpression();
                    TraverseExpression(childExpression, tokens, scope);
                    switch (token.Type)
                    {
                    case ExcelFormulaTokenType.Function:
                        var name = token.Value.ToUpper();
                        var args = EvaluateFunctionArguments(childExpression, scope)
                                   .Select(o => o.Value)
                                   .ToList();
                        var value = Functions.INSTANCE.Evaluate(name, args, scope);
                        expression.Add(new ExcelExpressionPart(value));
                        break;

                    case ExcelFormulaTokenType.Subexpression:
                        var subExpression = childExpression.Evaluate(scope);
                        expression.Add(subExpression);
                        break;

                    default:
                        throw new NotImplementedException($"Start TokenType={token.Type}");
                    }
                }
                else
                {
                    expression.Add(new ExcelExpressionPart(token, scope));
                }
            }
        }
 public TResult Visit(ExcelExpression node)
 {
     return(node.Accept(this));
 }
Example #5
0
 internal BinaryExcelExpression(ExcelExpressionKind kind, ExcelExpression left, ExcelExpression right)
 {
     Kind  = kind;
     Left  = left;
     Right = right;
 }
Example #6
0
 public static BinaryExcelExpression Modulo(ExcelExpression left, ExcelExpression right)
 {
     return(new BinaryExcelExpression(ExcelExpressionKind.Modulo, left, right));
 }
Example #7
0
 public static BinaryExcelExpression Divide(ExcelExpression left, ExcelExpression right)
 {
     return(new BinaryExcelExpression(ExcelExpressionKind.Divide, left, right));
 }
Example #8
0
 public static BinaryExcelExpression Multiply(ExcelExpression left, ExcelExpression right)
 {
     return(new BinaryExcelExpression(ExcelExpressionKind.Multiply, left, right));
 }
Example #9
0
 public static BinaryExcelExpression Subtract(ExcelExpression left, ExcelExpression right)
 {
     return(new BinaryExcelExpression(ExcelExpressionKind.Subtract, left, right));
 }
Example #10
0
 public static BinaryExcelExpression Add(ExcelExpression left, ExcelExpression right)
 {
     return(new BinaryExcelExpression(ExcelExpressionKind.Add, left, right));
 }