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; }
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)); }
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); }
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; }
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); }
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); }
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"); }
public override LexemVariable Execute(Lexem lexem, ILexemEnvironment environment = null) { return base.Execute(lexem, environment); }
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); }
public static LexemVariable Calculate(string text, ILexemEnvironment environment = null) { return new LexemExpression(text).Calculate(environment); }
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); }