Пример #1
0
    void PreprocessCode(string rawCode)
    {
        code = rawCode.ToLower();

        // Enforce curly braces to be on their own line:
        code = code.Replace("{", "\n{\n");
        code = code.Replace("}", "\n}\n");

        // Format lines
        var unformattedLines = code.Split('\n');
        var formattedLines   = new List <string>();

        foreach (string unformattedLine in unformattedLines)
        {
            if (!string.IsNullOrWhiteSpace(unformattedLine))
            {
                string   formattedLine = CompilerFormatter.Format(unformattedLine);
                string[] sections      = formattedLine.Split(' ');

                // Strip comments
                foreach (string s in sections)
                {
                    if (s == commentMarker)
                    {
                        formattedLine = formattedLine.Substring(0, formattedLine.IndexOf(commentMarker));
                    }
                }
                if (!string.IsNullOrWhiteSpace(formattedLine))
                {
                    // Syntactic sugar
                    if (sections.Length > 1)
                    {
                        sections = formattedLine.Split(' ');
                        if (sections[1] == "+=")
                        {
                            formattedLine = string.Format("{0} = {0} + ( {1} )", sections[0], ArrayToString(sections, 2));
                        }
                        else if (sections[1] == "-=")
                        {
                            formattedLine = string.Format("{0} = {0} - ( {1} )", sections[0], ArrayToString(sections, 2));
                        }
                        else if (sections[1] == "*=")
                        {
                            formattedLine = string.Format("{0} = {0} * ( {1} )", sections[0], ArrayToString(sections, 2));
                        }
                        else if (sections[1] == "/=")
                        {
                            formattedLine = string.Format("{0} = {0} / ( {1} )", sections[0], ArrayToString(sections, 2));
                        }
                        else if (sections[1] == "++")
                        {
                            formattedLine = string.Format("{0} = {0} + 1", sections[0]);
                        }
                        else if (sections[1] == "--")
                        {
                            formattedLine = string.Format("{0} = {0} - 1", sections[0]);
                        }
                    }
                    formattedLines.Add(formattedLine);
                    processedCode += formattedLine + '\n';
                }
            }
        }

        lines = formattedLines.ToArray();

        // Create condition block info
        var conditionBlocks = new List <ConditionBlockInfo>();
        int blockDepth      = 0;

        for (int i = 0; i < lines.Length; i++)
        {
            string section   = lines[i].Split(' ')[0];
            var    condition = new ConditionBlockInfo()
            {
                lineIndex = i, depth = blockDepth
            };

            switch (section)
            {
            case "if":
                condition.type = ConditionBlockInfo.Type.If;
                conditionBlocks.Add(condition);
                break;

            case "elseif":
                condition.type = ConditionBlockInfo.Type.ElseIf;
                conditionBlocks.Add(condition);
                break;

            case "else":
                condition.type = ConditionBlockInfo.Type.Else;
                conditionBlocks.Add(condition);
                break;

            case "{":
                blockDepth++;
                break;

            case "}":
                blockDepth--;
                break;
            }
        }

        // Create links between chained conditions (if-elseif-else)
        for (int i = 0; i < conditionBlocks.Count; i++)
        {
            var condition = conditionBlocks[i];
            conditionByLineIndex.Add(condition.lineIndex, condition);
            // Try find an elseif/else block attached to this block
            if (condition.type == ConditionBlockInfo.Type.If || condition.type == ConditionBlockInfo.Type.ElseIf)
            {
                for (int j = i + 1; j < conditionBlocks.Count; j++)
                {
                    var nextCondition = conditionBlocks[j];

                    // At same depth, so might be continuation of chain
                    if (nextCondition.depth == condition.depth)
                    {
                        // If-statement is start of a new chain, so must be end of current chain
                        if (nextCondition.type == ConditionBlockInfo.Type.If)
                        {
                            break;
                        }
                        condition.nextInChain         = nextCondition;
                        nextCondition.previousInChain = condition;
                        break;
                    }
                    // Out of scope, so is end of chain
                    else if (nextCondition.depth < condition.depth)
                    {
                        break;
                    }
                }
            }
        }
    }
Пример #2
0
    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);
                }
            }
        }
    }
Пример #3
0
    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 == CompilerSymbols.commentMarker || isComment)
            {
                colour    = theme.comment;
                isComment = true;
            }
            else if (section == CompilerSymbols.usingKeyword)
            {
                colour = theme.usingKeyword;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.types, section))
            {
                colour = theme.types;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.reservedNames, section))
            {
                colour = theme.reservedNames;
            }
            else if (CompilerSymbols.allOperators.Contains(section.ToLower()))
            {
                colour = theme.allOperators;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.builtinFunctions, section))
            {
                colour = theme.builtinFunctions;
            }
            else if (CompilerSymbols.brackets.Contains(section.ToLower()))
            {
                colour = theme.brackets;
            }
            else if (float.TryParse(section.Replace('.', ','), out _))
            {
                colour = theme.value;
            }
            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);
    }
Пример #4
0
    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);
    }