private void ValidarParametros(ItemTs procedure)
        {
            //Validar argumentos procedure

            var i = IndexAtual;

            var tipoParametros = new List <TipoParametro>();

            while (Tokens[i].Tipo != TipoToken.SimboloAbreParenteses)
            {
                if (Tokens[i].Tipo == TipoToken.Identificador)
                {
                    var parametro = TabelaDeSimbolos.Find(Tokens[i].Cadeia, EscopoStack.Peek());
                    tipoParametros.Add(parametro.Tipo == TipoItemTs.NumeroInteiro
                        ? TipoParametro.NumeroInteiro
                        : TipoParametro.NumeroReal);
                }

                i--;
            }

            if (tipoParametros.Count != procedure.Parametros.Count)
            {
                throw new CompiladorException($"Quantidade errada de parametros\nLinha: {Tokens[i].Linha}");
            }

            for (int j = 0; j < tipoParametros.Count - 1; j++)
            {
                if (tipoParametros[j] != procedure.Parametros[j].Tipo)
                {
                    throw new CompiladorException(
                              $"Parametro com tipo diferente do esperado, encontrou {tipoParametros[j].ToString()} mas esperava {procedure.Parametros[j].Tipo.ToString()}\nLinha: {Tokens[i].Linha}");
                }
            }
        }
        private void AddParametrosNaProcedure(ItemTs procedure)
        {
            var i = IndexAtual - 4;


            while (Tokens[i].Tipo != TipoToken.SimboloAbreParenteses)
            {
                if (Tokens[i].Tipo == TipoToken.Identificador)
                {
                    var indexTipoParametro = i;

                    while (Tokens[indexTipoParametro].Tipo != TipoToken.ReservadoInteger &&
                           Tokens[indexTipoParametro].Tipo != TipoToken.ReservadoReal)
                    {
                        indexTipoParametro++;
                    }

                    procedure.Parametros.Add(new Parametro
                    {
                        Cadeia = Tokens[i].Cadeia,
                        Tipo   = Tokens[indexTipoParametro].Tipo == TipoToken.ReservadoInteger
                            ? TipoParametro.NumeroInteiro
                            : TipoParametro.NumeroReal
                    });
                }

                i--;
            }
        }
 public void VerificarSeVariavelJaFoiDeclarada(ItemTs itemTs)
 {
     if (Simbolos.All(x => x.Key != itemTs.Escopo + ":" + itemTs.Cadeia))
     {
         throw new CompiladorException($"A variável {itemTs.Cadeia} não foi declarada\nLinha: {itemTs.Linha}");
     }
 }
        public void TryAddNewItem(ItemTs itemTs)
        {
            //Verifica se a variaveil já está na tabela de simbolos
            if (Simbolos.Any(x => x.Key == itemTs.Cadeia && x.Value.Escopo == itemTs.Escopo))
            {
                throw new CompiladorException($"A variável {itemTs.Cadeia} já foi declarada\nLinha: {itemTs.Linha}");
            }

            Simbolos.Add(itemTs.Escopo + ":" + itemTs.Cadeia, itemTs);
        }
        private void DcP()
        {
            CallStack.Push(nameof(DcP));

            if (Tokens[IndexAtual].Tipo == TipoToken.ReservadoProcedure)
            {
                IndexAtual++;
                if (Tokens[IndexAtual].Tipo == TipoToken.Identificador)
                {
                    var procedure = new ItemTs
                    {
                        Cadeia     = Tokens[IndexAtual].Cadeia,
                        Escopo     = EscopoStack.Peek(),
                        Tipo       = TipoItemTs.Procedimento,
                        Linha      = Tokens[IndexAtual].Linha,
                        Parametros = new List <Parametro>()
                    };

                    EscopoStack.Push(Tokens[IndexAtual].Cadeia);

                    IndexAtual++;
                    Parametros();

                    AddParametrosNaProcedure(procedure);

                    TabelaDeSimbolos.TryAddNewItem(procedure);

                    CorpoP();

                    EscopoStack.Pop();
                }
                else
                {
                    ThrowCompiladorException(Tokens[IndexAtual]);
                }
            }
            else
            {
                ThrowCompiladorException(Tokens[IndexAtual]);
            }

            CallStack.Pop();
        }