public VisitorGeracaoCodigo geraAtributosParaAsVariaveisPassadasPorReferencia(
        Map<TipoDado, List<NoDeclaracaoVariavel>> variaveis) {
      if (variaveis.isEmpty()) {
        return this;
      }

      String identacao = Utils.geraIdentacao(nivelEscopo);

      // declara os arrays (separados por tipo) que armazenam todas as referências
      // gera os arrays nessa sequência de tipos
      TipoDado tipos[] = {
        TipoDado.INTEIRO, TipoDado.REAL, TipoDado.LOGICO, TipoDado.CARACTER, TipoDado.CADEIA
      };

      for (TipoDado tipo : tipos) {
        if (variaveis.containsKey(tipo)) {
          String nomeTipo = Utils.getNomeTipoJava(tipo);
          int numeroVariaveis = variaveis.get(tipo).size();
          saida
              .append(identacao)
              .format(
                  "private final %s[] REFS_%s = new %s[%d];",
                  nomeTipo, nomeTipo.toUpperCase(), nomeTipo, numeroVariaveis)
              .println();
        }
      }

      saida.println(); // pula uma linha antes de declarar as variáveis de cada tipo

      for (TipoDado tipo : tipos) {
        if (variaveis.containsKey(tipo)) {
          for (NoDeclaracaoVariavel variavel : variaveis.get(tipo)) {
            saida
                .append(identacao)
                .append("private final int ")
                .append(Utils.geraStringIndice(variavel))
                .append(" = ")
                .append(String.valueOf(variavel.getIndiceReferencia()))
                .append(";")
                .println();
          }

          saida.println(); // separa as declarações para cada tipo
        }
      }

      return this;
    }
 private void inicializaVariaveisGlobaisQueSaoPassadasPorReferencia() throws ExcecaoVisitaASA {
   List<NoDeclaracao> declaracoes = asa.getListaDeclaracoesGlobais();
   for (NoDeclaracao declaracao : declaracoes) {
     if (declaracao instanceof NoDeclaracaoVariavel) {
       NoDeclaracaoVariavel variavel = (NoDeclaracaoVariavel) declaracao;
       if (variavel.ehPassadaPorReferencia() && variavel.temInicializacao()) {
         String nomeTipo = Utils.getNomeTipoJava(variavel.getTipoDado());
         saida.append(Utils.geraIdentacao(nivelEscopo));
         saida.format(
             "REFS_%s[%s] = ", nomeTipo.toUpperCase(), Utils.geraStringIndice(variavel));
         variavel.getInicializacao().aceitar(this);
         saida.append(";").println(); // o ponto e vírgula depois da inicialização
       }
     }
   }
 }
    @Override
    public Void visitar(NoReferenciaVariavel no) throws ExcecaoVisitaASA {
      String nome = no.getNome();
      if (no.getEscopo() != null) {
        saida.append(no.getEscopo()).append(".");
      }

      NoDeclaracao declaracao = no.getOrigemDaReferencia();
      boolean ehParametroPorReferencia =
          declaracao instanceof NoDeclaracaoParametro
              && (((NoDeclaracaoParametro) declaracao).getModoAcesso()
                  == ModoAcesso.POR_REFERENCIA);
      if (ehParametroPorReferencia || no.ehPassadoPorReferencia()) {
        String stringIndice = ehParametroPorReferencia ? no.getNome() : Utils.geraStringIndice(no);
        String nomeTipo = Utils.getNomeTipoJava(declaracao.getTipoDado()).toUpperCase();
        saida.format("REFS_%s[%s]", nomeTipo, stringIndice);
      } else {
        saida.append(nome);
      }

      return null;
    }