ExpDeclaracao.java

Go to the documentation of this file.
00001 //Mudar o for do iterator para o novo for.
00002 package plp.functional1.expression;
00003 
00004 import java.util.HashMap;
00005 import java.util.List;
00006 import java.util.Map;
00007 
00008 import plp.expressions1.util.Tipo;
00009 import plp.expressions2.expression.Expressao;
00010 import plp.expressions2.expression.Id;
00011 import plp.expressions2.expression.Valor;
00012 import plp.expressions2.memory.AmbienteCompilacao;
00013 import plp.expressions2.memory.AmbienteExecucao;
00014 import plp.expressions2.memory.VariavelJaDeclaradaException;
00015 import plp.expressions2.memory.VariavelNaoDeclaradaException;
00016 import plp.functional1.declaration.DecFuncao;
00017 import plp.functional1.declaration.DeclaracaoFuncional;
00018 import plp.functional1.memory.AmbienteExecucaoFuncional;
00019 import plp.functional1.util.ValorFuncao;
00020 
00021 public class ExpDeclaracao implements Expressao {
00022 
00023         List<DeclaracaoFuncional> seqdecFuncional;
00024         Expressao expressao;
00025 
00026         public ExpDeclaracao(List<DeclaracaoFuncional> declaracoesFuncionais, Expressao expressaoArg) {
00027                 seqdecFuncional = declaracoesFuncionais;
00028                 expressao = expressaoArg;
00029         }
00030 
00036         public String toString() {
00037                 StringBuffer sb = new StringBuffer();
00038                 sb.append("let ");
00039                 sb.append(seqdecFuncional.toString());
00040                 sb.append("\nin\n");
00041                 sb.append(expressao.toString());
00042                 return sb.toString();
00043         }
00044 
00045         public Valor avaliar(AmbienteExecucao ambienteFuncional)
00046                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00047                 AmbienteExecucaoFuncional ambiente =
00048                         (AmbienteExecucaoFuncional) ambienteFuncional;
00049                 ambiente.incrementa();
00050 
00051                 // Como declaracoes feitas neste nivel nao devem ter influencia
00052                 // mutua, armazenamos os valores em uma tabela auxiliar, para depois
00053                 // fazer o mapeamento.
00054                 Map<Id,Valor> auxIdValor = new HashMap<Id,Valor>();
00055                 Map<Id,ValorFuncao> auxIdValorFuncao = new HashMap<Id,ValorFuncao>();
00056 
00057                 resolveBindings(ambiente, auxIdValor, auxIdValorFuncao);
00058 
00059                 includeBindings(ambiente, auxIdValor, auxIdValorFuncao);
00060 
00061                 Valor vresult = expressao.avaliar(ambiente);
00062                 ambiente.restaura();
00063                 return vresult;
00064         }
00065 
00066         private void includeBindings(
00067                 AmbienteExecucaoFuncional ambiente,
00068                 Map<Id,Valor> auxIdValor,
00069                 Map<Id,ValorFuncao> auxIdValorFuncao)
00070                 throws VariavelJaDeclaradaException {
00071         
00072                 for(Map.Entry<Id,Valor> idValor:auxIdValor.entrySet()){
00073                         Id id = (Id) idValor.getKey();
00074                         Valor valor = (Valor) idValor.getValue();
00075                         ambiente.map(id, valor);
00076                 }
00077                 
00078                 for(Map.Entry<Id,ValorFuncao> idValorFuncao:auxIdValorFuncao.entrySet()){
00079                         Id id = (Id) idValorFuncao.getKey();
00080                         ValorFuncao valor = (ValorFuncao) idValorFuncao.getValue();
00081                         ambiente.mapFuncao(id, valor);
00082                 }       
00083         }
00084 
00085         private void resolveBindings(
00086                 AmbienteExecucaoFuncional ambiente,
00087                 Map<Id,Valor> auxIdValor,
00088                 Map<Id,ValorFuncao> auxIdValorFuncao)
00089                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00090                         
00091                 for(DeclaracaoFuncional decFuncional:this.seqdecFuncional){
00092                         if (decFuncional.getAridade() == 0) {
00093                                 auxIdValor.put(
00094                                         decFuncional.getID(),
00095                                         decFuncional.getExpressao().avaliar(ambiente));
00096                         } else {
00097                                 DecFuncao decFuncao = (DecFuncao) decFuncional;
00098                                 ValorFuncao valorFuncao = decFuncao.getFuncao();
00099                                 auxIdValorFuncao.put(decFuncional.getID(), valorFuncao);
00100                         }                       
00101                 }
00102         }
00103 
00115         public boolean checaTipo(AmbienteCompilacao ambiente)
00116                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00117                 ambiente.incrementa();
00118 
00119                 boolean result = false;
00120                 try {
00121                         result = checkTypeBindings(ambiente);
00122                         if (result) {
00123                                 Map<Id,Tipo> resolvedTypes = resolveTypeBidings(ambiente);
00124                                 includeTypeBindings(ambiente,resolvedTypes);            
00125                                 result = expressao.checaTipo(ambiente);
00126                         }
00127                 } finally {
00128                         ambiente.restaura();                            
00129                 }
00130                 return result;
00131         }
00132 
00133         private Map<Id,Tipo> resolveTypeBidings(AmbienteCompilacao ambiente)
00134                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00135                 Map<Id,Tipo> resolvedTypes = new HashMap<Id,Tipo>();
00136                 
00137                 for(DeclaracaoFuncional decFuncional:this.seqdecFuncional){
00138                         if (resolvedTypes.put(decFuncional.getID(),decFuncional.getTipo(ambiente)) != null) {
00139                                 throw new VariavelJaDeclaradaException (decFuncional.getID());
00140                         }
00141                 }
00142                 return resolvedTypes;
00143         }
00144 
00145         private boolean checkTypeBindings(AmbienteCompilacao ambiente)
00146                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00147                 boolean result = true;
00148                 for(DeclaracaoFuncional decFuncional:this.seqdecFuncional){
00149                         if (!decFuncional.checaTipo(ambiente)) {
00150                                 ambiente.restaura();
00151                                 result = false;
00152                         }                       
00153                 }       
00154                 return result;
00155         }
00156 
00157 
00158         private void includeTypeBindings(AmbienteCompilacao ambiente, Map<Id,Tipo> resolvedTypes)
00159                         throws VariavelJaDeclaradaException {
00160                 for(Id id:resolvedTypes.keySet()){
00161                         Tipo type = (Tipo) resolvedTypes.get(id);
00162                         ambiente.map(id, type);
00163                 }
00164         }
00165 
00177         public Tipo getTipo(AmbienteCompilacao ambiente)
00178                 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00179                 ambiente.incrementa();
00180                 for(DeclaracaoFuncional decFuncional:this.seqdecFuncional){
00181                         if (decFuncional.getAridade() == 0) {
00182                                 ambiente.map(
00183                                         decFuncional.getID(),
00184                                         decFuncional.getExpressao().getTipo(ambiente));
00185                         } else {
00186                                 DecFuncao decFuncao = (DecFuncao) decFuncional;
00187                                 Tipo tipo = decFuncao.getFuncao().getTipo(ambiente);
00188                                 if (tipo != Tipo.TIPO_INDEFINIDO) {
00189                                         ambiente.map(decFuncional.getID(), tipo);
00190                                 }
00191                         }
00192                 }
00193                 Tipo vresult = expressao.getTipo(ambiente);
00194                 ambiente.restaura();
00195                 return vresult;
00196         }
00197 
00202         public List<DeclaracaoFuncional> getSeqdecFuncional() {
00203                 return seqdecFuncional;
00204         }
00205 
00210         public Expressao getExpressao() {
00211                 return expressao;
00212         }
00213 
00214 }

Generated on Tue Sep 12 21:52:02 2006 for PLP by  doxygen 1.4.7