public void ParseNumber() { var str = "5"; var res = ExprCalc.Eval(str); Assert.AreEqual(5, res); }
public void MinusParan() { var str = "2 * -(1+1)"; var res = ExprCalc.Eval(str); Assert.AreEqual(-4, res); }
public void MultiplyToMinus() { var str = "2 * -1"; var res = ExprCalc.Eval(str); Assert.AreEqual(-2, res); }
public void CalcParanMinus2Plus2() { var str = "(-2 + 2)"; var res = ExprCalc.Eval(str); Assert.AreEqual(0, res); }
public void Calc2Plus2() { var str = "2 + 2"; var res = ExprCalc.Eval(str); Assert.AreEqual(4, res); }
public void OpOrder() { var str = "2 + 2 * 2"; var res = ExprCalc.Eval(str); Assert.AreEqual(6, res); var res2 = ExprCalc.Eval("(2*2) + 2"); Assert.AreEqual(6, res2); }
public ParseContentRes ParseContent(string str, VarStorg vars) { VarStorg localVars = null; var res = string.Empty; var inherits = new List <string>(); for (var i = 0; i < str.Length; i++) { var skipChar = false; var varfound = false; if (str.IsNextStr(i, OssConst.InheritKey)) { // inherit i += OssConst.InheritKey.Length; var name = str.GetNextWordToSemicol(i, out i); inherits.Add(name); res = res.TrimEnd(StrConst.EmptyChars); // rem space left from inherit line continue; } if (str.IsNextStr(i, OssConst.CalcKey)) { i += OssConst.CalcKey.Length - 1; var endi = StrUtil.GetBlockEndPrn(str, i); if (endi < 0) { throw new Exception("can't find end of calc("); } var expr = str.FromTo(i + 1, endi - 1); var pexpr = ParseContent(expr, vars).Content; var val = ExprCalc.Eval(pexpr); if (val == (int)val) { res = res + val; } else { res = res + val.ToString("0.##", CultureInfo.InvariantCulture); } i = endi; skipChar = true; } var isvar = str.IsNextStr(i, OssConst.VarKey); var isvarprn = str.IsNextStr(i, OssConst.VarPrnKey); if (isvar || isvarprn) { // var.x string varname = null; if (isvar) { i += OssConst.VarKey.Length; foreach (var key in vars.Keys) { if (!str.IsNextStr(i, key)) { continue; } i += key.Length - 1; varname = key; varfound = true; skipChar = true; break; } } else { i += OssConst.VarPrnKey.Length; var endi = StrUtil.GetBlockEndPrn(str, i); varname = str.FromTo(i, endi - 1).Trim(); i = endi; var psi = str.FindNextNonEmpty("{", i + 1); if (psi > -1) { var pei = str.GetBlockEnd(psi); if (pei < 0) { logger.Error($"can't find closing bracket for var({varname}) parameters ')' "); } var pcon = str.FromTo(psi + 1, pei - 1); var parms = ParamsParser.Parse(pcon); localVars = new VarStorg(); foreach (var parm in parms) { var osv = new OssVar(); osv.Name = parm.Key; osv.IsRules = parm.Value.Contains("{"); osv.Val = osv.IsRules ? new ParseContentRes { Content = parm.Value } : ParseContent(parm.Value, vars); //osv.Val.RawContent = parm.Value; localVars.Add(parm.Key, osv); } i = pei; } varfound = true; skipChar = true; } if (varfound) { var vpr = vars[varname].Val; var val = vpr.Content; if (localVars != null) { // merge vars into localVars, without vars that exist in localVars //foreach (var item in vars) //{ // if (!localVars.ContainsKey(item.Key)) // { // localVars.Add(item); // } //} localVars.SetBase(vars); val = ParseContent(vpr.RawContent, localVars).Content; } else if (vpr.IsRaw) { val = ParseContent(vpr.RawContent, vars).Content; } // get indentation if (val.Contains(';')) { var nli = res.LastIndexOf('\n'); if (nli > 0) { var space = res.Substring(nli + 1); if (space.Length > 0 && space.Trim(' ', '\t').Length == 0) { // set indentation in val var arr = val.Split('\n'); for (var j = 1; j < arr.Length; j++) { arr[j] = space + arr[j].TrimStart(); } val = string.Join("\n", arr); } } } if (val == "rem") { res = res.TrimEnd(); var spacei = res.LastIndexOfAny(new[] { ' ', '\t' }); if (spacei > 0) { res = res.Remove(spacei).TrimEnd(new[] { ' ', '\t' }); } val = string.Empty; } res += val; if (vpr.Inherits != null) { inherits.AddRange(vpr.Inherits); } if ((val.EndsWith(";") || val == string.Empty) && str.Length > i + 1 && str[i + 1] == ';') { i++; } if (val == string.Empty) { var nli = str.IndexOf("\n", i, StringComparison.Ordinal); if (nli > 0) { if (str.FromTo(i + 1, nli).Trim(StrConst.EmptyChars) == string.Empty) { i = nli; res = res.TrimEnd(' ', '\t'); } } } } else { logger.Error("could not find var at " + str.GetNextWordToSemicol(i, out _)); } } if (!skipChar) { res += str[i]; } } return(new ParseContentRes { Content = res, Inherits = inherits }); }