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