public ValueString(string code, Dictionary <string, float> variables) { values = new List <float> (); elements = new List <ExpressionElement> (); string[] sections = code.Split(' '); for (int i = 0; i < sections.Length; i++) { string section = sections[i]; // Check for built-in functions (sqrt, abs) etc if (VirtualCompiler.ArrayContainsString(VirtualCompiler.builtinFunctions, section)) { switch (section) { case "sqrt": elements.Add(ExpressionElement.SqrtFunc); break; case "abs": elements.Add(ExpressionElement.AbsFunc); break; case "sign": elements.Add(ExpressionElement.SignFunc); break; case "sin": elements.Add(ExpressionElement.SinFunc); break; case "cos": elements.Add(ExpressionElement.CosFunc); break; case "tan": elements.Add(ExpressionElement.TanFunc); break; case "asin": elements.Add(ExpressionElement.AsinFunc); break; case "acos": elements.Add(ExpressionElement.AcosFunc); break; case "atan": elements.Add(ExpressionElement.AtanFunc); break; } } // Check for math operators (+, -) etc else if (VirtualCompiler.ArrayContainsString(VirtualCompiler.mathOperators, section) || section == "(" || section == ")") { switch (section) { case "+": elements.Add(ExpressionElement.Plus); break; case "-": elements.Add(ExpressionElement.Minus); break; case "*": elements.Add(ExpressionElement.Multiply); break; case "/": elements.Add(ExpressionElement.Divide); break; case "(": elements.Add(ExpressionElement.StartGroup); break; case ")": elements.Add(ExpressionElement.EndGroup); break; } } // Try get value from variable name else if (variables.ContainsKey(section)) { values.Add(variables[section]); elements.Add(ExpressionElement.Value); } // Try get value from variable array else if (section.Contains("[") && section.Contains("]")) { string indexString = VirtualCompiler.Substring(section, section.IndexOf("[") + 1, section.IndexOf("]")); var indexValueString = new ValueString(CompilerFormatter.Format(indexString), variables); int index = (int)new NumericalExpression(indexValueString).Evaluate(); string varName = section.Substring(0, section.IndexOf("[")) + VirtualCompiler.arrayIndexSeperator + index; if (variables.ContainsKey(varName)) { elements.Add(ExpressionElement.Value); values.Add(variables[varName]); } } // Try parse value string to float else { float value; if (float.TryParse(section.Replace(".", ","), out value)) { values.Add(value); elements.Add(ExpressionElement.Value); } } } }
/// Format string such that all values/variables/operators are separated by a single space /// e.g. "x+7 *(3+y) <= -10" should be formatted as "x + 7 * ( 3 + y ) <= - 10" /// Note that compound operators (<= and >= and ==) should be treated as a single symbol /// Note also that anything inside array index should not be formatted: x[3*2+7] for example should be left as is public static string Format(string line) { line = line.Trim(); var sections = new List <string> (); string substring = ""; bool lastWasOperator = false; bool inArrayIndexer = false; for (int i = 0; i < line.Length; i++) { char currentChar = line[i]; bool isOperator = VirtualCompiler.allOperators.Contains(currentChar.ToString()); if (currentChar == '[') { inArrayIndexer = true; } else if (currentChar == ']') { inArrayIndexer = false; } if ((currentChar == spaceChar || isOperator || lastWasOperator) && !inArrayIndexer) { if (!string.IsNullOrEmpty(substring)) { sections.Add(substring); } substring = ""; } if (isOperator || currentChar != spaceChar) { substring += currentChar; } if (i == line.Length - 1) { if (!string.IsNullOrEmpty(substring)) { sections.Add(substring); } } lastWasOperator = isOperator; } string formattedLine = ""; string lastAddedSection = ""; for (int i = 0; i < sections.Count; i++) { // Remove previous space if compound operator string compound = lastAddedSection + sections[i]; if (VirtualCompiler.ArrayContainsString(VirtualCompiler.compoundOperators, compound)) { formattedLine = formattedLine.Substring(0, formattedLine.Length - 1); } formattedLine += sections[i]; if (i != sections.Count - 1) { formattedLine += spaceChar; } lastAddedSection = sections[i]; } return(formattedLine); }
static string HighlightLine(string line, SyntaxTheme theme) { var cols = new List <Color> (); var startEndIndices = new List <Vector2Int> (); string[] sections = CompilerFormatter.Format(line).Split(' '); int nonSpaceIndex = 0; bool isComment = false; for (int i = 0; i < sections.Length; i++) { Color colour = Color.clear; string section = sections[i]; if (section == VirtualCompiler.commentMarker || isComment) { colour = theme.comment; isComment = true; } else if (section == "if" || section == "elseif" || section == "else") { colour = theme.conditionKeyword; } else if (section == "loop") { colour = theme.loopKeyword; } else if (VirtualCompiler.ArrayContainsString(VirtualCompiler.mathOperators, section)) { colour = theme.mathOperator; } else if (VirtualCompiler.ArrayContainsString(VirtualCompiler.comparisonOperators, section)) { colour = theme.comparisonOperator; } else if (section == "(" || section == ")") { colour = theme.parentheses; } else if (section == "{" || section == "}") { colour = theme.curlyBrackets; } else if (float.TryParse(section.Replace('.', ','), out _)) { colour = theme.value; } else if (section == "=") { colour = theme.assignment; } else { colour = theme.variable; } if (colour != Color.clear) { cols.Add(colour); int endIndex = nonSpaceIndex + sections[i].Length; startEndIndices.Add(new Vector2Int(nonSpaceIndex, endIndex)); } nonSpaceIndex += sections[i].Length; } if (cols.Count > 0) { nonSpaceIndex = 0; int colIndex = 0; int actualStartIndex = -1; for (int i = 0; i <= line.Length; i++) { if (startEndIndices[colIndex].x == nonSpaceIndex) { actualStartIndex = i; } else if (startEndIndices[colIndex].y == nonSpaceIndex) { //print (colIndex + " replace: " + startEndIndices[colIndex] +" with: " + new Vector2Int (actualStartIndex, i)); startEndIndices[colIndex] = new Vector2Int(actualStartIndex, i); colIndex++; if (colIndex >= cols.Count) { break; } i--; continue; } if (i < line.Length) { char c = line[i]; if (c != ' ') { nonSpaceIndex++; } } } } for (int i = cols.Count - 1; i >= 0; i--) { var col = cols[i]; var startEndIndex = startEndIndices[i]; string colString = ColorUtility.ToHtmlStringRGB(col); line = line.Insert(startEndIndex.y, "</color>"); line = line.Insert(startEndIndex.x, $"<color=#{colString}>"); //print ("insert: " + startEndIndex.x + " " + startEndIndex.y); } return(line); }