00001 package plp.functional2.util;
00002
00003 import java.lang.reflect.InvocationTargetException;
00004 import java.lang.reflect.Method;
00005 import java.util.ArrayList;
00006 import java.util.HashMap;
00007 import java.util.HashSet;
00008 import java.util.List;
00009 import java.util.Map;
00010 import java.util.Set;
00011
00012 import plp.expressions2.expression.ExpAnd;
00013 import plp.expressions2.expression.ExpConcat;
00014 import plp.expressions2.expression.ExpEquals;
00015 import plp.expressions2.expression.ExpLength;
00016 import plp.expressions2.expression.ExpMenos;
00017 import plp.expressions2.expression.ExpNot;
00018 import plp.expressions2.expression.ExpOr;
00019 import plp.expressions2.expression.ExpSoma;
00020 import plp.expressions2.expression.ExpSub;
00021 import plp.expressions2.expression.Expressao;
00022 import plp.expressions2.expression.Id;
00023 import plp.expressions2.expression.ValorBooleano;
00024 import plp.expressions2.expression.ValorInteiro;
00025 import plp.expressions2.expression.ValorString;
00026 import plp.expressions2.memory.AmbienteExecucao;
00027 import plp.expressions2.memory.VariavelNaoDeclaradaException;
00028 import plp.functional1.declaration.DecVariavel;
00029 import plp.functional1.declaration.DeclaracaoFuncional;
00030 import plp.functional1.expression.IfThenElse;
00031 import plp.functional2.declaration.DecFuncao;
00032 import plp.functional2.expression.Aplicacao;
00033 import plp.functional2.expression.ExpDeclaracao;
00034 import plp.functional2.expression.ValorFuncao;
00035
00043 public class PartialInstantiatorVisitor {
00044 private Map<String, Method> metodosVisit;
00045
00046 private static PartialInstantiatorVisitor instance = null;
00047
00048 protected PartialInstantiatorVisitor() {
00049 metodosVisit = new HashMap<String, Method>();
00050 Method metodos[] = this.getClass().getMethods();
00051 for (Method method : metodos) {
00052 if (method.getName().startsWith("_visit")) {
00053 metodosVisit.put(method.getName(), method);
00054 }
00055 }
00056 }
00057
00058 public static PartialInstantiatorVisitor getInstance() {
00059 if (instance == null) {
00060 instance = new PartialInstantiatorVisitor();
00061 }
00062 return instance;
00063 }
00064
00065 public Expressao visit(Expressao exp, AmbienteExecucao ambiente,
00066 Set<Id> localVariables) {
00067
00068
00069
00070
00071 String methodName = exp.getClass().getName();
00072 methodName = "_visit"
00073 + methodName.substring(methodName.lastIndexOf('.') + 1);
00074
00075 Expressao result = null;
00076
00077 try {
00078
00079 Method m = getMethod(methodName);
00080
00081
00082 result = (Expressao) m.invoke(this, new Object[] { exp, ambiente,
00083 localVariables });
00084 } catch (IllegalAccessException e) {
00085 System.out.println(e.getMessage());
00086 e.printStackTrace();
00087 throw new IllegalStateException(
00088 "Não foi possível executar o método (" + methodName
00089 + "). IllegalAccessException");
00090
00091 } catch (InvocationTargetException e) {
00092 System.out.println(e.getMessage());
00093 e.printStackTrace();
00094
00095 throw new IllegalStateException(
00096 "Não foi possível executar o método (" + methodName
00097 + "). InvocationTargetException");
00098
00099 } catch (NoSuchMethodException e) {
00100 System.out.println(e.getMessage());
00101 e.printStackTrace();
00102
00103 throw new IllegalStateException("O método visit chamado ("
00104 + methodName + ") não foi implementado");
00105 }
00106 return result;
00107 }
00108
00109 private Method getMethod(String name) throws NoSuchMethodException {
00110 Object method = metodosVisit.get(name);
00111 if (method == null)
00112 throw new NoSuchMethodException("O método '" + name
00113 + "' especificado não foi encontrado");
00114 return (Method) method;
00115 }
00116
00117 public Expressao _visitAplicacao(Aplicacao expressao,
00118 AmbienteExecucao ambiente, Set<Id> localVariables) {
00119 List<Expressao> novosValoresReais = new ArrayList<Expressao>(expressao
00120 .getArgsExpressao().size());
00121 Set<Id> novasVariaveisLocais = new HashSet<Id>(localVariables);
00122
00123 Expressao func = expressao.getFunc();
00124 if (func instanceof Id)
00125 novasVariaveisLocais.add((Id) func);
00126
00127 for (Expressao argReal : expressao.getArgsExpressao()) {
00128 Expressao novoArg = visit(argReal, ambiente, novasVariaveisLocais);
00129 novosValoresReais.add(novoArg);
00130 }
00131 Aplicacao resultado = new Aplicacao(func.avaliar(ambiente),
00132 novosValoresReais);
00133
00134 return resultado;
00135 }
00136
00137 public Expressao _visitExpAnd(ExpAnd expressao, AmbienteExecucao ambiente,
00138 Set<Id> localVariables) {
00139
00140 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00141 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00142 ExpAnd resultado = new ExpAnd(esquerda, direita);
00143 return resultado;
00144 }
00145
00146 public Expressao _visitExpConcat(ExpConcat expressao,
00147 AmbienteExecucao ambiente, Set<Id> localVariables) {
00148 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00149 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00150 ExpConcat resultado = new ExpConcat(esquerda, direita);
00151 return resultado;
00152 }
00153
00154 public Expressao _visitExpDeclaracao(ExpDeclaracao expressao,
00155 AmbienteExecucao ambiente, Set<Id> localVariables) {
00156
00157
00158 Set<Id> novasVariaveisLocais = new HashSet<Id>(localVariables);
00159 List<DeclaracaoFuncional> novaListaDeclaracao = new ArrayList<DeclaracaoFuncional>(
00160 expressao.getSeqdecFuncional().size());
00161 for (Object element : expressao.getSeqdecFuncional()) {
00162 DeclaracaoFuncional declaracao = (DeclaracaoFuncional) element;
00163 if (declaracao instanceof DecFuncao) {
00164 DecFuncao novaDec = visitDecFuncao((DecFuncao) declaracao,
00165 ambiente, localVariables);
00166 novaListaDeclaracao.add(novaDec);
00167 } else if (declaracao instanceof DecVariavel) {
00168 DecVariavel novaDec = visitDecVariavel(
00169 (DecVariavel) declaracao, ambiente, localVariables);
00170 novaListaDeclaracao.add(novaDec);
00171 } else
00172 throw new IllegalStateException(
00173 "DeclaracaoFuncional desconhecida em PartialInstantiatorVisitor");
00174 Id idAtual = declaracao.getId();
00175 novasVariaveisLocais.add(idAtual);
00176 }
00177
00178 Expressao novaExpressao = visit(expressao.getExpressao(), ambiente,
00179 novasVariaveisLocais);
00180 ExpDeclaracao resultado = new ExpDeclaracao(novaListaDeclaracao,
00181 novaExpressao);
00182 return resultado;
00183 }
00184
00185 private DecFuncao visitDecFuncao(DecFuncao declaracao,
00186 AmbienteExecucao ambiente, Set<Id> localVariables) {
00187 Set<Id> novasVariaveisLocais = new HashSet<Id>(localVariables);
00188 novasVariaveisLocais.add(declaracao.getId());
00189 ValorFuncao novaExpressao = (ValorFuncao) _visitValorFuncao(declaracao
00190 .getFuncao(), ambiente, novasVariaveisLocais);
00191 DecFuncao resultado = new DecFuncao(declaracao.getId(), novaExpressao);
00192 return resultado;
00193 }
00194
00195 private DecVariavel visitDecVariavel(DecVariavel declaracao,
00196 AmbienteExecucao ambiente, Set<Id> localVariables) {
00197 Set<Id> novasVariaveisLocais = new HashSet<Id>(localVariables);
00198 novasVariaveisLocais.add(declaracao.getId());
00199 Expressao novaExpressao = visit(declaracao.getExpressao(), ambiente,
00200 novasVariaveisLocais);
00201 DecVariavel resultado = new DecVariavel(declaracao.getId(),
00202 novaExpressao);
00203 return resultado;
00204 }
00205
00206 public Expressao _visitExpEquals(ExpEquals expressao,
00207 AmbienteExecucao ambiente, Set<Id> localVariables) {
00208 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00209 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00210 ExpEquals resultado = new ExpEquals(esquerda, direita);
00211 return resultado;
00212 }
00213
00214 public Expressao _visitExpLength(ExpLength expressao,
00215 AmbienteExecucao ambiente, Set<Id> localVariables) {
00216
00217 Expressao expInterna = visit(expressao.getExp(), ambiente,
00218 localVariables);
00219 ExpLength resultado = new ExpLength(expInterna);
00220 return resultado;
00221 }
00222
00223 public Expressao _visitExpMenos(ExpMenos expressao,
00224 AmbienteExecucao ambiente, Set<Id> localVariables) {
00225 Expressao expInterna = visit(expressao.getExp(), ambiente,
00226 localVariables);
00227 ExpMenos resultado = new ExpMenos(expInterna);
00228 return resultado;
00229 }
00230
00231 public Expressao _visitExpNot(ExpNot expressao, AmbienteExecucao ambiente,
00232 Set<Id> localVariables) {
00233 Expressao expInterna = visit(expressao.getExp(), ambiente,
00234 localVariables);
00235 ExpNot resultado = new ExpNot(expInterna);
00236 return resultado;
00237 }
00238
00239 public Expressao _visitExpOr(ExpOr expressao, AmbienteExecucao ambiente,
00240 Set<Id> localVariables) {
00241 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00242 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00243 ExpOr resultado = new ExpOr(esquerda, direita);
00244 return resultado;
00245 }
00246
00247 public Expressao _visitExpSoma(ExpSoma expressao,
00248 AmbienteExecucao ambiente, Set<Id> localVariables) {
00249 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00250 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00251 ExpSoma resultado = new ExpSoma(esquerda, direita);
00252 return resultado;
00253 }
00254
00255 public Expressao _visitExpSub(ExpSub expressao, AmbienteExecucao ambiente,
00256 Set<Id> localVariables) {
00257 Expressao esquerda = visit(expressao.getEsq(), ambiente, localVariables);
00258 Expressao direita = visit(expressao.getDir(), ambiente, localVariables);
00259 ExpSub resultado = new ExpSub(esquerda, direita);
00260 return resultado;
00261 }
00262
00263 public Expressao _visitIfThenElse(IfThenElse expressao,
00264 AmbienteExecucao ambiente, Set<Id> localVariables) {
00265
00266 Expressao condicao = visit(expressao.getCondicao(), ambiente,
00267 localVariables);
00268 Expressao then = visit(expressao.getThen(), ambiente, localVariables);
00269 Expressao elseExpressao = visit(expressao.getElseExpressao(), ambiente,
00270 localVariables);
00271 IfThenElse resultado = new IfThenElse(condicao, then, elseExpressao);
00272 return resultado;
00273 }
00274
00275 public Expressao _visitId(Id thisId, AmbienteExecucao ambiente,
00276 Set<Id> localVariables) {
00277 Expressao resultado;
00278 if (localVariables.contains(thisId)) {
00279 resultado = thisId;
00280 } else {
00281 try {
00282 resultado = thisId.avaliar(ambiente);
00283 } catch (VariavelNaoDeclaradaException e) {
00284 resultado = thisId;
00285 }
00286 }
00287 return resultado;
00288 }
00289
00290 public Expressao _visitValorInteiro(ValorInteiro valor,
00291 AmbienteExecucao ambiente, Set<Id> localVariables) {
00292 return valor;
00293 }
00294
00295 public Expressao _visitValorString(ValorString valor,
00296 AmbienteExecucao ambiente, Set<Id> localVariables) {
00297 return valor;
00298 }
00299
00300 public Expressao _visitValorBooleano(ValorBooleano valor,
00301 AmbienteExecucao ambiente, Set<Id> localVariables) {
00302 return valor;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 public Expressao _visitValorFuncao(ValorFuncao valor,
00315 AmbienteExecucao ambiente, Set<Id> localVariables) {
00316 Set<Id> novasVariaveisLocais = new HashSet<Id>(localVariables);
00317 novasVariaveisLocais.addAll(valor.getListaId());
00318 Expressao novaExpressao = visit(valor.getExp(), ambiente,
00319 novasVariaveisLocais);
00320 ValorFuncao resultado = new ValorFuncao(valor.getListaId(),
00321 novaExpressao);
00322 return resultado;
00323 }
00324
00325 }