private void TreatWhileStatement(CSharpParser.WhileStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a do statement:
            IToken whileToken = statement.WHILE().Symbol;
            Node   whileNode  = new Node(whileToken, Node.Kind.DoStatement, null);

            ast.AddNode(whileNode);
            int whileIndex = ast.NodeIndex(whileNode);

            parentNode.AddChildIndex(whileIndex);

            symbolTable.EnterScope(whileIndex);

            // Creating sub tree for the condition expression:
            beginTreatExpression(statement.expression(), whileNode);

            // Craeting sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, whileNode);
            }
            else
            {
                TreatBlock(embedded.block(), whileNode);
            }

            symbolTable.ExitScope();
        }
 private void TreatSimpleEmbeddedStatement(CSharpParser.Simple_embedded_statementContext context, Node parentNode)
 {
     if (context is CSharpParser.IfStatementContext)
     {
         TreatIfStatement((CSharpParser.IfStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.SwitchStatementContext)
     {
         TreatSwitchStatement((CSharpParser.SwitchStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.DoStatementContext)
     {
         TreatDoStatement((CSharpParser.DoStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.WhileStatementContext)
     {
         TreatWhileStatement((CSharpParser.WhileStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.ForStatementContext)
     {
         TreatForStatement((CSharpParser.ForStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.ForeachStatementContext)
     {
         TreatForeachStatement((CSharpParser.ForeachStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.BreakStatementContext)
     {
         TreatBreakStatement((CSharpParser.BreakStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.ContinueStatementContext)
     {
         TreatContinueStatement((CSharpParser.ContinueStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.GotoStatementContext)
     {
         TreatGoToStatement((CSharpParser.GotoStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.ReturnStatementContext)
     {
         TreatReturnStatement((CSharpParser.ReturnStatementContext)context, parentNode);
     }
     else if (context is CSharpParser.ExpressionStatementContext)
     {
         CSharpParser.ExpressionStatementContext expr = (CSharpParser.ExpressionStatementContext)context;
         beginTreatExpression(expr.expression(), parentNode);
     }
     else
     {
         Console.WriteLine("FATAL ERROR: Could not define the type of simple_embedded_statement rule.");
         Environment.Exit(1);
     }
 }
        private void TreatForeachStatement(CSharpParser.ForeachStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a foreach statement:
            IToken foreachToken = statement.FOREACH().Symbol;
            Node   foreachNode  = new Node(foreachToken, Node.Kind.ForeachStatement, null);

            ast.AddNode(foreachNode);
            int foreachIndex = ast.NodeIndex(foreachNode);

            parentNode.AddChildIndex(foreachIndex);

            symbolTable.EnterScope(foreachIndex);

            // Creating sub tree for the variable creation in the iterator:
            Type   t              = symbolTable.FindType(statement.local_variable_type().type_().Stop);
            IToken idToken        = statement.identifier().Start;
            Symbol iteratorSymbol = new Symbol(Symbol.ModifierFlag.None);

            symbolTable.AddSymbol(idToken, iteratorSymbol);
            Node iteratorNode = new Node(idToken, Node.Kind.IteratorDeclaration, t, iteratorSymbol);

            ast.AddNode(iteratorNode);
            int iteratorIndex = ast.NodeIndex(iteratorNode);

            foreachNode.AddChildIndex(iteratorIndex);

            // Treat the expression that returns the iterable
            beginTreatExpression(statement.expression(), foreachNode);

            // Creating sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, foreachNode);
            }
            else
            {
                TreatBlock(embedded.block(), foreachNode);
            }

            symbolTable.ExitScope();
        }
        private void TreatForStatement(CSharpParser.ForStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a for statement:
            IToken forToken = statement.FOR().Symbol;
            Node   forNode  = new Node(forToken, Node.Kind.ForStatement, null);

            ast.AddNode(forNode);
            int forIndex = ast.NodeIndex(forNode);

            parentNode.AddChildIndex(forIndex);

            symbolTable.EnterScope(forIndex);

            // Craeting sub tree for the initializer expression:
            CSharpParser.For_initializerContext initContext = statement.for_initializer();
            if (initContext != null)
            {
                CSharpParser.Local_variable_declarationContext declContext = initContext.local_variable_declaration();
                if (declContext != null)
                {
                    // Getting the local variables modifiers:
                    Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None;
                    if (declContext.REF() != null)
                    {
                        modFlags |= Symbol.ModifierFlag.Ref;
                    }
                    if (declContext.READONLY() != null)
                    {
                        modFlags |= Symbol.ModifierFlag.ReadOnly;
                    }

                    // Creating the local variables symbols:
                    IToken typeToken = declContext.local_variable_type().Start;
                    Type   t         = symbolTable.FindType(typeToken);
                    if (t == null)
                    {
                        Console.WriteLine("FATAL ERROR: Unidentified type found.");
                        Environment.Exit(1);
                    }
                    MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast);
                    CSharpParser.Local_variable_declaratorContext[] declarators =
                        declContext.local_variable_declarator();
                    foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators)
                    {
                        // Creating the variable symbol:
                        CSharpParser.IdentifierContext identifier = declarator.identifier();
                        IToken         variableID     = identifier.Start;
                        VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod);
                        symbolTable.AddSymbol(variableID, variableSymbol);

                        // Creating the variable node and adding it to the AST:
                        Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t);
                        ast.AddNode(variableNode);
                        int varDeclIndex = ast.NodeIndex(variableNode);
                        parentNode.AddChildIndex(varDeclIndex);

                        // Treating the variable initialization:
                        TreatVariableInitializer(declarator.local_variable_initializer(), variableNode);
                    }
                }
                else
                {
                    CSharpParser.ExpressionContext[] initExpressions = initContext.expression();
                    foreach (CSharpParser.ExpressionContext expression in initExpressions)
                    {
                        beginTreatExpression(expression, forNode);
                    }
                }
            }

            // Creating sub tree for the condition expression:
            beginTreatExpression(statement.expression(), forNode);

            // Creating sub tree for the iterator:
            CSharpParser.For_iteratorContext iteratorContext = statement.for_iterator();
            if (iteratorContext != null)
            {
                CSharpParser.ExpressionContext[] expressions = iteratorContext.expression();
                foreach (CSharpParser.ExpressionContext expression in expressions)
                {
                    beginTreatExpression(expression, forNode);
                }
            }

            // Craeting sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, forNode);
            }
            else
            {
                TreatBlock(embedded.block(), forNode);
            }

            symbolTable.ExitScope();
        }
        private void TreatStatement(CSharpParser.StatementContext statement, Node parentNode)
        {
            CSharpParser.Labeled_StatementContext labeledStatement = statement.labeled_Statement();
            if (labeledStatement != null)
            {
                // Getting the label token:
                CSharpParser.IdentifierContext label = labeledStatement.identifier();
                IToken labelToken = label.Start;

                // Adding the label to the symbol table:
                Symbol labelSymbol = new Symbol(Symbol.ModifierFlag.None);
                symbolTable.AddSymbol(labelToken, labelSymbol);

                // Creating the label node and adding it to the AST:
                Node labelNode = new Node(labelToken, Node.Kind.Label, null);
                ast.AddNode(labelNode);
                int labelNodeIndex = ast.NodeIndex(labelNode);

                parentNode.AddChildIndex(labelNodeIndex);

                CSharpParser.StatementContext innerStatement = labeledStatement.statement();

                // Treating the labeled statement:
                TreatStatement(innerStatement, labelNode);
            }
            else
            {
                CSharpParser.DeclarationStatementContext declaration = statement.declarationStatement();
                if (declaration != null)
                {
                    CSharpParser.Local_variable_declarationContext localVariable = declaration.local_variable_declaration();
                    if (localVariable != null)
                    {
                        // Getting the local variables modifiers:
                        Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None;
                        if (localVariable.REF() != null)
                        {
                            modFlags |= Symbol.ModifierFlag.Ref;
                        }
                        if (localVariable.READONLY() != null)
                        {
                            modFlags |= Symbol.ModifierFlag.ReadOnly;
                        }

                        // Creating the local variables symbols:
                        IToken typeToken = localVariable.local_variable_type().Start;
                        Type   t         = symbolTable.FindType(typeToken);
                        if (t == null)
                        {
                            Console.WriteLine("FATAL ERROR: Unidentified type found.");
                            Environment.Exit(1);
                        }
                        MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast);
                        CSharpParser.Local_variable_declaratorContext[] declarators =
                            localVariable.local_variable_declarator();
                        foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators)
                        {
                            // Creating the variable symbol:
                            CSharpParser.IdentifierContext identifier = declarator.identifier();
                            IToken         variableID     = identifier.Start;
                            VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod);
                            symbolTable.AddSymbol(variableID, variableSymbol);

                            // Creating the variable node and adding it to the AST:
                            Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t);
                            ast.AddNode(variableNode);
                            int varDeclIndex = ast.NodeIndex(variableNode);
                            parentNode.AddChildIndex(varDeclIndex);

                            // Treating the variable initialization:
                            TreatVariableInitializer(declarator.local_variable_initializer(), variableNode);
                        }
                    }
                }
                else
                {
                    CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
                    CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
                    if (simpleStatement != null)
                    {
                        TreatSimpleEmbeddedStatement(simpleStatement, parentNode);
                    }
                    else
                    {
                        TreatBlock(embedded.block(), parentNode);
                    }
                }
            }
        }
        private void TreatIfStatement(CSharpParser.IfStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's an if statement:
            IToken ifToken = statement.IF().Symbol;
            Node   ifNode  = new Node(ifToken, Node.Kind.IfStatement, null);

            ast.AddNode(ifNode);
            int ifNodeIndex = ast.NodeIndex(ifNode);

            parentNode.AddChildIndex(ifNodeIndex);

            // Creating sub tree for the condition expression:
            beginTreatExpression(statement.expression(), ifNode);

            // Creating a node and a scope for the if body:
            Node ifBodyNode = new Node(null, Node.Kind.IfStatementBody, null);

            ast.AddNode(ifBodyNode);
            int ifBodyNodeIndex = ast.NodeIndex(ifBodyNode);

            ifNode.AddChildIndex(ifBodyNodeIndex);
            // The node with the statements will be a child of the if body node

            CSharpParser.If_bodyContext[] ifBodies = statement.if_body();
            // Treating the if statement body:
            CSharpParser.Simple_embedded_statementContext embedded = ifBodies[0].simple_embedded_statement();
            if (embedded != null)
            {
                TreatSimpleEmbeddedStatement(embedded, ifBodyNode);
            }
            else
            {
                TreatBlock(ifBodies[0].block(), ifBodyNode);
            }

            // Checking if there's an else statement:
            if (ifBodies.Length == 2)
            {
                // Creating the else statement node:
                IToken elseToken = statement.ELSE().Symbol;
                Node   elseNode  = new Node(elseToken, Node.Kind.ElseStatement, null);
                ast.AddNode(elseNode);
                int elseNodeIndex = ast.NodeIndex(elseNode);
                ifNode.AddChildIndex(elseNodeIndex);

                // Creating the else body node:
                Node elseBody = new Node(null, Node.Kind.ElseStatementBody, null);
                ast.AddNode(elseBody);
                int elseBodyIndex = ast.NodeIndex(elseBody);
                elseNode.AddChildIndex(elseBodyIndex);

                // Treating the else statement body:
                CSharpParser.Simple_embedded_statementContext elseEmbedded = ifBodies[1].simple_embedded_statement();
                if (elseEmbedded != null)
                {
                    TreatSimpleEmbeddedStatement(elseEmbedded, elseBody);
                }
                else
                {
                    TreatBlock(ifBodies[1].block(), elseBody);
                }
            }
        }