/// <summary> /// Resolves parentheses and adds ".call" to direct function calls on variables. /// </summary> private string ResolveParentheses(string exp) { if (exp.Contains("(") && exp.Contains(")")) { int index = 0; int depth = 0; int parenthesesStartIndex = -1; StringBuilder newExpression = new StringBuilder(); StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, 0); while (index < exp.Length) { char t = exp[index]; escaper.CheckStartAt(index); if (!escaper.IsString) { if (t == '{' || t == '[') { depth++; if (parenthesesStartIndex == -1) newExpression.Append(t); } else if (t == '}' || t == ']') { depth--; if (parenthesesStartIndex == -1) newExpression.Append(t); } else if (t == '(') { if (depth == 0 && parenthesesStartIndex == -1) { ElementCapture capture = CaptureLeft(newExpression.ToString(), newExpression.Length - 1); string identifier = capture.Identifier; if (capture.Depth == 0 || identifier == "") { if (identifier.Length == 0) { parenthesesStartIndex = index; } else { string testExp = newExpression.ToString().Remove(capture.StartIndex).Trim(); if (testExp.Length > 0 && testExp.Last() == '.' || StatementProcessor.controlStatements.Contains(identifier) || identifier.StartsWith("new ")) { newExpression.Append(t); } else { newExpression.Append(".call" + t); } depth++; } } else { newExpression.Append(t); depth++; } } else { depth++; if (parenthesesStartIndex == -1) newExpression.Append(t); } } else if (t == ')') { if (depth == 0 && parenthesesStartIndex > -1) { string parenthesesCode = exp.Substring(parenthesesStartIndex + 1, index - parenthesesStartIndex - 1); if (parenthesesCode.Length > 0) { if (parenthesesCode.Contains("=>") && Regex.IsMatch(parenthesesCode, REGEX_LAMBDA)) { newExpression.Append(BuildLambdaFunction(parenthesesCode)); } else { var returnObject = ExecuteStatement(new ScriptStatement(parenthesesCode)); newExpression.Append(returnObject.ToScriptObject()); } } parenthesesStartIndex = -1; } else { depth--; if (parenthesesStartIndex == -1) newExpression.Append(t); } } else { if (parenthesesStartIndex == -1) newExpression.Append(t); } } else { if (parenthesesStartIndex == -1) newExpression.Append(t); } index++; } return newExpression.ToString(); } return exp; }
/// <summary> /// Captures an element right from the starting index. /// </summary> private ElementCapture CaptureRight(string exp, int index) { if (string.IsNullOrWhiteSpace(exp)) return new ElementCapture() { Length = 0, StartIndex = 0, Identifier = "", Depth = 0 }; string identifier = ""; bool foundSeperatorChar = false; int depth = 0; StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, index); while (index < exp.Length && !foundSeperatorChar) { char t = exp[index]; escaper.CheckStartAt(index); if (!escaper.IsString) { if (t == ')' || t == ']' || t == '}') { depth--; } else if (t == '(' || t == '[' || t == '{') { depth++; } } if (t == '-' && string.IsNullOrWhiteSpace(identifier)) { identifier += "-"; } else { if (!escaper.IsString && depth == 0) { if (t == '.') { // Check if the '.' is not a decimal seperator: if (!Regex.IsMatch(identifier.Trim(), REGEX_NUMLEFTDOT)) { foundSeperatorChar = true; } } else if (IDENTIFIER_SEPERATORS.Contains(t)) { foundSeperatorChar = true; } } // Append the char to the identifier: if (!foundSeperatorChar) { identifier += t; } } index++; } if (foundSeperatorChar) return new ElementCapture() { StartIndex = index - 1 - identifier.Length, Length = identifier.Length, Identifier = identifier.Trim(), Depth = depth }; else return new ElementCapture() { StartIndex = index - identifier.Length, Length = identifier.Length, Identifier = identifier.Trim(), Depth = depth }; }
/// <summary> /// Returns positions of the given operator in the expression, sorted from left to right. /// </summary> private int[] GetOperatorPositions(string exp, string op) { List<int> operators = new List<int>(); StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, 0); int depth = 0; int index = 0; while (index < exp.Length) { char t = exp[index]; escaper.CheckStartAt(index); if (!escaper.IsString) { if (t == '(' || t == '[' || t == '{') { depth--; } else if (t == ')' || t == ']' || t == '}') { depth++; } if (t == op[0] && depth == 0) { if (op.Length > 1 && index + op.Length - 1 < exp.Length) { bool correctOperator = true; for (int i = 1; i < op.Length; i++) { if (exp[index + i] != op[i]) correctOperator = false; } if (correctOperator) operators.Add(index); } else if (op.Length == 1) { operators.Add(index); } } } index++; } return operators.ToArray(); }