/// <summary>
        /// Recursive exp
        /// </summary>
        /// <param name="expressions">Expressions</param>
        /// <param name="lastToken">Last token</param>
        /// <param name="pLevel">Parenthesis level</param>
        /// <param name="actualBlock">Actual block</param>
        /// <returns>New expressions</returns>
        List<IExpression> RecursiveExp(List<IExpression> expressions, Token lastToken, int pLevel, Block actualBlock)
        {
            if (pLevel < 0 || !HasNextToken())
                return expressions;

            Token actualToken = Peek();

            bool restart = true;

            switch (lastToken.Type)
            {
                case TokenType.IDENTIFIER:
                    switch (actualToken.Type)
                    {
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                        case TokenType.DOT:
                        case TokenType.CLOSEPAREN:
                            actualToken = Pop();
                            expressions.Add(new VariableExpression(lastToken.Value, actualBlock));
                            break;
                        case TokenType.OPENPAREN:
                            actualToken = Pop();
                            List<List<IExpression>> exps = new List<List<IExpression>>();
                            while (!Match(TokenType.CLOSEPAREN))
                            {
                                exps.Add(Exp(actualBlock));
                                if (Match(TokenType.CLOSEPAREN))
                                    break;
                                else if (!Match(TokenType.COMMA))
                                    Logger.Error("Parameter need to be separated with a comma");
                                Pop(); // Pop the comma
                            }
                            expressions.Add(new MethodCallExpression(lastToken.Value, actualBlock, exps));
                            break;
                        default:
                            expressions.Add(new VariableExpression(lastToken.Value, actualBlock));
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.NEW:
                    switch (actualToken.Type)
                    {
                        case TokenType.IDENTIFIER:
                            Token customTypeToken = Pop();
                            List<List<IExpression>> exps = new List<List<IExpression>>();
                            if (Match(TokenType.OPENPAREN))
                            {
                                Pop(); // Pop the parenthesis
                                while (!Match(TokenType.CLOSEPAREN))
                                {
                                    exps.Add(Exp(actualBlock));
                                    if (Match(TokenType.COMMA))
                                    {
                                        Pop(); // Pop the comma
                                        continue;
                                    }
                                    else
                                        break;
                                }
                            }
                            else
                                Logger.Error("You need to open parenthesis after object instantation.");

                            if (!Match(TokenType.CLOSEPAREN))
                                Logger.Error("You need to close parenthesis after put parameters");

                            actualToken = Pop(); // Pop the parenthesis
                            expressions.Add(new ConstructorExpression(customTypeToken.Value, actualBlock, exps));
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.DOT:
                    switch (actualToken.Type)
                    {
                        case TokenType.IDENTIFIER:
                        case TokenType.CLOSEPAREN:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.COMMA:
                    restart = false;
                    break;

                case TokenType.PLUS:
                case TokenType.MINUS:
                case TokenType.MULTIPLY:
                case TokenType.DIVIDE:
                    switch (actualToken.Type)
                    {
                        case TokenType.IDENTIFIER:
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.INTLITERAL:
                        case TokenType.FLOATLITERAL:
                        case TokenType.STRINGLITERAL:
                        case TokenType.EXMARK:
                        case TokenType.OPENPAREN:
                            actualToken = Pop();
                            expressions.Add(new OperatorExpression(lastToken.Type));
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.STRINGLITERAL:
                    expressions.Add(new Value(VariableType.STRING, lastToken.Value));
                    switch (actualToken.Type)
                    {
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.BOOLLITERAL:
                    expressions.Add(new Value(VariableType.BOOL, lastToken.Value == Language.Keywords["true"] ? true : false));
                    switch (actualToken.Type)
                    {
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.INTLITERAL:
                    expressions.Add(new Value(VariableType.INT, Convert.ToInt32(lastToken.Value)));
                    switch (actualToken.Type)
                    {
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                        case TokenType.CLOSEPAREN:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.FLOATLITERAL:
                    expressions.Add(new Value(VariableType.FLOAT, Conv.StringToFloat(lastToken.Value)));
                    switch (actualToken.Type)
                    {
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                        case TokenType.CLOSEPAREN:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.EXMARK:
                    switch (actualToken.Type)
                    {
                        case TokenType.IDENTIFIER:
                        case TokenType.BOOLLITERAL:
                        case TokenType.OPENPAREN:
                            actualToken = Pop();
                            expressions.Add(new OperatorExpression(lastToken.Type));
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.OPENPAREN:
                    pLevel++;
                    expressions.Add(new OperatorExpression(lastToken.Type));
                    switch (actualToken.Type)
                    {
                        case TokenType.IDENTIFIER:
                        case TokenType.PLUS:
                        case TokenType.MINUS:
                        case TokenType.MULTIPLY:
                        case TokenType.DIVIDE:
                        case TokenType.EXMARK:
                        case TokenType.BOOLLITERAL:
                        case TokenType.STRINGLITERAL:
                        case TokenType.INTLITERAL:
                        case TokenType.FLOATLITERAL:
                        case TokenType.OPENPAREN:
                        case TokenType.CLOSEPAREN:
                            actualToken = Pop();
                            break;
                        default:
                            restart = false;
                            break;
                    }
                    break;

                case TokenType.CLOSEPAREN:
                    if (pLevel > 0)
                    {
                        pLevel--;
                        expressions.Add(new OperatorExpression(lastToken.Type));
                        switch (actualToken.Type)
                        {
                            case TokenType.PLUS:
                            case TokenType.MINUS:
                            case TokenType.MULTIPLY:
                            case TokenType.DIVIDE:
                            case TokenType.CLOSEPAREN:
                                actualToken = Pop();
                                break;
                            default:
                                restart = false;
                                break;
                        }
                    }
                    else
                    {
                        Push(lastToken);
                        restart = false;
                    }
                    break;

                default:
                    restart = false;
                    break;

            }

            if (restart)
                return RecursiveExp(expressions, actualToken, pLevel, actualBlock);
            else
                return expressions;
        }
 /// <summary>
 /// Push a token
 /// </summary>
 /// <param name="token">Token to push</param>
 void Push(Token token)
 {
     Tokens.Push(token);
 }