00001 package plp.imperative2.command; 00002 00003 import java.util.List; 00004 00005 import plp.expressions1.util.Tipo; 00006 import plp.expressions2.expression.Id; 00007 import plp.expressions2.memory.IdentificadorJaDeclaradoException; 00008 import plp.expressions2.memory.IdentificadorNaoDeclaradoException; 00009 import plp.expressions2.memory.VariavelJaDeclaradaException; 00010 import plp.expressions2.memory.VariavelNaoDeclaradaException; 00011 import plp.imperative1.command.Comando; 00012 import plp.imperative1.memory.AmbienteCompilacaoImperativa; 00013 import plp.imperative1.memory.AmbienteExecucaoImperativa; 00014 import plp.imperative1.memory.EntradaVaziaException; 00015 import plp.imperative1.memory.ListaValor; 00016 import plp.imperative2.declaration.ListaDeclaracaoParametro; 00017 import plp.imperative2.memory.AmbienteCompilacaoImperativa2; 00018 import plp.imperative2.memory.AmbienteExecucaoImperativa2; 00019 import plp.imperative2.memory.Procedimento; 00020 00021 public class ChamadaProcedimento implements Comando { 00022 00023 private Id nomeProcedimento; 00024 00025 private ListaExpressao parametrosReais; 00026 00027 public ChamadaProcedimento(Id nomeProcedimento, 00028 ListaExpressao parametrosReais) { 00029 this.nomeProcedimento = nomeProcedimento; 00030 this.parametrosReais = parametrosReais; 00031 } 00032 00033 public AmbienteExecucaoImperativa executar(AmbienteExecucaoImperativa amb) 00034 throws IdentificadorNaoDeclaradoException, 00035 IdentificadorJaDeclaradoException, EntradaVaziaException { 00036 AmbienteExecucaoImperativa2 ambiente = (AmbienteExecucaoImperativa2) amb; 00037 Procedimento procedimento = ambiente.getProcedimento(nomeProcedimento); 00038 ambiente.incrementa(); 00039 ListaDeclaracaoParametro parametrosFormais = procedimento 00040 .getParametrosFormais(); 00041 AmbienteExecucaoImperativa2 aux = bindParameters(ambiente, 00042 parametrosFormais); 00043 aux = (AmbienteExecucaoImperativa2) procedimento.getComando().executar( 00044 aux); 00045 aux.restaura(); 00046 return aux; 00047 /* 00048 * o incrementa e o restaura neste ponto servem para criar as variveis 00049 * que serao utilizadas pela execucao do procedimento 00050 */ 00051 } 00052 00057 private AmbienteExecucaoImperativa2 bindParameters( 00058 AmbienteExecucaoImperativa2 ambiente, 00059 ListaDeclaracaoParametro parametrosFormais) 00060 throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException { 00061 ListaValor listaValor = parametrosReais.avaliar(ambiente); 00062 while (listaValor.length() > 0) { 00063 ambiente.map(parametrosFormais.getHead().getId(), listaValor.getHead()); 00064 parametrosFormais = (ListaDeclaracaoParametro) parametrosFormais.getTail(); 00065 listaValor = (ListaValor) listaValor.getTail(); 00066 } 00067 return ambiente; 00068 } 00069 00081 public boolean checaTipo(AmbienteCompilacaoImperativa amb) 00082 throws IdentificadorJaDeclaradoException, 00083 IdentificadorNaoDeclaradoException { 00084 AmbienteCompilacaoImperativa2 ambiente = (AmbienteCompilacaoImperativa2) amb; 00085 boolean resposta; 00086 ambiente.incrementa(); 00087 ListaDeclaracaoParametro parametrosFormais = ambiente 00088 .getParametrosProcedimento(nomeProcedimento); 00089 List<Tipo> tiposParametrosReais = parametrosReais.getTipos(ambiente); 00090 // tem o mesmo numero de parametros formais e reais? 00091 if (tiposParametrosReais.size() == parametrosFormais.length()) { 00092 // a funcao tem algum parametro? 00093 if (tiposParametrosReais.isEmpty() 00094 || parametrosFormais.getHead() == null) { 00095 resposta = true; 00096 } else { 00097 resposta = true; 00098 // tem parametros formais de tipos diferentes 00099 // de parametros reais na ordem em que se apresentam? 00100 for (Tipo tipoAtual : tiposParametrosReais) { 00101 if (parametrosFormais == null) 00102 break; 00103 if (!tipoAtual.equals(parametrosFormais.getHead().getTipo())) { 00104 resposta = false; 00105 break; 00106 } 00107 parametrosFormais = (ListaDeclaracaoParametro) parametrosFormais.getTail(); 00108 } 00109 } 00110 } else { 00111 resposta = false; 00112 } 00113 ambiente.restaura(); 00114 return resposta; 00115 } 00116 00117 }