ExpDeclaracao.java

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

Generated on Tue Jul 18 22:04:30 2006 for PLP by  doxygen 1.4.7