package loo1.plp.orientadaObjetos1.comando; import loo1.plp.expressions2.memory.VariavelJaDeclaradaException; import loo1.plp.expressions2.memory.VariavelNaoDeclaradaException; import loo1.plp.orientadaObjetos1.declaracao.procedimento.ListaDeclaracaoParametro; import loo1.plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ObjetoJaDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ProcedimentoJaDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ProcedimentoNaoDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.execucao.EntradaInvalidaException; import loo1.plp.orientadaObjetos1.expressao.ListaExpressao; import loo1.plp.orientadaObjetos1.memoria.AmbienteCompilacaoOO1; import loo1.plp.orientadaObjetos1.memoria.AmbienteExecucaoOO1; import loo1.plp.orientadaObjetos1.memoria.colecao.ListaValor; import loo1.plp.orientadaObjetos1.util.ListaTipo; /** * Classe que representa uma chamada de um procedimento. */ public class ChamadaProcedimento implements Comando { /** * � o procedimento */ private Procedimento procedimento; /** * S�o os parametros do procedimento */ private ListaExpressao parametrosReais; /** * Valores que serao atribu�dos aos parametros reais */ private ListaValor valoresParametros; /** * Contrutor Default. * @param procedimento � o procedimento * @param parametrosReais sao os par�metros do procedimento * @param valoresParametros sao os valores dos parametros */ public ChamadaProcedimento(Procedimento procedimento, ListaExpressao parametrosReais, ListaValor valoresParametros){ this.procedimento = procedimento; this.parametrosReais = parametrosReais; this.valoresParametros = valoresParametros; } /** * Contrutor Default. * @param procedimento � o procedimento * @param parametrosReais sao os par�metros do procedimento */ public ChamadaProcedimento(Procedimento procedimento, ListaExpressao parametrosReais){ this.procedimento = procedimento; this.parametrosReais = parametrosReais; this.valoresParametros = null; } /** * Executa este comando. * @param ambiente o ambiente que contem o mapeamento entre identificadores * e valores. * @return o ambiente modificado pela execu��o do comando. */ public AmbienteExecucaoOO1 executar(AmbienteExecucaoOO1 ambiente) throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException, ProcedimentoNaoDeclaradoException, ProcedimentoJaDeclaradoException, ObjetoNaoDeclaradoException, ObjetoJaDeclaradoException, ClasseNaoDeclaradaException, ClasseJaDeclaradaException, EntradaInvalidaException{ ambiente.incrementa(); ambiente = bindParameters(ambiente, procedimento.getParametrosFormais()); ambiente = procedimento.getComando().executar(ambiente); ambiente.restaura(); return ambiente; } /** * insere no contexto o resultado da associacao entre cada parametro formal * e seu correspondente parametro atual * @throws ClasseNaoDeclaradaException */ private AmbienteExecucaoOO1 bindParameters (AmbienteExecucaoOO1 ambiente, ListaDeclaracaoParametro parametrosFormais) throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException, ObjetoNaoDeclaradoException, ClasseNaoDeclaradaException{ ListaValor listaValor = this.valoresParametros; if(listaValor == null) { listaValor = parametrosReais.avaliar(ambiente); } while (listaValor.length() > 0){ ambiente.map(parametrosFormais.getHead().getId(), listaValor.getHead()); parametrosFormais = ((ListaDeclaracaoParametro) parametrosFormais.getTail()); listaValor = (ListaValor)listaValor.getTail(); } return ambiente; } /** * Realiza a verificacao de tipos desta chamada de procedimento, onde * os tipos dos parametros formais devem ser iguais aos tipos dos * parametros reais na ordem em que se apresentam. * * @param ambiente o ambiente que contem o mapeamento entre identificadores * e tipos. * * @return true se a chamada de procedimeno est� bem tipada; * false caso contrario. */ public boolean checaTipo(AmbienteCompilacaoOO1 ambiente) throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException, ProcedimentoNaoDeclaradoException,ClasseNaoDeclaradaException { boolean resposta; ambiente.incrementa(); ListaDeclaracaoParametro parametrosFormais = procedimento.getParametrosFormais(); ListaTipo listaTipo = parametrosReais.getTipos(ambiente); //tem o mesmo numero de parametros formais e reais? if(listaTipo.length() == parametrosFormais.length()) { // a funcao tem algum parametro? if(listaTipo.head() == null || parametrosFormais.getHead() == null) { resposta = true; } else { resposta = true; // tem parametros formais de tipos diferentes // de parametros reais na ordem em que se apresentam? while(listaTipo != null && parametrosFormais != null) { if( ! listaTipo.head().equals(parametrosFormais.getHead().getTipo())) { resposta = false; break; } listaTipo = listaTipo.tail(); parametrosFormais = ((ListaDeclaracaoParametro) parametrosFormais.getTail()); } } } else { resposta = false; } ambiente.restaura(); return resposta; } }