00001 package plp.functional3.expression;
00002
00003 import java.util.HashMap;
00004 import java.util.Map;
00005
00006 import plp.expressions1.util.Tipo;
00007 import plp.expressions2.expression.Expressao;
00008 import plp.expressions2.expression.Id;
00009 import plp.expressions2.expression.Valor;
00010 import plp.expressions2.expression.ValorBooleano;
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.util.TipoPolimorfico;
00016 import plp.functional3.util.TipoLista;
00017
00018 public class Gerador {
00019
00020 private Id id;
00021 private Expressao expressao;
00022 private Gerador proximo;
00023
00024 public Gerador(Id id, Expressao expressao) {
00025 this.id = id;
00026 this.expressao = expressao;
00027 }
00028
00029 public Gerador getProximoGerador() {
00030 return proximo;
00031 }
00032
00033 public void addProximoGerador(Gerador gerador) {
00034 if (this.proximo == null) {
00035 this.proximo = gerador;
00036 } else {
00037 this.proximo.addProximoGerador(gerador);
00038 }
00039 }
00040
00041 public void gerarValores(AmbienteExecucao amb, ValorLista resultado,
00042 Expressao expressao, Expressao filtro)
00043 throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
00044
00045
00046
00047 ValorLista temp = (ValorLista) this.expressao.avaliar(amb);
00048
00049
00050 while (temp != null && !temp.isEmpty()) {
00051 amb.incrementa();
00052
00053
00054 Valor valor = temp.getHead().avaliar(amb);
00055 amb.map(this.id, valor);
00056 temp = temp.getTail();
00057
00058
00059
00060
00061 if (getProximoGerador() == null) {
00062 if (filtro == null
00063 || ((ValorBooleano) filtro.avaliar(amb)).valor()) {
00064 resultado.cons(expressao.avaliar(amb));
00065 }
00066 } else {
00067
00068
00069 getProximoGerador().gerarValores(amb, resultado, expressao,
00070 filtro);
00071 }
00072
00073 amb.restaura();
00074 }
00075 }
00076
00077 public boolean temProximoGerador() {
00078 return proximo != null;
00079 }
00080
00081 public Map<Id, Tipo> checkTypeBindings(AmbienteCompilacao amb) {
00082 HashMap<Id, Tipo> tipos = new HashMap<Id, Tipo>();
00083
00084 Tipo tipo = expressao.getTipo(amb);
00085 if (tipo instanceof TipoPolimorfico) {
00086 TipoPolimorfico tp = (TipoPolimorfico) tipo;
00087 tipo = tp.getTipoInstanciado();
00088 }
00089 TipoLista tipoLista = (TipoLista) tipo;
00090 tipos.put(id, tipoLista.getSubTipo());
00091 if (temProximoGerador()) {
00092 tipos.putAll(proximo.checkTypeBindings(amb));
00093 }
00094
00095 return tipos;
00096
00097 }
00098
00099 public boolean checaTipo(AmbienteCompilacao amb) {
00100 return this.expressao.checaTipo(amb)
00101 && (!temProximoGerador() || proximo.checaTipo(amb));
00102 }
00103
00104 }