/// <summary> /// Gets bracket operation and creates list from them /// </summary> /// <param name="data">String with expression</param> /// <param name="bracketOperations"></param> /// <returns>Data without brackets operations</returns> private static string CalculateBrackets(string data) { string actExpr = ""; string specialMode = ""; int bracketLevel = 0; List <BracketOperation> bracketOperations = new List <BracketOperation>(); for (int i = 0; i < data.Length; i++) { if (bracketLevel > 0) { actExpr += data[i]; } if (data[i] == ')') { if (bracketLevel > 1) { bracketLevel--; } else if (bracketLevel == 1) { BracketOperation operation = new BracketOperation(actExpr.Remove(0, 1).Remove(actExpr.Length - 2, 1), i - actExpr.Length + 1 - specialMode.Length); if (specialMode.Length > 0) { Function f = FindFunction(specialMode, true); if (f == null) { Debug.LogError("Cannot find function " + specialMode); return("ENOFUNCTION"); } operation.specialFunction = f; } //Debug.Log("Bracket operation: \"" + operation.operation + "\""); //Debug.Log("Bracket operation start: " + operation.positionInString); bracketOperations.Add(operation); data = data.Remove(i - actExpr.Length + 1 - specialMode.Length, actExpr.Length + specialMode.Length); i -= actExpr.Length + specialMode.Length; actExpr = ""; specialMode = ""; bracketLevel = 0; } else { Debug.LogError("Closing bracket without opening"); return(double.NaN.ToString()); } } else if (data[i] == '(') { bracketLevel++; if (bracketLevel == 1) { actExpr += data[i]; string s = ""; for (int j = i - 1; j >= 0; j--) { if (MUtil.IsNumber(data[j])) { break; } if (FindOperation(data[j]) != null) { break; } s = "" + data[j]; specialMode = specialMode.Insert(0, s); } } } } //Debug.Log("Bracket level: " + bracketLevel); if (bracketLevel > 0) { Debug.LogError("No closing bracket"); return("ENOCLOSEBRACKET"); } // Recurently get additional brackets from brackets for (int i = 0; i < bracketOperations.Count; i++) { BracketOperation op = bracketOperations[i]; op.operation = CalculateBrackets(bracketOperations[i].operation); bracketOperations[i] = op; } // Calcualate brackets for (int i = 0; i < bracketOperations.Count; i++) { string rtBeforeComma = ""; string rtAfterComma = ""; bool rtIsAfterComma = false; string result; // Two args functions if (bracketOperations[i].specialFunction != null && bracketOperations[i].specialFunction.function == null && bracketOperations[i].specialFunction.twoArgFunction != null) { for (int j = 0; j < bracketOperations[i].operation.Length; j++) { if (bracketOperations[i].operation[j] == ';') { rtIsAfterComma = true; continue; } if (rtIsAfterComma) { rtAfterComma += bracketOperations[i].operation[j]; } else { rtBeforeComma += bracketOperations[i].operation[j]; } } rtBeforeComma = CalculateExpression(rtBeforeComma); //Debug.Log("rtBeforeComma after: " + rtBeforeComma); rtAfterComma = CalculateExpression(rtAfterComma); //Debug.Log("rtAfterComma after: " + rtAfterComma); result = "0"; } else { result = CalculateExpression(bracketOperations[i].operation); } double res; if (!double.TryParse(result, out res)) { Debug.LogError("Cannot convert " + result + " to result ( double )"); return("ECONVERSION"); } if (bracketOperations[i].specialFunction != null) { if (bracketOperations[i].specialFunction.function != null) { res = bracketOperations[i].specialFunction.function.Invoke(res); result = MUtil.ToStandardNotationString(res); if (result.Length == 0) { result = "0"; } } else { if (bracketOperations[i].specialFunction.function == null && bracketOperations[i].specialFunction.twoArgFunction != null) { if (rtBeforeComma.Length == 0 || rtAfterComma.Length == 0) { Debug.LogError("Bad 2 arg function arguments"); return("EBADROOTARG"); } else { double l1; double n; if (!double.TryParse(rtBeforeComma, out l1)) { Debug.LogError("Cannot convert first root argument to l1 ( double )"); return("EBADCONVERSION"); } if (!double.TryParse(rtAfterComma, out n)) { Debug.LogError("Cannot convert second root argument to n ( double )"); return("EBADCONVERSION"); } res = bracketOperations[i].specialFunction.twoArgFunction(l1, n); //OperationFunctions.Rt(l1, n); result = MUtil.ToStandardNotationString(res); if (result.Length == 0) { result = "0"; } } } } //Debug.Log("Result: " + result); } data = data.Insert(bracketOperations[i].positionInString, result); // Fix offsets for (int j = i + 1; j < bracketOperations.Count; j++) { BracketOperation tOp = bracketOperations[j]; tOp.positionInString += result.Length; bracketOperations[j] = tOp; } } return(data); }
public static string CalculateSpecificOperations(string data, Operation[] allowedOperations) { double l1 = 0, l2 = 0; Operation op = null; // First operation is always addition string actualNumber = ""; bool noPrevOperators = true; bool operationIsAllowed = false; int startIndex = 0; string startData = ""; for (int i = 0; i < data.Length; i++) { op = FindOperation(data[i]); if (op != null) { if (i == 0 && data[0] == '-') { startData += data[0]; continue; } startIndex = i; break; } startData += data[i]; } // No operator if (op == null) { return(data); } if (startIndex == 0) { Debug.LogError("Operator without number: \"" + data + "\" op: " + op.name); return("EOPWTHTNMBR"); } if (!double.TryParse(startData, out l1)) { if (startData[startData.Length - 1] == 'E') { for (int i = startData.Length; i < data.Length; i++) { if (MUtil.IsNumber(data[i]) || data[i] == '+') { startData += data[i]; } else { break; } } for (int i = 0; i < data.Length; i++) { if (data[i] == 'E') { if (data.Length > i + 1) { if (data[i + 1] == '+') { i += 2; } } } op = FindOperation(data[i]); if (op != null) { break; } } l1 = MUtil.GetDoubleFromExpNotation(startData); data = data.Remove(0, startData.Length); string decimalStartData = MUtil.ExpNotationToDecimalNotation(startData); data = data.Insert(0, decimalStartData); startData = decimalStartData; startIndex = startData.Length; Debug.Log("Data after converting exponent notation: " + data); } else { Debug.LogError("Cannot convert " + startData + " to l1 ( double )"); return("ECONVERSION"); } if (l1.Equals(double.NaN)) { Debug.LogError("Cannot convert " + startData + " to l1 ( double ). l1 = NaN"); return("ECONVERSION"); } } actualNumber = startData; bool firstOperation = true; // Multiply for (int i = startIndex; i < data.Length; i++) { Operation aop = FindOperation(data[i]); if (aop != null) { if (actualNumber.Length == 0 && data[i] == '-') { actualNumber += data[i]; continue; } operationIsAllowed = false; for (int j = 0; j < allowedOperations.Length; j++) { if (op == allowedOperations[j]) { operationIsAllowed = true; break; } } if (operationIsAllowed) { if (data[i] == '+' && i > 0 && (data[i - 1] == 'E')) { actualNumber += data[i]; continue; } //Debug.Log("Data before: " + data); if (noPrevOperators) { data = data.Remove(0, actualNumber.Length); i = 0; } else { string l1Str = MUtil.ToStandardNotationString(l1); data = data.Remove(i - actualNumber.Length - 1 - l1Str.Length, actualNumber.Length + 1 + l1Str.Length); i -= actualNumber.Length + 1 + l1Str.Length; } noPrevOperators = false; //l1 = l2; //actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber); if (!DoMaths(ref actualNumber, ref l1, ref l2, ref op, aop, ref firstOperation)) { return("ECONVERSION"); } string standardNotL1 = MUtil.ToStandardNotationString(l1); data = data.Insert(i, standardNotL1); i += standardNotL1.Length; actualNumber = ""; op = aop; //Debug.Log("Data after: " + data); } else { if (data[i] == '+' && i > 0 && (data[i - 1] == 'E')) { actualNumber += data[i]; continue; } if (!double.TryParse(actualNumber, out l1)) { actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber); if (!double.TryParse(actualNumber, out l1)) { Debug.LogError("Cannot parse " + actualNumber + " to number ( double ) #2"); return("ECONVERSION"); } } op = aop; actualNumber = ""; noPrevOperators = false; firstOperation = false; } } else { actualNumber += data[i]; } } operationIsAllowed = false; for (int j = 0; j < allowedOperations.Length; j++) { if (op == allowedOperations[j]) { operationIsAllowed = true; break; } } if (operationIsAllowed) { if (data[data.Length - 1] == '+' && data.Length > 0 && (data[data.Length - 1] == 'E')) { return(data); } //Debug.Log("l1.ToString(): " + MUtil.ExpNotationToDecimalNotation(l1.ToString()) + ", lenght: " + MUtil.ExpNotationToDecimalNotation(l1.ToString()).Length); string l1Str = MUtil.ToStandardNotationString(l1); data = data.Remove(data.Length - actualNumber.Length - 1 - l1Str.Length, actualNumber.Length + 1 + l1Str.Length); noPrevOperators = false; //l1 = l2; //actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber); if (!DoMaths(ref actualNumber, ref l1, ref l2, ref op, operations[0], ref firstOperation)) { return("ECONVERSION"); } data = data.Insert(data.Length, MUtil.ToStandardNotationString(l1)); //i += l1.ToString().Length; actualNumber = ""; op = operations[0]; //Debug.Log("Data after: " + data); } return(data); }