(Created page with "{{PRJPOAvisosEN20172018}} {{PRJPOMandatory20172018}} {{TOCright}} <!--'''<font color="red">ÉPOCA NORMAL</font>'''--> (...) category:Ensino category:PO category:Pr...") |
|||
Line 4: | Line 4: | ||
<!--'''<font color="red">ÉPOCA NORMAL</font>'''--> | <!--'''<font color="red">ÉPOCA NORMAL</font>'''--> | ||
− | (...) | + | O objectivo do projecto é criar uma aplicação que gere os itinerários de um passageiro que usa comboios. |
+ | |||
+ | Os itinerários são constituídos por um ou mais segmentos, realizados por comboios que cumprem horários pré-definidos. | ||
+ | |||
+ | Neste texto, o tipo '''negrito''' indica um literal (i.e., é exactamente como apresentado); o símbolo <amsmath>\verb*| |</amsmath> indica um espaço; e o tipo ''itálico'' indica uma parte variável (i.e., uma descrição). | ||
+ | |||
+ | = Estrutura dos horários e dos itinerários = | ||
+ | |||
+ | Existem dois conceitos básicos: horário e itinerário. | ||
+ | |||
+ | == Estrutura de um horário == | ||
+ | |||
+ | Um horário é um percurso realizado por um comboio ao longo de vários locais. A cada local está associado o momento de partida do comboio. Por simplicidade, considera-se que a hora de partida é sempre igual à de chegada. | ||
+ | |||
+ | Cada segmento de um horário tem um custo. Este custo depende da distância entre os locais, do tipo de serviço e do tipo de cliente. | ||
+ | |||
+ | Cada comboio suporta um ou mais serviços. Os serviços são ``conforto'', ``turística'' e ``única''. | ||
+ | |||
+ | == Estrutura de um itinerário == | ||
+ | |||
+ | Um itinerário é um conjunto de segmentos, correspondentes a partes de horários. Cada segmento tem um local e hora de partida e um local e uma hora de chegada. É possível saber, através do horário associado, qual o percurso a realizar nesse segmento. O custo de cada segmento é o do percurso realizado no horário e serviço correspondente. | ||
+ | |||
+ | O custo do itinerário é a soma dos custos dos segmentos individuais. Dependendo do tipo de cliente, podem ser realizados descontos em alguns tipos de serviço. A classe de serviço está associada a cada segmento e não ao itinerário em si. | ||
+ | |||
+ | = Funcionalidade da Aplicação = | ||
+ | |||
+ | A aplicação permite manter informação sobre horários e criar novos itinerários para o passageiro. Possui também várias formas de preservar o seu estado (não é possível manter várias versões do estado do interpretador em simultâneo). | ||
+ | |||
+ | == Interpretação de expressões == | ||
+ | |||
+ | As expressões, apresentadas ao interpretador em forma de texto, devem ser interpretadas antes de serem armazenadas. O texto original não é preservado. Note-se que o processo de interpretação (conversão do texto para estruturas/objectos) é diferente do de avaliação (conversão das estruturas/objectos para valores). | ||
+ | |||
+ | O texto a interpretar (expressões ou programas) pode ser providenciado via interface do próprio interpretador ou na forma de um ficheiro que contém um programa. | ||
+ | |||
+ | Uma falha de interpretação causa o lançamento de uma excepção no analisador do interpretador. | ||
+ | |||
+ | {{Suggestion|Note-se que não é necessário implementar de raiz o analisador de expressões e programas do interpretador. Um analisador já parcialmente concretizado, '''mmt.Parser''', está disponível. Este analisador é responsável por processar um programa ou uma expressão e realizar a conversão de texto para a estrutura de dados correspondente. Será apenas necessário indicar as entidades utilizadas para representar um programa ou uma expressão.}} | ||
+ | |||
+ | == Armazenamento de programas == | ||
+ | |||
+ | O interpretador permite associar nomes a programas, preservando-os. Note-se que isto não corresponde a guardar valores calculados por esses programas, mas a guardar as suas descrições, i.e., as resultantes da interpretação da forma textual correspondente. Se um nome já estiver em uso, a associação ao programa anterior é perdida. | ||
+ | |||
+ | == Interpretação de programas == | ||
+ | |||
+ | A interpretação de programas e, consequentemente, das suas expressões, deve ser feita de forma flexível. Ou seja, deve ser possível -- sem alterar o código das expressões ou do interpretador -- definir novas formas de avaliação. Por omissão, a avaliação corresponde simplesmente à apresentação de uma forma textual do programa (e das suas expressões). | ||
+ | |||
+ | Uma outra avaliação possível é o cálculo dos valores das expressões do programa, correspondente à execução desse programa. | ||
+ | |||
+ | == Serialização == | ||
+ | |||
+ | É possível reiniciar, guardar e recuperar o estado actual da aplicação, preservando todos a informação de horários e itinerários. | ||
+ | |||
+ | = Interacção com o Utilizador = | ||
+ | |||
+ | Descreve-se nesta secção a '''funcionalidade máxima''' da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de proceder à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção '''Sair''' (fecha o menu). | ||
+ | |||
+ | As operações de pedido e apresentação de informação ao utilizador '''devem''' realizar-se através dos objectos ''form'' e ''display'', respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das [[Programação com Objectos/Projecto de Programação com Objectos/Material de Apoio ao Desenvolvimento|bibliotecas de suporte]] ('''po-uuilib''' e '''mmt-app'''). As mensagens não podem ser usadas no núcleo da aplicação ('''mmt-core'''). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação. | ||
+ | |||
+ | As excepções usadas na interacção, excepto se indicado, são subclasses de '''pt.tecnico.po.ui.DialogException''', são lançadas pelos comandos e tratadas por '''pt.tecnico.po.ui.Menu'''. Outras excepções não devem substituir as fornecidas nos casos descritos. | ||
+ | |||
+ | {{CVSCode|Note-se que os comandos e menus a seguir descritos, assim como o programa principal, já estão implementados nas classes das ''packages'' '''mmt.app''', '''mmt.app.main''' e '''mmt.app.evaluator'''. Estas classes são de uso obrigatório e estão disponíveis no [[Programação com Objectos/Projecto de Programação com Objectos/Repositório CVS|CVS]] (módulo '''mmt-app''').}} | ||
+ | |||
+ | == Menu Principal == | ||
+ | |||
+ | As acções do menu permitem gerir a salvaguarda do estado da aplicação: [[#Salvaguarda do Estado Actual do Interpretador|Criar]], [[#Salvaguarda do Estado Actual do Interpretador|Abrir]], [[#Salvaguarda do Estado Actual do Interpretador|Guardar]], [[#Criação, Leitura e Escrita de Programas|Criar Programa]], [[#Criação, Leitura e Escrita de Programas|Ler Programa]], [[#Criação, Leitura e Escrita de Programas|Escrever Programa]] e [[#Manipulação de Programa|Manipulação de Programa]]. A classe '''mmt.app.main.Message''' define os métodos para geração das mensagens de diálogo. Inicialmente, o interpretador está vazio. | ||
+ | |||
+ | === Salvaguarda do Estado Actual do Interpretador === | ||
+ | |||
+ | O conteúdo da aplicação (inclui todos os horários e itinerários actualmente carregados pela aplicação) pode ser guardado para posterior recuperação (via serialização Java: '''java.io.Serializable'''). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte: | ||
+ | |||
+ | * '''Criar''' -- Cria um novo interpretador sem ficheiro associado. | ||
+ | * '''Abrir''' -- Carrega um interpretador anteriormente salvaguardado, ficando o interpretador carregado associado ao ficheiro nomeado: pede-se o nome do ficheiro a abrir ('''openFile()'''). Caso o ficheiro não exista, é apresentada a mensagem '''fileNotFound()'''. | ||
+ | * '''Guardar''' -- Guarda o estado actual do interpretador no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado. Esta interacção realiza-se através do método '''newSaveAs()'''. Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda. | ||
+ | |||
+ | As opções '''Criar''' e '''Abrir''' descartam eventuais alterações no interpretador ou no seu conteúdo. | ||
+ | |||
+ | A opção '''Sair''' nunca guarda o estado da aplicação, mesmo que existam alterações. | ||
+ | |||
+ | {{CVSCode|Estes comandos já estão parcialmente implementados nas classes da ''package'' '''mmt.app.main''' (disponível no CVS), respectivamente: '''New''', '''Open''', '''Save'''.}} | ||
+ | |||
+ | === Criação, Leitura e Escrita de Programas === | ||
+ | |||
+ | É possível criar novos programas (vazios), ler programas a partir de ficheiros textuais e escrever programas sob a forma de ficheiros textuais. As operações são as seguintes: | ||
+ | |||
+ | * '''Criar Programa''' -- Permite criar um programa vazio. É pedido o nome do programa através de '''requestProgramId()'''. A utilização de um nome previamente registado substitui o programa a ele associado por um programa vazio. | ||
+ | * '''Ler Programa''' -- Permite ler e interpretar o texto de um programa a partir de um ficheiro. É lido o ficheiro indicado pelo método '''programFileName()'''. A leitura de novo ficheiro com o mesmo nome substitui o programa anterior com esse nome (nome do ficheiro indicado). Note-se que o novo programa é interpretado: se a excepção '''mmt.ParserException''' (do "core") for recebida, então a excepção '''mmt.app.BadFileException''' (a desenvolver) deve ser lançada pelo comando. Neste caso, o programa não deve ser registado. | ||
+ | * '''Escrever Programa''' -- Permite guardar um programa como um ficheiro de texto, passível de ser lido novamente pelo interpretador. O interpretador pede o identificador do programa '''requestProgramId()''' e o nome do ficheiro onde deve ser guardado o programa, através do método '''programFileName()'''. Se o programa não existir, é comunicado o erro através de '''noSuchProgram()'''. Escritas no mesmo ficheiro substituem o conteúdo anterior, não ficando associado ao interpretador. | ||
+ | |||
+ | {{CVSCode|Estes comandos já estão parcialmente implementados nas classes da ''package'' '''mmt.app.main''' (disponível no CVS), respectivamente: '''NewProgram''', '''ReadProgram''', '''WriteProgram'''.}} | ||
+ | {{Aviso|É necessário definir a excepção '''mmt.app.BadFileException''', devendo o seu construtor receber como argumento o nome do ficheiro que contém o programa a ler.}} | ||
+ | |||
+ | === Consulta de Horários === | ||
+ | |||
+ | Esta opção permite a consulta de horários associados ao serviços de transporte. É pedido o identificador do serviço a consultar: '''requestScheduleId()'''. Se o serviço não existir, é comunicado o erro através de '''noSuchSchedule()'''. | ||
+ | |||
+ | {{CVSCode|Este comando já está implementado na classe '''mmt.app.main.ShowService''' (disponível no CVS).}} | ||
+ | |||
+ | === Manipulação de Itinerários === | ||
+ | |||
+ | Abre o menu de edição de um itinerário. É pedido o identificador do itinerário '''requestIteneraryId()'''. Se o itinerário não existir, é comunicado o erro através de '''noSuchItinerary()'''. | ||
+ | |||
+ | {{CVSCode|Este comando já está implementado na classe '''mmt.app.main.ManageIninerary''' (disponível no CVS).}} | ||
+ | |||
+ | == Menu de Manipulação de Programas == | ||
+ | |||
+ | Este menu permite efectuar operações sobre um programa. A lista completa é a seguinte: [[#Listar programa|Listar programa]], [[#Executar|Executar]], [[#Adicionar expressão|Adicionar expressão]], [[#Substituir expressão|Substituir expressão]], [[#Mostrar os identificadores presentes no programa|Mostrar os identificadores presentes no programa]], [[#Mostrar os identificadores não inicializados do programa|Mostrar os identificadores não inicializados do programa]]. | ||
+ | |||
+ | As etiquetas das opções deste menu estão definidas na classe '''mmt.app.evaluator.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''mmt.app.evaluator.Message'''. | ||
+ | |||
+ | {{CVSCode|Estes comandos já estão parcialmente implementados nas classes da ''package'' '''mmt.app.evaluator''' (disponível no CVS), respectivamente: '''ShowProgram''', '''RunProgram''', '''AddExpression''', '''ReplaceExpression''', '''ShowAllIdentifiers''', '''ShowUninitializedIdentifiers'''.}} | ||
+ | |||
+ | === Listar programa === | ||
+ | |||
+ | Este comando apresenta a lista de expressões do programa em formato textual. | ||
+ | |||
+ | === Adicionar expressão ao programa === | ||
+ | |||
+ | Este comando permite adicionar uma nova expressão ao programa. Para tal, é pedido o índice correspondente à posição de inserção (o primeiro índice é 0), através de '''requestPosition()''', sendo a nova expressão aí inserida. A nova expressão é lida como resposta a '''requestExpression()'''. | ||
+ | |||
+ | Se a indicação de posição for igual ao número de elementos do programa, a nova expressão é inserida no final do programa (após todas as outras). | ||
+ | |||
+ | Se a indicação de posição for inválida, o comando deve lançar a excepção '''mmt.app.BadPositionException''' e o programa não é alterado. | ||
+ | |||
+ | Note-se que a nova expressão é interpretada: se a excepção '''mmt.ParserException''' (do "core") for recebida, então a excepção '''mmt.app.BadExpressionException''' deve ser lançada pelo comando. Neste caso, o programa não deve ser alterado. | ||
+ | |||
+ | === Substituir expressão no programa === | ||
+ | |||
+ | Este comando permite substituir uma expressão existente no programa por uma nova expressão. Para tal, é pedido o índice correspondente à posição de inserção (o primeiro índice é 0), através de '''requestPosition()''', sendo a expressão aí existente substituída pela nova expressão. A nova expressão é lida como resposta a '''requestExpression()'''. | ||
+ | |||
+ | Se a indicação de posição for inválida, o comando deve lançar a excepção '''mmt.app.BadPositionException''' e o programa não é alterado. | ||
+ | |||
+ | Note-se que a nova expressão é interpretada: se a excepção '''mmt.ParserException''' (do "core") for recebida, então a excepção '''mmt.app.BadExpressionException''' deve ser lançada pelo comando. Neste caso, o programa não deve ser alterado. | ||
+ | |||
+ | === Mostrar os identificadores presentes no programa === | ||
+ | |||
+ | Este comando permite listar todos os identificadores presentes no programa (apresentando um identificador por linha, por ordem alfabética), tanto nas expressões de definição, como nas que usam identificadores. | ||
+ | |||
+ | === Mostrar os identificadores do programa sem inicialização explícita === | ||
+ | |||
+ | Este comando permite listar todos os identificadores presentes no programa que não são objecto de nenhuma incialização explícita (apresentando um identificador por linha, por ordem alfabética), i.e., não terem um valor previamente associado via operador '''set'''. | ||
+ | |||
+ | = Leitura de Programas a Partir de Ficheiros Textuais = | ||
+ | |||
+ | Além das opções de manipulação de ficheiros descritas no [[#Salvaguarda do Documento Actual|menu principal]], é possível iniciar a aplicação com um ficheiro de texto especificado pela propriedade Java '''[[#Execução dos Programas e Testes Automáticos|import]]'''. Este ficheiro contém um programa que é avaliado pelo interpretador. <!-- Se não existirem definições de variáveis, a avaliação não deixa traços na memória da calculadora. Apenas é lida a primeira expressão presente no ficheiro.--> O programa fica registado com o nome '''import'''. | ||
+ | |||
+ | == Exemplo de ficheiro a importar == | ||
+ | |||
+ | Este programa é composto por três expressões, a última das quais é um ciclo. | ||
+ | <lisp> | ||
+ | (seq (add 1 2) (sub 1 2) (mul (add 1 2) 3)) | ||
+ | (seq (add 1 2) (sub 1 2) (mul (add 1 2) 3) (div 2 5) "olá") | ||
+ | (seq (set ix 0) (while (lt ix 30) (seq (print "ix =" ix) (set ix (add ix 1))))) | ||
+ | </lisp> | ||
+ | |||
+ | Embora o interpretador de expressões tenha de assinalar problemas relativos à interpretação de expressões mal especificadas, assume-se que não existem entradas mal-formadas nestes ficheiros (embora tenham de ser detectadas). | ||
+ | |||
+ | = Considerações sobre Flexibilidade e Eficiência = | ||
+ | |||
+ | Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Em particular, a solução encontrada para salvaguardar textualmente o conteúdo do documento deve ser suficientemente flexível de modo a permitir visualizar o conteúdo de um documento noutro formato (por exemplo, XML) sem que isso implique alterações no código ''core'' da aplicação. | ||
+ | |||
+ | = Execução dos Programas e Testes Automáticos = | ||
+ | |||
+ | Usando os ficheiros '''test.import''', '''test.in''' e '''test.out''', é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável '''CLASSPATH''' (ou da opção equivalente '''-cp''' do comando '''java'''), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação ('''mmt.app.App.main'''). As propriedades são tratadas automaticamente pelo código de apoio. | ||
+ | |||
+ | java -Dimport=test.import -Din=test.in -Dout=test.outhyp mmt.app.App | ||
+ | |||
+ | Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída '''test.outhyp'''. Em caso de sucesso, os ficheiros das saídas esperada ('''test.out''') e obtida ('''test.outhyp''') devem ser iguais. A comparação pode ser feita com o comando: | ||
+ | |||
+ | diff -b test.out test.outhyp | ||
+ | |||
+ | Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade. | ||
[[category:Ensino]] | [[category:Ensino]] |
AVISOS - Avaliação em Época Normal |
---|
Esclarecimento de dúvidas:
|
Requisitos para desenvolvimento, material de apoio e actualizações do enunciado (ver informação completa em Projecto de Programação com Objectos):
|
Processo de avaliação (ver informação completa em Avaliação do Projecto):
|
Material de Uso Obrigatório |
---|
As bibliotecas po-uuilib e o conteúdo inicial do CVS são de uso obrigatório: |
|
A máquina virtual, fornecida para desenvolvimento do projecto, já contém todo o material de apoio. |
Uso Obrigatório: Repositório CVS |
Apenas se consideram para avaliação os projectos existentes no repositório CVS oficial.
Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho. |
O objectivo do projecto é criar uma aplicação que gere os itinerários de um passageiro que usa comboios.
Os itinerários são constituídos por um ou mais segmentos, realizados por comboios que cumprem horários pré-definidos.
Neste texto, o tipo negrito indica um literal (i.e., é exactamente como apresentado); o símbolo indica um espaço; e o tipo itálico indica uma parte variável (i.e., uma descrição).
Existem dois conceitos básicos: horário e itinerário.
Um horário é um percurso realizado por um comboio ao longo de vários locais. A cada local está associado o momento de partida do comboio. Por simplicidade, considera-se que a hora de partida é sempre igual à de chegada.
Cada segmento de um horário tem um custo. Este custo depende da distância entre os locais, do tipo de serviço e do tipo de cliente.
Cada comboio suporta um ou mais serviços. Os serviços são ``conforto, ``turística e ``única.
Um itinerário é um conjunto de segmentos, correspondentes a partes de horários. Cada segmento tem um local e hora de partida e um local e uma hora de chegada. É possível saber, através do horário associado, qual o percurso a realizar nesse segmento. O custo de cada segmento é o do percurso realizado no horário e serviço correspondente.
O custo do itinerário é a soma dos custos dos segmentos individuais. Dependendo do tipo de cliente, podem ser realizados descontos em alguns tipos de serviço. A classe de serviço está associada a cada segmento e não ao itinerário em si.
A aplicação permite manter informação sobre horários e criar novos itinerários para o passageiro. Possui também várias formas de preservar o seu estado (não é possível manter várias versões do estado do interpretador em simultâneo).
As expressões, apresentadas ao interpretador em forma de texto, devem ser interpretadas antes de serem armazenadas. O texto original não é preservado. Note-se que o processo de interpretação (conversão do texto para estruturas/objectos) é diferente do de avaliação (conversão das estruturas/objectos para valores).
O texto a interpretar (expressões ou programas) pode ser providenciado via interface do próprio interpretador ou na forma de um ficheiro que contém um programa.
Uma falha de interpretação causa o lançamento de uma excepção no analisador do interpretador.
O interpretador permite associar nomes a programas, preservando-os. Note-se que isto não corresponde a guardar valores calculados por esses programas, mas a guardar as suas descrições, i.e., as resultantes da interpretação da forma textual correspondente. Se um nome já estiver em uso, a associação ao programa anterior é perdida.
A interpretação de programas e, consequentemente, das suas expressões, deve ser feita de forma flexível. Ou seja, deve ser possível -- sem alterar o código das expressões ou do interpretador -- definir novas formas de avaliação. Por omissão, a avaliação corresponde simplesmente à apresentação de uma forma textual do programa (e das suas expressões).
Uma outra avaliação possível é o cálculo dos valores das expressões do programa, correspondente à execução desse programa.
É possível reiniciar, guardar e recuperar o estado actual da aplicação, preservando todos a informação de horários e itinerários.
Descreve-se nesta secção a funcionalidade máxima da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de proceder à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção Sair (fecha o menu).
As operações de pedido e apresentação de informação ao utilizador devem realizar-se através dos objectos form e display, respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das bibliotecas de suporte (po-uuilib e mmt-app). As mensagens não podem ser usadas no núcleo da aplicação (mmt-core). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.
As excepções usadas na interacção, excepto se indicado, são subclasses de pt.tecnico.po.ui.DialogException, são lançadas pelos comandos e tratadas por pt.tecnico.po.ui.Menu. Outras excepções não devem substituir as fornecidas nos casos descritos.
As acções do menu permitem gerir a salvaguarda do estado da aplicação: Criar, Abrir, Guardar, Criar Programa, Ler Programa, Escrever Programa e Manipulação de Programa. A classe mmt.app.main.Message define os métodos para geração das mensagens de diálogo. Inicialmente, o interpretador está vazio.
O conteúdo da aplicação (inclui todos os horários e itinerários actualmente carregados pela aplicação) pode ser guardado para posterior recuperação (via serialização Java: java.io.Serializable). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:
As opções Criar e Abrir descartam eventuais alterações no interpretador ou no seu conteúdo.
A opção Sair nunca guarda o estado da aplicação, mesmo que existam alterações.
É possível criar novos programas (vazios), ler programas a partir de ficheiros textuais e escrever programas sob a forma de ficheiros textuais. As operações são as seguintes:
Esta opção permite a consulta de horários associados ao serviços de transporte. É pedido o identificador do serviço a consultar: requestScheduleId(). Se o serviço não existir, é comunicado o erro através de noSuchSchedule().
Abre o menu de edição de um itinerário. É pedido o identificador do itinerário requestIteneraryId(). Se o itinerário não existir, é comunicado o erro através de noSuchItinerary().
Este menu permite efectuar operações sobre um programa. A lista completa é a seguinte: Listar programa, Executar, Adicionar expressão, Substituir expressão, Mostrar os identificadores presentes no programa, Mostrar os identificadores não inicializados do programa.
As etiquetas das opções deste menu estão definidas na classe mmt.app.evaluator.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe mmt.app.evaluator.Message.
Este comando apresenta a lista de expressões do programa em formato textual.
Este comando permite adicionar uma nova expressão ao programa. Para tal, é pedido o índice correspondente à posição de inserção (o primeiro índice é 0), através de requestPosition(), sendo a nova expressão aí inserida. A nova expressão é lida como resposta a requestExpression().
Se a indicação de posição for igual ao número de elementos do programa, a nova expressão é inserida no final do programa (após todas as outras).
Se a indicação de posição for inválida, o comando deve lançar a excepção mmt.app.BadPositionException e o programa não é alterado.
Note-se que a nova expressão é interpretada: se a excepção mmt.ParserException (do "core") for recebida, então a excepção mmt.app.BadExpressionException deve ser lançada pelo comando. Neste caso, o programa não deve ser alterado.
Este comando permite substituir uma expressão existente no programa por uma nova expressão. Para tal, é pedido o índice correspondente à posição de inserção (o primeiro índice é 0), através de requestPosition(), sendo a expressão aí existente substituída pela nova expressão. A nova expressão é lida como resposta a requestExpression().
Se a indicação de posição for inválida, o comando deve lançar a excepção mmt.app.BadPositionException e o programa não é alterado.
Note-se que a nova expressão é interpretada: se a excepção mmt.ParserException (do "core") for recebida, então a excepção mmt.app.BadExpressionException deve ser lançada pelo comando. Neste caso, o programa não deve ser alterado.
Este comando permite listar todos os identificadores presentes no programa (apresentando um identificador por linha, por ordem alfabética), tanto nas expressões de definição, como nas que usam identificadores.
Este comando permite listar todos os identificadores presentes no programa que não são objecto de nenhuma incialização explícita (apresentando um identificador por linha, por ordem alfabética), i.e., não terem um valor previamente associado via operador set.
Além das opções de manipulação de ficheiros descritas no menu principal, é possível iniciar a aplicação com um ficheiro de texto especificado pela propriedade Java import. Este ficheiro contém um programa que é avaliado pelo interpretador. O programa fica registado com o nome import.
Este programa é composto por três expressões, a última das quais é um ciclo. <lisp>
(seq (add 1 2) (sub 1 2) (mul (add 1 2) 3)) (seq (add 1 2) (sub 1 2) (mul (add 1 2) 3) (div 2 5) "olá") (seq (set ix 0) (while (lt ix 30) (seq (print "ix =" ix) (set ix (add ix 1)))))
</lisp>
Embora o interpretador de expressões tenha de assinalar problemas relativos à interpretação de expressões mal especificadas, assume-se que não existem entradas mal-formadas nestes ficheiros (embora tenham de ser detectadas).
Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Em particular, a solução encontrada para salvaguardar textualmente o conteúdo do documento deve ser suficientemente flexível de modo a permitir visualizar o conteúdo de um documento noutro formato (por exemplo, XML) sem que isso implique alterações no código core da aplicação.
Usando os ficheiros test.import, test.in e test.out, é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável CLASSPATH (ou da opção equivalente -cp do comando java), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação (mmt.app.App.main). As propriedades são tratadas automaticamente pelo código de apoio.
java -Dimport=test.import -Din=test.in -Dout=test.outhyp mmt.app.App
Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída test.outhyp. Em caso de sucesso, os ficheiros das saídas esperada (test.out) e obtida (test.outhyp) devem ser iguais. A comparação pode ser feita com o comando:
diff -b test.out test.outhyp
Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade.