예제 #1
0
        public static void Run()
        {
            Console.WriteLine("Converting ox emoji to UTF-16 and UTF-8");
            Rune rune = Rune.GetRuneAt("🐂", 0);

            Console.WriteLine($"Rune value: {rune.Value}");

            // <SnippetUtf16CharArray>
            char[] chars           = new char[rune.Utf16SequenceLength];
            int    numCharsWritten = rune.EncodeToUtf16(chars);

            // </SnippetUtf16CharArray>

            Console.WriteLine($"Number of chars: {numCharsWritten}");

            // <SnippetUtf16String>
            string theString = rune.ToString();

            // </SnippetUtf16String>

            // <SnippetUtf8ByteArray>
            byte[] bytes           = new byte[rune.Utf8SequenceLength];
            int    numBytesWritten = rune.EncodeToUtf8(bytes);

            // </SnippetUtf8ByteArray>

            Console.WriteLine($"Number of UTF-8 bytes: {numBytesWritten}");
        }
예제 #2
0
        public static void TryEncodeToUtf16(GeneralTestData testData)
        {
            Rune rune = new Rune(testData.ScalarValue);

            Assert.Equal(testData.Utf16Sequence.Length, rune.Utf16SequenceLength);

            // First, try with a buffer that's too short

            Span <char> utf16Buffer = stackalloc char[rune.Utf16SequenceLength - 1];
            bool        success     = rune.TryEncodeToUtf16(utf16Buffer, out int charsWritten);

            Assert.False(success);
            Assert.Equal(0, charsWritten);

            Assert.Throws <ArgumentException>("destination", () => rune.EncodeToUtf16(new char[rune.Utf16SequenceLength - 1]));

            // Then, try with a buffer that's appropriately sized

            utf16Buffer = stackalloc char[rune.Utf16SequenceLength];
            success     = rune.TryEncodeToUtf16(utf16Buffer, out charsWritten);
            Assert.True(success);
            Assert.Equal(testData.Utf16Sequence.Length, charsWritten);
            Assert.True(utf16Buffer.SequenceEqual(testData.Utf16Sequence));

            utf16Buffer.Clear();
            Assert.Equal(testData.Utf16Sequence.Length, rune.EncodeToUtf16(utf16Buffer));
            Assert.True(utf16Buffer.SequenceEqual(testData.Utf16Sequence));

            // Finally, try with a buffer that's too long (should succeed)

            utf16Buffer = stackalloc char[rune.Utf16SequenceLength + 1];
            success     = rune.TryEncodeToUtf16(utf16Buffer, out charsWritten);
            Assert.True(success);
            Assert.Equal(testData.Utf16Sequence.Length, charsWritten);
            Assert.True(utf16Buffer.Slice(0, testData.Utf16Sequence.Length).SequenceEqual(testData.Utf16Sequence));

            utf16Buffer.Clear();
            Assert.Equal(testData.Utf16Sequence.Length, rune.EncodeToUtf16(utf16Buffer));
            Assert.True(utf16Buffer.Slice(0, testData.Utf16Sequence.Length).SequenceEqual(testData.Utf16Sequence));
        }
예제 #3
0
        /// <summary>
        /// Get the <see cref="Char"/> representation of this <see cref="Rune"/>.
        /// </summary>
        /// <param name="rune">The <see cref="Rune"/> to convert.</param>
        /// <returns>An <see cref="Array"/> of zero to two <see cref="Char"/> representing this <paramref name="rune"/>. <see cref="Array.Empty{T}"/> signifies an invalid conversion.</returns>
        /// <exception cref="InvalidOperationException">There was an issue with the internal buffers.</exception>
        public static Char[] AsChars(this Rune rune)
        {
            Char[]      chars = new Char[2];
            Span <Char> span;

            try {
                span = new Span <Char>(chars);
            } catch (ArrayTypeMismatchException ex) {
                throw new InvalidOperationException("There was an issue with the internal buffers.", ex);
            }
            switch (rune.EncodeToUtf16(span))
            {
            case 1:
                return(new[] { chars[0] });

            case 2:
                return(chars);

            default:
                return(Array.Empty <Char>());
            }
        }
예제 #4
0
    private static void AddAstNodeToTree(ES_AstNode node, TreeViewItem parentItem)
    {
        if (node == null)
        {
            return;
        }

        switch (node)
        {
        case ES_AstNamespace namespaceDef: {
            var thisItem = AddNodeToTree($"Namespace \"{namespaceDef.NamespaceName}\"", parentItem);
            thisItem.Tag = namespaceDef.NamespaceName;

            foreach (var content in namespaceDef.Contents)
            {
                AddAstNodeToTree(content, thisItem);
            }
            break;
        }

            #region Aggregates

        case ES_AstClassDefinition classDef: {
            var thisItem = AddNodeToTree($"Class \"{classDef.Name.Text}\"", parentItem);
            thisItem.Tag = classDef.Name;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(classDef.AccessModifier.ToString(), modifiersList);
            if (classDef.Static)
            {
                AddNodeToTree("Static", modifiersList);
            }

            if (classDef.InheritanceList != null && classDef.InheritanceList.Length > 0)
            {
                var inheritanceList = AddNodeToTree("Inheritance list", thisItem);

                foreach (var type in classDef.InheritanceList)
                {
                    var typeItem = AddNodeToTree(type.ToString(), inheritanceList);
                    typeItem.Tag = type;
                }
            }

            if (classDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = classDef.DocComment.Value;
                AddNodeToTree(classDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            if (classDef.Contents != null && classDef.Contents.Length > 0)
            {
                var contentsList = AddNodeToTree("Contents", thisItem);

                foreach (var childNode in classDef.Contents)
                {
                    AddAstNodeToTree(childNode, contentsList);
                }
            }
            break;
        }

        case ES_AstStructDefinition structDef: {
            var thisItem = AddNodeToTree($"Struct \"{structDef.Name.Text}\"", parentItem);
            thisItem.Tag = structDef.Name;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(structDef.AccessModifier.ToString(), modifiersList);

            if (structDef.InterfacesList != null && structDef.InterfacesList.Length > 0)
            {
                var inheritanceList = AddNodeToTree("Interfaces list", thisItem);

                foreach (var type in structDef.InterfacesList)
                {
                    var typeItem = AddNodeToTree(type.ToString(), inheritanceList);
                    typeItem.Tag = type;
                }
            }

            if (structDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = structDef.DocComment.Value;
                AddNodeToTree(structDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            if (structDef.Contents != null && structDef.Contents.Length > 0)
            {
                var contentsList = AddNodeToTree("Contents", thisItem);

                foreach (var childNode in structDef.Contents)
                {
                    AddAstNodeToTree(childNode, contentsList);
                }
            }
            break;
        }

        case ES_AstMemberVarDefinition memberVarDef: {
            var thisItem = AddNodeToTree($"Field {memberVarDef.Name.Text} ({memberVarDef.ValueType})", parentItem);
            thisItem.Tag = memberVarDef.Name;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(memberVarDef.AccessModifier.ToString(), modifiersList);
            if (memberVarDef.Static)
            {
                AddNodeToTree("Static", modifiersList);
            }

            if (memberVarDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = memberVarDef.DocComment.Value;
                AddNodeToTree(memberVarDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            if (memberVarDef.InitializationExpression != null)
            {
                var initializer = AddNodeToTree("Initialization expression", thisItem);

                AddAstNodeToTree(memberVarDef.InitializationExpression, initializer);
            }

            break;
        }

        case ES_AstConstructorDefinition consDef: {
            var thisItem = AddNodeToTree(!consDef.Static ? "Constructor" : "Static constructor", parentItem);
            thisItem.Tag = consDef.ThisToken;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(consDef.AccessModifier.ToString(), modifiersList);

            if (consDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = consDef.DocComment.Value;
                AddNodeToTree(consDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            var argsList   = AddNodeToTree("Arguments list", thisItem);
            var statements = AddNodeToTree("Body", thisItem);

            AddArgumentsListToTree(consDef.ArgumentsList, argsList);

            var curStatement = consDef.Statement;
            while (curStatement is not null)
            {
                AddAstNodeToTree(curStatement, statements);

                curStatement = curStatement.Endpoint;
            }

            break;
        }

            #endregion

        case ES_AstEnumDefinition enumDef: {
            TreeViewItem thisItem;
            if (enumDef.BaseType == null)
            {
                thisItem = AddNodeToTree($"Enum {enumDef.Name.Text}", parentItem);
            }
            else
            {
                thisItem = AddNodeToTree($"Enum {enumDef.Name.Text} ({enumDef.BaseType.Value})", parentItem);
            }

            thisItem.Tag = enumDef.Name;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(enumDef.AccessModifier.ToString(), modifiersList);

            if (enumDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = enumDef.DocComment.Value;
                AddNodeToTree(enumDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            var membersList = AddNodeToTree("Members", thisItem);
            if (enumDef.MembersList != null)
            {
                foreach (var member in enumDef.MembersList)
                {
                    var memberItem = AddNodeToTree(member.Item1.Text.ToString(), membersList);
                    memberItem.Tag = member.Item1;
                    if (member.Item2 != null)
                    {
                        AddAstNodeToTree(member.Item2, memberItem);
                    }
                }
            }

            break;
        }

        case ES_AstFunctionDefinition funcDef: {
            var thisItem = AddNodeToTree($"Function {funcDef.Name.Text} ({funcDef.ReturnType})", parentItem);
            thisItem.Tag = funcDef.Name;

            var modifiersList = AddNodeToTree("Access modifiers", thisItem);
            AddNodeToTree(funcDef.AccessModifier.ToString(), modifiersList);
            if (funcDef.Static)
            {
                AddNodeToTree("Static", modifiersList);
            }
            if (funcDef.Const)
            {
                AddNodeToTree("Const", modifiersList);
            }

            if (funcDef.DocComment != null)
            {
                var docComNode = AddNodeToTree("Documentation comment", thisItem);
                docComNode.Tag = funcDef.DocComment.Value;
                AddNodeToTree(funcDef.DocComment.Value.Text.Span.ToString(), docComNode);
            }

            var argsList   = AddNodeToTree("Arguments list", thisItem);
            var statements = AddNodeToTree("Body", thisItem);

            AddArgumentsListToTree(funcDef.ArgumentsList, argsList);

            var curStatement = funcDef.Statement;
            while (curStatement is not null)
            {
                AddAstNodeToTree(curStatement, statements);

                curStatement = curStatement.Endpoint;
            }

            break;
        }

            #region Statements

        case ES_AstEmptyErrorExpression: {
            AddNodeToTree("Empty (error) statement", parentItem);
            break;
        }

        case ES_AstEmptyErrorStatement: {
            AddNodeToTree("Empty (error) statement", parentItem);
            break;
        }

        case ES_AstLabeledStatement labeledStatement: {
            var thisItem = AddNodeToTree($"Label \"{labeledStatement.LabelName.Text}\":", parentItem);
            thisItem.Tag = labeledStatement.LabelName;
            break;
        }

        case ES_AstBlockStatement blockStatement: {
            var thisItem = AddNodeToTree("Statement block", parentItem);

            var curStatement = blockStatement.Statement;
            while (curStatement != null)
            {
                AddAstNodeToTree(curStatement, thisItem);
                curStatement = curStatement.Endpoint;
            }
            break;
        }

        case ES_AstEmptyStatement emptyStatement: {
            AddNodeToTree("Empty statement", parentItem);
            break;
        }

            #region Symbol definition

        case ES_AstTypeAlias alias: {
            var thisItem = AddNodeToTree($"Type alias {alias.AliasName.Text} = {alias.OriginalName}", parentItem);
            thisItem.Tag = alias.AliasName;
            break;
        }

        case ES_AstImportStatement importStatement: {
            var thisItem = AddNodeToTree($"Import {importStatement.NamespaceName}", parentItem);
            thisItem.Tag = importStatement.NamespaceName;

            if (importStatement.ImportedNames != null && importStatement.ImportedNames.Length > 0)
            {
                foreach (var symbol in importStatement.ImportedNames)
                {
                    AddNodeToTree(symbol.Text.ToString(), thisItem);
                }
            }

            break;
        }

        case ES_AstLocalVarDefinition localVarDefStatement: {
            if (localVarDefStatement.Variables == null)
            {
                break;
            }

            var baseText = $"{(localVarDefStatement.UsingVar ? "using " : "")}{localVarDefStatement.ValueType?.ToString () ?? "var"}";
            foreach (var variable in localVarDefStatement.Variables)
            {
                var exprText = variable.InitializationExpression != null ? " = [...]" : "";

                var varNode = AddNodeToTree($"{baseText} {variable.Name}{exprText}", parentItem);
                varNode.Tag = variable.Name;

                AddAstNodeToTree(variable.InitializationExpression, varNode);
            }

            break;
        }

            #endregion

            #region Jumps

        case ES_AstConditionalStatement condStatement: {
            var thisItem = AddNodeToTree("if (...)", parentItem);

            var conditionItem = AddNodeToTree("Condition", thisItem);
            var thenItem      = AddNodeToTree("Then", thisItem);

            AddAstNodeToTree(condStatement.ConditionExpression, conditionItem);
            AddAstNodeToTree(condStatement.ThenStatement, thenItem);

            if (condStatement.ElseStatement != null)
            {
                var elseItem = AddNodeToTree("Else", thisItem);
                AddAstNodeToTree(condStatement.ElseStatement, elseItem);
            }

            break;
        }

        case ES_AstSwitchStatement switchStatement: {
            var thisItem = AddNodeToTree("switch (...) [NOT IMPLEMENTED]", parentItem);

            break;
        }

        case ES_AstBreakStatement breakStatement: {
            var itemText = breakStatement.LabelName != null ? "break" : $"break {breakStatement.LabelName}";
            var thisItem = AddNodeToTree(itemText, parentItem);
            if (breakStatement.LabelName != null)
            {
                thisItem.Tag = breakStatement.LabelName;
            }

            break;
        }

        case ES_AstContinueStatement continueStatement: {
            var itemText = continueStatement.LabelName != null ? "continue" : $"continue {continueStatement.LabelName}";
            var thisItem = AddNodeToTree(itemText, parentItem);
            if (continueStatement.LabelName != null)
            {
                thisItem.Tag = continueStatement.LabelName;
            }

            break;
        }

        case ES_AstGotoLabelStatement gotoLabelStatement: {
            var thisItem = AddNodeToTree($"goto {gotoLabelStatement.LabelName}", parentItem);
            thisItem.Tag = gotoLabelStatement.LabelName;

            break;
        }

        case ES_AstGotoCaseStatement gotoCaseStatement: {
            var thisItem = AddNodeToTree(gotoCaseStatement.CaseExpression != null ? "goto case (...)" : "goto default", parentItem);
            AddAstNodeToTree(gotoCaseStatement.CaseExpression, thisItem);

            break;
        }

        case ES_AstReturnStatement returnStatement: {
            var thisItem = AddNodeToTree(returnStatement.ReturnExpression != null ? "return (...)" : "return", parentItem);
            AddAstNodeToTree(returnStatement.ReturnExpression, thisItem);

            break;
        }

            #endregion

            #region Loops

        case ES_AstLoopStatement loopStatement: {
            string itemString;
            var    forLoop = false;

            if (
                loopStatement.InitializationStatement != null ||
                loopStatement.ConditionExpression == null ||
                loopStatement.IterationExpressions != null
                )
            {
                var initString = loopStatement.InitializationStatement != null ? "..." : "";
                var condString = loopStatement.ConditionExpression != null ? " ..." : "";
                var iterString = loopStatement.IterationExpressions != null ? " ..." : "";

                itemString = $"{(loopStatement.PostLoop ? "do-" : "")}for ({initString};{condString};{iterString})";
                forLoop    = true;
            }
            else
            {
                itemString = $"{(loopStatement.PostLoop ? "do-" : "")}while (...)";
            }

            var thisItem = AddNodeToTree(itemString, parentItem);

            if (forLoop)
            {
                if (loopStatement.InitializationStatement != null)
                {
                    var initItem = AddNodeToTree("Initialization", thisItem);
                    AddAstNodeToTree(loopStatement.InitializationStatement, initItem);
                }

                if (loopStatement.ConditionExpression != null)
                {
                    var condItem = AddNodeToTree("Condition", thisItem);
                    AddAstNodeToTree(loopStatement.ConditionExpression, condItem);
                }

                if (loopStatement.IterationExpressions != null)
                {
                    var iterItem = AddNodeToTree("Iteration", thisItem);

                    foreach (var expr in loopStatement.IterationExpressions)
                    {
                        AddAstNodeToTree(expr, iterItem);
                    }
                }
            }
            else
            {
                var condItem = AddNodeToTree("Condition", thisItem);
                AddAstNodeToTree(loopStatement.ConditionExpression, condItem);
            }

            var bodyItem = AddNodeToTree("Body", thisItem);
            AddAstNodeToTree(loopStatement.LoopBody, bodyItem);

            break;
        }

            #endregion

        case ES_AstExpressionStatement exprStatement: {
            AddAstNodeToTree(exprStatement.Expression, parentItem);
            break;
        }

            #endregion

            #region Expressions

            #region Primary expressions

        case ES_AstParenthesisExpression parenthesisExpr: {
            var thisItem = AddNodeToTree($"()", parentItem);
            AddAstNodeToTree(parenthesisExpr.Inner, thisItem);
            break;
        }

        case ES_AstIntegerLiteralExpression intLiteralExpr: {
            var signSuffix = string.Empty;
            if (intLiteralExpr.Signed is not null)
            {
                signSuffix = intLiteralExpr.Signed == true ? "s" : "u";
            }

            var sizeSuffix = intLiteralExpr.Size switch {
                ES_IntSize.Int8 => "8",
                ES_IntSize.Int16 => "16",
                ES_IntSize.Int32 => "32",
                ES_IntSize.Int64 => "64",

                null => string.Empty,

                _ => throw new NotImplementedException(),
            };

            var thisItem = AddNodeToTree($"Int literal {intLiteralExpr.Value}{signSuffix}{sizeSuffix}", parentItem);
            thisItem.Tag = intLiteralExpr.Token;

            break;
        }

        case ES_AstBooleanLiteralExpression boolLiteralExpr: {
            var thisItem = AddNodeToTree($"{boolLiteralExpr.Value}", parentItem);
            thisItem.Tag = boolLiteralExpr.Token;

            break;
        }

        case ES_AstFloatLiteralExpression floatLiteralExpr: {
            string nodeText;
            if (floatLiteralExpr.IsFloat)
            {
                nodeText = $"Float literal {floatLiteralExpr.ValueFloat}f";
            }
            else
            {
                nodeText = $"Float literal {floatLiteralExpr.ValueDouble}d";
            }

            var thisItem = AddNodeToTree(nodeText, parentItem);
            thisItem.Tag = floatLiteralExpr.Token;

            break;
        }

        case ES_AstStringLiteralExpression strLiteralExpr: {
            string nodeText;
            if (!strLiteralExpr.Verbatim)
            {
                nodeText = $"String literal \"{strLiteralExpr.ValueUTF16}\"";
            }
            else
            {
                nodeText = $"Verbatim string literal \"{strLiteralExpr.ValueUTF16}\"";
            }

            var thisItem = AddNodeToTree(nodeText, parentItem);
            thisItem.Tag = strLiteralExpr.Token;

            break;
        }

        case ES_AstCharLiteralExpression charLiteralExpr: {
            Span <char> charBuf = stackalloc char [2];

            var rune = new Rune(charLiteralExpr.Value);
            rune.EncodeToUtf16(charBuf);

            var thisItem = AddNodeToTree($"Char literal '{charBuf.ToString ()}'", parentItem);
            thisItem.Tag = charLiteralExpr.Token;

            break;
        }

        case ES_AstNullLiteralExpression nullLiteralExpr: {
            var thisItem = AddNodeToTree("Null", parentItem);
            thisItem.Tag = nullLiteralExpr.Token;

            break;
        }

        case ES_AstNameExpression nameExpr: {
            var thisItem = AddNodeToTree($"Name \"{nameExpr.Value.Text}\"", parentItem);
            thisItem.Tag = nameExpr.Value;
            break;
        }

        case ES_AstMemberAccessExpression memberAccessExpr: {
            var thisItem = AddNodeToTree("Member access", parentItem);
            AddAstNodeToTree(memberAccessExpr.Parent, thisItem);
            if (memberAccessExpr.Member is not null)
            {
                AddNodeToTree(memberAccessExpr.Member.Value.Text.Span.GetPooledString(), thisItem);
            }
            else
            {
                AddNodeToTree("[NULL]", thisItem);
            }

            break;
        }

        case ES_AstFunctionCallExpression funcCallExpr: {
            var thisItem = AddNodeToTree("Function call", parentItem);
            var funcExpr = AddNodeToTree("Expression", thisItem);
            var argsList = AddNodeToTree("Arguments", thisItem);

            AddAstNodeToTree(funcCallExpr.FunctionExpression, funcExpr);
            AddArgumentsListToTree(funcCallExpr.Arguments, argsList);

            break;
        }

        case ES_AstIndexingExpression indexingExpr: {
            var thisItem    = AddNodeToTree("Indexing", parentItem);
            var indexedExpr = AddNodeToTree("Expression", thisItem);
            var ranksList   = AddNodeToTree("Ranks", thisItem);

            AddAstNodeToTree(indexingExpr.IndexedExpression, indexedExpr);
            foreach (var rank in indexingExpr.RankExpressions)
            {
                AddAstNodeToTree(rank, ranksList);
            }

            break;
        }

        case ES_AstNewObjectExpression newObjExpr: {
            string thisItemText;

            if (newObjExpr.Arguments.Length < 1)
            {
                thisItemText = $"new {newObjExpr.TypeDeclaration} ()";
            }
            else
            {
                thisItemText = $"new {newObjExpr.TypeDeclaration} ([...])";
            }

            var thisItem = AddNodeToTree(thisItemText, parentItem);
            AddArgumentsListToTree(newObjExpr.Arguments, thisItem);

            break;
        }

        case ES_AstNewArrayExpression newArrayExpr: {
            string thisItemText;

            thisItemText = $"new {newArrayExpr.ElementType} []";

            var thisItem = AddNodeToTree(thisItemText, parentItem);

            foreach (var rank in newArrayExpr.Ranks)
            {
                AddAstNodeToTree(rank, thisItem);
            }

            break;
        }

            #endregion

        case ES_AstIncDecExpression incDecExpr: {
            var sideText = incDecExpr.Postfix ? "Postfix" : "Prefix";
            var opText   = !incDecExpr.Decrement ? "Increment" : "Decrement";
            var thisItem = AddNodeToTree($"{sideText} {opText}", parentItem);
            AddAstNodeToTree(incDecExpr.Inner, thisItem);

            break;
        }

            #region Unary expressions

        case ES_AstSimpleUnaryExpression simpleUnaryExpr: {
            var opText = simpleUnaryExpr.ExpressionType switch {
                SimpleUnaryExprType.Positive => "Positive",
                SimpleUnaryExprType.Negative => "Negative",
                SimpleUnaryExprType.LogicalNot => "Logical NOT",
                SimpleUnaryExprType.BitNot => "Bitwise NOT",
                SimpleUnaryExprType.Dereference => "Dereference",

                _ => throw new NotImplementedException(),
            };
            var thisItem = AddNodeToTree(opText, parentItem);
            AddAstNodeToTree(simpleUnaryExpr.Inner, thisItem);

            break;
        }

        case ES_AstCastExpression castExpr: {
            var thisItem = AddNodeToTree($"Cast ({castExpr.DestinationType})", parentItem);
            AddAstNodeToTree(castExpr.InnerExpression, thisItem);

            break;
        }

            #endregion

        case ES_AstSimpleBinaryExpression simpleBinaryExpr: {
            var opText = simpleBinaryExpr.ExpressionType switch {
                SimpleBinaryExprType.Concatenation => "Concatenation",

                SimpleBinaryExprType.Power => "Exponentiation",

                SimpleBinaryExprType.Multiply => "Multiplication",
                SimpleBinaryExprType.Divide => "Division",
                SimpleBinaryExprType.Modulo => "Modulo",

                SimpleBinaryExprType.Add => "Addition",
                SimpleBinaryExprType.Subtract => "Subtraction",

                SimpleBinaryExprType.ShiftLeft => "Bitshift left",
                SimpleBinaryExprType.ShiftRight => "Bitshift right",
                SimpleBinaryExprType.ShiftRightUnsigned => "Bitshift right unsigned",

                SimpleBinaryExprType.LesserThan => "Lesser than",
                SimpleBinaryExprType.GreaterThan => "Greater than",
                SimpleBinaryExprType.LesserThanEqual => "Lesser than or equals",
                SimpleBinaryExprType.GreaterThanEqual => "Greater than or equals",

                SimpleBinaryExprType.Equals => "Equals",
                SimpleBinaryExprType.NotEquals => "Not equals",

                SimpleBinaryExprType.BitAnd => "Bitwise AND",
                SimpleBinaryExprType.BitXor => "Bitwise XOR",
                SimpleBinaryExprType.BitOr => "Bitwise OR",

                SimpleBinaryExprType.LogicalAnd => "Logical AND",
                SimpleBinaryExprType.LogicalOr => "Logical OR",

                #region Assignment

                SimpleBinaryExprType.Assign => "Assignment",

                SimpleBinaryExprType.AssignAdd => "Assign-Addition",
                SimpleBinaryExprType.AssignSubtract => "Assign-Subtraction",

                SimpleBinaryExprType.AssignMultiply => "Assign-Multiplication",
                SimpleBinaryExprType.AssignDivide => "Assign-Division",
                SimpleBinaryExprType.AssignModulo => "Assign-Modulo",
                SimpleBinaryExprType.AssignPower => "Assign-Exponentiation",

                SimpleBinaryExprType.AssignBitAnd => "Assign-Bitwise AND",
                SimpleBinaryExprType.AssignBitOr => "Assign-Bitwise OR",
                SimpleBinaryExprType.AssignXor => "Assign-Bitwise XOR",

                SimpleBinaryExprType.AssignConcatenate => "Assign-Concatenation",

                SimpleBinaryExprType.AssignShiftLeft => "Assign-Shift left",
                SimpleBinaryExprType.AssignShiftRight => "Assign-Shift right",
                SimpleBinaryExprType.AssignShiftRightUnsigned => "Assign-Shift right unsigned",

                #endregion

                _ => throw new NotImplementedException(),
            };
            var thisItem = AddNodeToTree(opText, parentItem);
            AddAstNodeToTree(simpleBinaryExpr.Left, thisItem);
            AddAstNodeToTree(simpleBinaryExpr.Right, thisItem);

            break;
        }

            #endregion

        case ES_AstConditionalExpression condExpr: {
            var thisItem = AddNodeToTree($"?:", parentItem);

            var condItem = AddNodeToTree($"Condition", thisItem);
            var thenItem = AddNodeToTree($"Then", thisItem);
            var elseItem = AddNodeToTree($"Else", thisItem);

            AddAstNodeToTree(condExpr.Condition, condItem);
            AddAstNodeToTree(condExpr.Then, thenItem);
            AddAstNodeToTree(condExpr.Else, elseItem);

            break;
        }

        default:
            throw new NotImplementedException();
        }
    }