INF1018 - Software Básico

Aulas de Laboratório

Co-rotinas como iteradores

Neste laboratório, vamos usar a biblioteca de co-rotinas discutida em sala. Para começar, pegue os arquivos: e coloque em um diretório novo chamado labcoro.

Vamos utilizar também uma lista de inteiros. Pegue agora os arquivos:

Examine os arquivos. Observe que ListaInteiros é um tipo abstrato, cuja representação só é vista dentro de listainteiros.c. O programa usuário de uma lista só pode acessá-la através das operações oferecidas em sua interface.

Considere o seguinte problema. Imagine que você quer calcular a soma e o produto dos elementos numa lista já existente. Você poderia fazer isso em testaLista.c...?

Isso não é possível devido à estrutura de encapsulamento da lista. Vamos então estender o tipo abstrato ListaInteiros, incluindo um iterador baseado em corotinas, com o qual será possível realizar tarefas como a descrita.

Veja que há três funções na interface listainteiros.h:

que não estão totalmente implementadas em listainteiros.c.

A função criaIterador deve retornar uma nova corotina cujo código (corpo) é uma função - iteraLista - que percorre a lista dada, fornecendo com yield cada um dos seus elementos. Um "esqueleto" dessa função já está no arquivo listainteiros.c. Note que ela é declarada como static no arquivo listainteiros.c pois não deve ser usada diretamente de fora desse arquivo.

Note que a lista só está sendo passada como argumento para a função criaIterador. Para amarrar a lista passada à corotina criada, essa função já deve fazer um primeiro resume para poder passar a lista como parâmetro para a função iteraLista. iteraLista começa logo dando um yield para retornar o controle a criaIterador. Ao alcançar o final da lista, a função iteraLista retorna MININT (é um aviso para o usuário do iterador que a lista acabou...) O retorno de criaIterador é um ponteiro para a nova corotina (do tipo CoroP), mas como não queremos que o programa usuário saiba disso, esse ponteiro é retornado como um void *.

A função ativaIterador recebe uma corotina, ativa sua execução, e retorna o valor fornecido por ela. Finalmente, destroiIterador destrói a corotina passada como argumento.

Escreva essas funções e teste-as em testaLista, escrevendo código para somar (e multiplicar) os elementos das duas listas criadas pela main. Não esqueça de destruir os iteradores após usá-los (eles não podem ser reusados, pois a função que é seu "corpo" terá retornado!). Uma sugestão é somar os elementos da primeira lista e multiplicar os elementos da segunda...

Para compilar seu programa, você vai usar:

gcc -m32 -Wa,--execstack -o meuprog core.s corotinas.c listainteiros.c testaLista.c