Beispiel #1
0
        public LexemVariable Calculate(ILexemEnvironment environment = null)
        {
            if (_poliz == null)
                _poliz = LexemPoliz.Create(_lexems);

            var result = _poliz.Calculate(environment);

            if (_variable != null && !String.IsNullOrEmpty(_variable.Name) && environment != null && result != null)
                environment.Set(_variable.Name, result.Value);

            return result;
        }
Beispiel #2
0
        public LexemVariable Calculate(ILexemEnvironment environment = null)
        {
            var args = this.Arguments.Select(arg => arg.Calculate(environment).Value).ToList();

            Func<int, double> getNumber = i => ((LexemValueNumber)args[i]).Value;

            switch (this.Name)
            {
                case "e":
                    return Math.E;
                case "pi":
                    return Math.PI;
                case "count":
                    return this.Arguments.Count;
                case "min":
                    return args.Min(arg => ((LexemValueNumber)arg).Value);
                case "max":
                    return args.Max(arg => ((LexemValueNumber)arg).Value);
                case "avg":
                    return args.Average(arg => ((LexemValueNumber)arg).Value);
                case "sum":
                    return args.Sum(arg => ((LexemValueNumber)arg).Value);
                case "sin":
                    return Math.Sin(getNumber(0));
                case "cos":
                    return Math.Cos(getNumber(0));
                case "tg":
                    return Math.Tan(getNumber(0));
                case "ctg":
                    return Math.Cos(getNumber(0)) / Math.Sin(getNumber(0));
                case "asin":
                    return Math.Asin(getNumber(0));
                case "acos":
                    return Math.Acos(getNumber(0));
                case "atg":
                    return Math.Atan(getNumber(0));
                case "actg":
                    return Math.PI / 2 - Math.Atan(getNumber(0));
                case "exp":
                    return Math.Exp(getNumber(0));
                case "ln":
                    return Math.Log(getNumber(0));
                case "abs":
                    return Math.Abs(getNumber(0));
                case "sign":
                    return Math.Sign(getNumber(0));
                case "sqrt":
                    return Math.Sqrt(getNumber(0));
                case "pow":
                    return Math.Pow(getNumber(0), getNumber(1));
                case "round":
                    return Math.Round(getNumber(0), (int)getNumber(1));
            }

            if (environment != null)
            {
                var res = environment.Calculate(this);
                if (res != null)
                    return res.Value;
            }

            throw new ArgumentException(String.Format("Function not recognized: {0}", this.Name));
        }
Beispiel #3
0
        public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
        {
            if (lexem == null)
                throw new InvalidOperationException("Can't execute null lexem on Value");

            var function = lexem as LexemFunction;
            if (function != null)
            {
                switch (function.Name.ToLower())
                {
                    case "tostring":
                        return this.ToString();
                }
            }

            return base.Execute(lexem, environment);
        }
Beispiel #4
0
        public LexemVariable Compute(Lexem argument1, Lexem argument2, ILexemEnvironment environment = null)
        {
            LexemValue result = null;

            if (this.OperatorType == OperationType.Arithmetic)
            {
                #region Arithmetic Operations
                LexemValue arg1 = LexemValue.GetValue(argument1);
                LexemValue arg2 = LexemValue.GetValue(argument2);
                if (arg1 == null || arg2 == null) return null;

                if (arg1 is LexemValueNumber && arg2 is LexemValueNumber)
                {
                    #region number
                    LexemValueNumber val1 = (LexemValueNumber)arg1;
                    LexemValueNumber va12 = (LexemValueNumber)arg2;

                    if (this.Text == "+") result = val1 + va12;
                    else if (this.Text == "-") result = val1 - va12;
                    else if (this.Text == "*") result = val1 * va12;
                    else if (this.Text == "/") result = val1 / va12;
                    #endregion
                }
                else if (arg1 is LexemValueComplex && arg2 is LexemValueComplex)
                {
                    #region complex
                    LexemValueComplex val1 = (LexemValueComplex)arg1;
                    LexemValueComplex val2 = (LexemValueComplex)arg2;

                    if (this.Text == "+") result = val1 + val2;
                    else if (this.Text == "-") result = val1 - val2;
                    else if (this.Text == "*") result = val1 * val2;
                    else if (this.Text == "/") result = val1 / val2;

                    if (result != null && result is LexemValueComplex && ((LexemValueComplex)result).Im == 0)
                        result = ((LexemValueComplex)result).Re;
                    #endregion
                }
                else if (arg1 is LexemValueDate && arg2 is LexemValueSpan)
                {
                    #region date and span
                    LexemValueDate date = (LexemValueDate)arg1;
                    LexemValueSpan span = (LexemValueSpan)arg2;

                    if (this.Text == "+")
                        result = date.Value + span.Value;
                    else if (this.Text == "-")
                        result = date.Value - span.Value;
                    #endregion
                }
                else if (arg1 is LexemValueSpan && arg2 is LexemValueDate)
                {
                    #region span and date
                    LexemValueDate date = (LexemValueDate)arg2;
                    LexemValueSpan span = (LexemValueSpan)arg1;

                    if (this.Text == "+")
                        result = date.Value + span.Value;
                    #endregion
                }
                else if (arg1 is LexemValueDate && arg2 is LexemValueDate)
                {
                    if (this.Text == "-")
                        result = ((LexemValueDate)arg1) - ((LexemValueDate)arg2);
                }
                else if (arg1 is LexemValueText && arg2 is LexemValueText)
                {
                    if (this.Text == "+")
                        result = ((LexemValueText)arg1) + ((LexemValueText)arg2);
                }
                #endregion
            }
            else if (this.OperatorType == OperationType.Logical)
            {
                #region Logical Operations
                LexemValue arg1 = LexemValue.GetValue(argument1);
                LexemValue arg2 = LexemValue.GetValue(argument2);
                if (arg1 == null || arg2 == null) return null;

                if (arg1 is LexemValueBool && arg2 is LexemValueBool)
                {
                    if (this.Text == "||")
                        result = ((LexemValueBool)arg1) || ((LexemValueBool)arg2);
                    else if (this.Text == "&&")
                        result = ((LexemValueBool)arg1) && ((LexemValueBool)arg2);
                    else
                        throw new InvalidOperationException($"Invalid operation {this.Text} between booleans");
                }
                #endregion
            }
            else if (this.OperatorType == OperationType.Comparison)
            {
                #region Comparison Operations
                LexemValue arg1 = LexemValue.GetValue(argument1);
                LexemValue arg2 = LexemValue.GetValue(argument2);
                if (arg1 == null || arg2 == null) return null;

                if (arg1 is LexemValueNumber && arg2 is LexemValueNumber)
                {
                    #region number
                    LexemValueNumber number1 = (LexemValueNumber)arg1;
                    LexemValueNumber number2 = (LexemValueNumber)arg2;

                    if (this.Text == ">") result = number1 > number2;
                    else if (this.Text == ">=") result = number1 >= number2;
                    else if (this.Text == "<") result = number1 < number2;
                    else if (this.Text == "<=") result = number1 <= number2;
                    else if (this.Text == "==") result = number1 == number2;
                    else if (this.Text == "!=") result = number1 != number2;
                    #endregion
                }
                else if (arg1 is LexemValueComplex && arg2 is LexemValueComplex)
                {
                    #region complex
                    LexemValueComplex complex1 = (LexemValueComplex)arg1;
                    LexemValueComplex complex2 = (LexemValueComplex)arg2;

                    if (this.Text == ">") result = complex1 > complex2;
                    else if (this.Text == ">=") result = complex1 >= complex2;
                    else if (this.Text == "<") result = complex1 < complex2;
                    else if (this.Text == "<=") result = complex1 <= complex2;
                    else if (this.Text == "==") result = complex1 == complex2;
                    else if (this.Text == "!=") result = complex1 != complex2;
                    #endregion
                }
                else if (arg1 is LexemValueText && arg2 is LexemValueText)
                {
                    #region text
                    LexemValueText text_1 = (LexemValueText)arg1;
                    LexemValueText text_2 = (LexemValueText)arg2;

                    if (this.Text == ">") result = text_1 > text_2;
                    else if (this.Text == ">=") result = text_1 >= text_2;
                    else if (this.Text == "<") result = text_1 < text_2;
                    else if (this.Text == "<=") result = text_1 <= text_2;
                    else if (this.Text == "==") result = text_1 == text_2;
                    else if (this.Text == "!=") result = text_1 != text_2;
                    #endregion
                }
                else if (arg1 is LexemValueDate && arg2 is LexemValueDate)
                {
                    #region date
                    LexemValueDate date1 = (LexemValueDate)arg1;
                    LexemValueDate date2 = (LexemValueDate)arg2;

                    if (this.Text == ">") result = date1 > date2;
                    else if (this.Text == ">=") result = date1 >= date2;
                    else if (this.Text == "<") result = date1 < date2;
                    else if (this.Text == "<=") result = date1 <= date2;
                    else if (this.Text == "==") result = date1 == date2;
                    else if (this.Text == "!=") result = date1 != date2;
                    #endregion
                }
                else if (arg1 is LexemValueSpan && arg2 is LexemValueSpan)
                {
                    #region span
                    LexemValueSpan span1 = (LexemValueSpan)arg1;
                    LexemValueSpan span2 = (LexemValueSpan)arg2;

                    if (this.Text == ">") result = span1 > span2;
                    else if (this.Text == ">=") result = span1 >= span2;
                    else if (this.Text == "<") result = span1 < span2;
                    else if (this.Text == "<=") result = span1 <= span2;
                    else if (this.Text == "==") result = span1 == span2;
                    else if (this.Text == "!=") result = span1 != span2;
                    #endregion
                }
                #endregion
            }
            else if (this.OperatorType == OperationType.Code)
            {
                #region Code Operations
                if (this.Text != "->" && this.Text != ".") return null;
                if (argument1 is LexemVariable)
                    return ((LexemVariable)argument1).Execute(argument2, environment);
                else if (argument1 is LexemValue)
                    return ((LexemValue)argument1).Execute(argument2, environment);
                else
                    return null;
                #endregion
            }

            return result;
        }
Beispiel #5
0
        public LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
        {
            if (lexem == null)
                throw new InvalidOperationException("Can't execute null lexem on Variable");

            if (this.Value == null)
                throw new InvalidOperationException("Can't execute Lexem on empty Value");

            return this.Value.Execute(lexem, environment);
        }
Beispiel #6
0
        public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
        {
            if (lexem == null)
                throw new InvalidOperationException("Can't execute null lexem on Value");

            if (lexem is LexemVariable)
                return this[((LexemVariable)lexem).Name];

            return base.Execute(lexem, environment);
        }
Beispiel #7
0
        public LexemVariable Calculate(ILexemEnvironment environment = null)
        {
            var stack = new Stack<Lexem>();

            for (int i = 0; i < _lexems.Count; i++)
            {
                if (_lexems[i] is LexemValue)
                {
                    stack.Push(_lexems[i]);
                }
                else if (_lexems[i] is LexemFunction)
                {
                    var prev = stack.Count <= 0 ? null : stack.Peek(); //i - 1 >= 0 ? _lexems[i - 1] : null;
                    var next = i + 1 < _lexems.Count ? _lexems[i + 1] : null;

                    if (prev != null && (prev is LexemValue || prev is LexemVariable) && next != null && next is LexemOperator && ((LexemOperator)next).OperatorType == LexemOperator.OperationType.Code)
                        stack.Push(_lexems[i]);
                    else
                        stack.Push((_lexems[i] as LexemFunction).Calculate(environment));
                }
                else if (_lexems[i] is LexemVariable)
                {
                    var variable = environment == null ? null : environment.Get((_lexems[i] as LexemVariable).Name);
                    stack.Push(variable == null ? _lexems[i] : variable);
                }
                else if (_lexems[i] is LexemOperator)
                {
                    var argument2 = stack.Pop();
                    var argument1 = stack.Pop();

                    stack.Push((_lexems[i] as LexemOperator).Compute(argument1, argument2, environment));
                }
                else if (_lexems[i] is LexemSwitch && _lexems[i].ToString() == "?")
                {
                    var sw = _lexems[i] as LexemSwitch;

                    var condition = LexemValue.GetValue(stack.Pop()) as LexemValueBool;
                    if (condition == null)
                        throw new InvalidOperationException("Conditional expression should return boolean value");

                    var separatorIndex = _lexems.FindPosition(sw.Simetric);
                    var endIndex = _lexems.FindPosition(sw.End);

                    if (condition.Value)
                        stack.Push(new LexemPoliz(_lexems.Range(i + 1, separatorIndex - i - 1)).Calculate(environment));
                    else
                        stack.Push(new LexemPoliz(_lexems.Range(separatorIndex + 1, endIndex - separatorIndex)).Calculate(environment));

                    i = endIndex;
                }
                else
                    stack.Push(_lexems[i]);
            }

            if (stack.Count != 1)
                throw new InvalidOperationException("Resulting lexem should be a single one");

            Lexem result = stack.Pop();
            if (result is LexemVariable)
                return (LexemVariable)result;
            else if (result is LexemValue)
                return (LexemValue)result;

            throw new InvalidOperationException("Resulting lexem should be Variable or Value type");
        }
Beispiel #8
0
 public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
 {
     return base.Execute(lexem, environment);
 }
Beispiel #9
0
        public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
        {
            if (lexem == null)
                throw new InvalidOperationException("Can't execute null lexem on Value");

            if (lexem is LexemVariable)
            {
                switch (((LexemVariable)lexem).Name.ToLower())
                {
                    case "date":
                        return this.Value.Date;
                    case "year":
                        return this.Value.Year;
                    case "month":
                        return this.Value.Month;
                    case "day":
                        return this.Value.Day;
                    case "hour":
                        return this.Value.Hour;
                    case "minute":
                        return this.Value.Minute;
                    case "second":
                        return this.Value.Second;
                    case "dayofweek":
                        return this.Value.DayOfWeek.ToString();
                }
            }
            else if (lexem is LexemFunction)
            {
                var function = lexem as LexemFunction;

                Func<int, double> getFuncNumber = i => (function.Arguments[i].Calculate(environment).Value as LexemValueNumber).Value;

                switch (((LexemFunction)lexem).Name.ToLower())
                {
                    case "tostring":
                        return this.Value.ToString(Formats.First());
                    case "addyears":
                        return this.Value.Date.AddYears((int)getFuncNumber(0));
                    case "addmonths":
                        return this.Value.Date.AddMonths((int)getFuncNumber(0));
                    case "adddays":
                        return this.Value.Date.AddDays(getFuncNumber(0));
                    case "addhours":
                        return this.Value.Date.AddHours(getFuncNumber(0));
                    case "addminutes":
                        return this.Value.Date.AddMinutes(getFuncNumber(0));
                    case "addseconds":
                        return this.Value.Date.AddSeconds(getFuncNumber(0));
                }
            }

            return base.Execute(lexem, environment);
        }
Beispiel #10
0
 public static LexemVariable Calculate(string text, ILexemEnvironment environment = null)
 {
     return new LexemExpression(text).Calculate(environment);
 }
Beispiel #11
0
        public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null)
        {
            if (lexem == null)
                throw new InvalidOperationException("Can't execute null lexem on Value");

            if (lexem is LexemVariable)
            {
                switch (((LexemVariable)lexem).Name.Trim().ToLower())
                {
                    case "length":
                        return this.Value.Length;
                }
            }
            else if (lexem is LexemFunction)
            {
                LexemFunction function = lexem as LexemFunction;

                Func<int, string> getFuncString = i => (function.Arguments[i].Calculate(environment).Value as LexemValueText).Value;
                Func<int, double> getFuncNumber = i => (function.Arguments[i].Calculate(environment).Value as LexemValueNumber).Value;

                switch (function.Name.Trim().ToLower())
                {
                    case "tostring":
                        return this.Value;
                    case "tonumber":
                        return LexemValueNumber.ParseNumber(this.Value, true);
                    case "todatetime":
                    case "todate":
                        {
                            return LexemValueDate.ParseDateTime(this.Value);
                        }
                    case "trim":
                        return this.Value.Trim();
                    case "tolower":
                        return this.Value.ToLower();
                    case "toupper":
                        return this.Value.ToUpper();
                    case "startswith":
                        return this.Value.StartsWith(getFuncString(0));
                    case "endswith":
                        return this.Value.EndsWith(getFuncString(0));
                    case "contains":
                        return this.Value.Contains(getFuncString(0));
                    case "like":
                        return this.Value.Like(getFuncString(0));
                    case "indexof":
                        return this.Value.IndexOf(getFuncString(0));
                    case "replace":
                        return this.Value.Replace(getFuncString(0), getFuncString(1));
                    case "substring":
                        {
                            if (function.Arguments.Count >= 2)
                                return this.Value.Substring((int)getFuncNumber(0), (int)getFuncNumber(1));
                            else
                                return this.Value.Substring((int)getFuncNumber(0));
                        }
                }
            }

            return base.Execute(lexem, environment);
        }