00001 package plp.expressions2.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.declaration.DecVariavel; 00009 import plp.expressions2.memory.AmbienteCompilacao; 00010 import plp.expressions2.memory.AmbienteExecucao; 00011 import plp.expressions2.memory.VariavelJaDeclaradaException; 00012 import plp.expressions2.memory.VariavelNaoDeclaradaException; 00013 00014 public class ExpDeclaracao implements Expressao{ 00015 00016 List<DecVariavel> seqdecVariavel; 00017 Expressao expressao; 00018 00019 public ExpDeclaracao(List<DecVariavel> declarations, Expressao expressaoArg){ 00020 seqdecVariavel = declarations; 00021 expressao = expressaoArg; 00022 } 00023 00024 public Valor avaliar(AmbienteExecucao ambiente) throws VariavelNaoDeclaradaException,VariavelJaDeclaradaException { 00025 00026 ambiente.incrementa(); 00027 Map<Id,Valor> resolvedValues = resolveValueBindings(ambiente); 00028 includeValueBindings(ambiente, resolvedValues); 00029 Valor result = expressao.avaliar(ambiente); 00030 ambiente.restaura(); 00031 00032 return result; 00033 } 00034 00035 private void includeValueBindings(AmbienteExecucao ambiente, Map<Id,Valor> resolvedValues) 00036 throws VariavelJaDeclaradaException { 00037 for (Id id : resolvedValues.keySet() ){ 00038 Valor valor = (Valor)resolvedValues.get(id); 00039 ambiente.map(id, valor); 00040 } 00041 } 00042 00043 private Map<Id,Valor> resolveValueBindings(AmbienteExecucao ambiente) 00044 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException { 00045 00046 Map<Id,Valor> resolvedValues = new HashMap<Id,Valor>(); 00047 00048 for(DecVariavel declaration : this.seqdecVariavel ){ 00049 resolvedValues.put(declaration.getID(), declaration.getExpressao().avaliar(ambiente) ); 00050 } 00051 return resolvedValues; 00052 } 00053 00065 public boolean checaTipo(AmbienteCompilacao ambiente) throws 00066 VariavelNaoDeclaradaException,VariavelJaDeclaradaException { 00067 ambiente.incrementa(); 00068 Map<Id,Tipo> resolvedTypes; 00069 boolean result = false; 00070 try { 00071 if (this.checkTypeBindings(ambiente)) { 00072 resolvedTypes = this.resolveTypeBindings(ambiente); 00073 this.includeTypeBindings(ambiente, resolvedTypes); 00074 result = expressao.checaTipo(ambiente); 00075 } 00076 else { 00077 result = false; 00078 } 00079 } finally { 00080 ambiente.restaura(); 00081 } 00082 return result; 00083 } 00084 00085 private void includeTypeBindings(AmbienteCompilacao ambiente, Map<Id,Tipo> resolvedTypes) 00086 throws VariavelJaDeclaradaException { 00087 00088 for(Id id:resolvedTypes.keySet()){ 00089 Tipo type = (Tipo) resolvedTypes.get(id); 00090 ambiente.map(id, type); 00091 } 00092 } 00093 00094 private Map<Id,Tipo> resolveTypeBindings(AmbienteCompilacao ambiente) 00095 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException { 00096 00097 Map<Id,Tipo> resolvedTypes = new HashMap<Id,Tipo>(); 00098 00099 for(DecVariavel declaration :this.seqdecVariavel ){ 00100 if (resolvedTypes.put(declaration.getID(), declaration.getExpressao().getTipo(ambiente) ) != null) { 00101 throw new VariavelJaDeclaradaException (declaration.getID()); 00102 } 00103 00104 } 00105 00106 return resolvedTypes; 00107 } 00108 00109 private boolean checkTypeBindings (AmbienteCompilacao ambiente) 00110 throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException { 00111 00112 boolean result = true; 00113 DecVariavel decVariavel; 00114 00115 00116 for(DecVariavel declaration:this.seqdecVariavel){ 00117 if (!declaration.getExpressao().checaTipo(ambiente)) { 00118 result = false; 00119 break; 00120 } 00121 } 00122 return result; 00123 } 00124 00135 public Tipo getTipo(AmbienteCompilacao ambiente) throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException { 00136 ambiente.incrementa(); 00137 00138 Map<Id,Tipo> resolvedTypes = this.resolveTypeBindings(ambiente); 00139 this.includeTypeBindings(ambiente, resolvedTypes); 00140 Tipo result = expressao.getTipo(ambiente); 00141 00142 ambiente.restaura(); 00143 return result; 00144 } 00145 00146 }