00001 package plp.orientadaObjetos1.memoria;
00002
00003 import java.io.BufferedReader;
00004 import java.io.IOException;
00005 import java.io.InputStreamReader;
00006 import java.util.HashMap;
00007 import java.util.Stack;
00008
00009 import plp.expressions2.expression.Id;
00010 import plp.expressions2.memory.VariavelJaDeclaradaException;
00011 import plp.expressions2.memory.VariavelNaoDeclaradaException;
00012 import plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException;
00013 import plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException;
00014 import plp.orientadaObjetos1.excecao.declaracao.ObjetoJaDeclaradoException;
00015 import plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException;
00016 import plp.orientadaObjetos1.excecao.execucao.EntradaInvalidaException;
00017 import plp.orientadaObjetos1.expressao.valor.Valor;
00018 import plp.orientadaObjetos1.expressao.valor.ValorBooleano;
00019 import plp.orientadaObjetos1.expressao.valor.ValorInteiro;
00020 import plp.orientadaObjetos1.expressao.valor.ValorNull;
00021 import plp.orientadaObjetos1.expressao.valor.ValorRef;
00022 import plp.orientadaObjetos1.expressao.valor.ValorString;
00023 import plp.orientadaObjetos1.memoria.colecao.ListaValor;
00024 import plp.orientadaObjetos1.util.Tipo;
00025 import plp.orientadaObjetos1.util.TipoPrimitivo;
00026
00027 public class ContextoExecucaoOO1 implements AmbienteExecucaoOO1 {
00028
00032 private Stack<HashMap<Id, Valor>> pilha;
00033
00037 private HashMap<Id, DefClasse> mapDefClasse;
00038
00043 private Stack<HashMap<ValorRef, Objeto>> pilhaObjeto;
00044
00048 private ListaValor entrada;
00049
00053 private ListaValor saida;
00054
00058 private ValorRef proxRef;
00059
00063 public ContextoExecucaoOO1(){
00064 pilha = new Stack<HashMap<Id, Valor>>();
00065
00066 pilhaObjeto = new Stack<HashMap<ValorRef, Objeto>>();
00067
00068
00069 pilhaObjeto.push(new HashMap<ValorRef, Objeto>());
00070
00071
00072
00073 mapDefClasse = new HashMap<Id, DefClasse>();
00074
00075 this.entrada = null;
00076 this.saida = new ListaValor();
00077 }
00078
00082 public ContextoExecucaoOO1(AmbienteExecucaoOO1 ambiente) throws VariavelJaDeclaradaException{
00083 proxRef = ambiente.getRef();
00084 this.pilhaObjeto = ambiente.getPilhaObjeto();
00085 this.mapDefClasse = ambiente.getMapDefClasse();
00086 this.entrada = ambiente.getEntrada();
00087 this.saida = ambiente.getSaida();
00088 pilha = new Stack<HashMap<Id, Valor>>();
00089 HashMap<Id, Valor> aux = new HashMap<Id, Valor>();
00090 aux.put(new Id("this"), new ValorNull());
00091 pilha.push(aux);
00092
00093 }
00094
00101 public ContextoExecucaoOO1(ListaValor entrada){
00102 pilha = new Stack<HashMap<Id, Valor>>();
00103
00104 pilhaObjeto = new Stack<HashMap<ValorRef, Objeto>>();
00105
00106
00107 pilhaObjeto.push(new HashMap<ValorRef, Objeto>());
00108
00109
00110
00111 mapDefClasse = new HashMap<Id, DefClasse>();
00112
00113 this.entrada = entrada;
00114 this.saida = new ListaValor();
00115 }
00116
00122 public Stack<HashMap<Id, Valor>> getPilha(){
00123 return this.pilha;
00124 }
00125
00131 public HashMap<Id, DefClasse> getMapDefClasse(){
00132 return this.mapDefClasse;
00133 }
00134
00140 public Stack<HashMap<ValorRef, Objeto>> getPilhaObjeto(){
00141 return this.pilhaObjeto;
00142 }
00143
00154 public Valor read(Tipo tipoIdLido) throws EntradaInvalidaException {
00155 String valorLido = leEntrada();
00156 if (valorLido!=null){
00157 valorLido = valorLido.trim();
00158 if (tipoIdLido instanceof TipoPrimitivo){
00159 TipoPrimitivo tipo = (TipoPrimitivo) tipoIdLido;
00160 try {
00161 if (tipo.eBooleano()){
00162 return new ValorBooleano(Boolean.parseBoolean(valorLido));
00163 } else if (tipo.eInteiro()){
00164 return new ValorInteiro(Integer.parseInt(valorLido));
00165 } else if (tipo.eString()){
00166 return new ValorString(valorLido);
00167 }
00168 }
00169 catch(NumberFormatException e){
00170 throw new EntradaInvalidaException("O tipo da entrada e o da variável"+
00171 " a ser lida são diferentes!");
00172 }
00173 }
00174 }
00175 throw new EntradaInvalidaException("O tipo da variável a ser lida não é um tipo Primitivo!");
00176 }
00177
00186 private String leEntrada() throws EntradaInvalidaException{
00187 if(this.entrada==null) {
00188 return leDaEntradaPadrao();
00189 } else {
00190
00191 if(entrada.length()==0) {
00192 throw new EntradaInvalidaException("Número de argumentos menor do que o número de reads!");
00193 }
00194 return leDaListaValor();
00195 }
00196 }
00202 private String leDaEntradaPadrao(){
00203 try {
00204 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
00205 return in.readLine();
00206 }
00207 catch (IOException e){
00208 System.out.println("Erro no valor lido da entrada padrão");
00209 }
00210 return "";
00211 }
00212
00218 private String leDaListaValor(){
00219 String retorno = entrada.getHead().toString();
00220 entrada = (ListaValor)entrada.getTail();
00221 return retorno;
00222 }
00223
00229 public ListaValor getSaida() {
00230 return saida;
00231 }
00232
00238 public ListaValor getEntrada(){
00239 return entrada;
00240 }
00241
00249 public AmbienteExecucaoOO1 write(Valor v){
00250 saida.write(v);
00251 return this;
00252 }
00256 public void incrementa() {
00257 pilha.push(new HashMap<Id, Valor>());
00258
00259
00260
00261
00262 }
00263
00267 public void restaura(){
00268 pilha.pop();
00269
00270
00271 }
00272
00283 public void map(Id idArg, Valor valorId)
00284 throws VariavelJaDeclaradaException {
00285 HashMap<Id, Valor> aux = pilha.peek();
00286 if (aux.put(idArg, valorId) != null) {
00287 throw new VariavelJaDeclaradaException(idArg);
00288 }
00289
00290 }
00291
00302 public void mapDefClasse(Id idArg, DefClasse defClasse)
00303 throws ClasseJaDeclaradaException {
00304 if (this.mapDefClasse.put(idArg, defClasse) != null) {
00305 throw new ClasseJaDeclaradaException(idArg);
00306 }
00307 }
00308
00319 public void mapObjeto(ValorRef valorRef, Objeto objeto)
00320 throws ObjetoJaDeclaradoException {
00321 HashMap<ValorRef, Objeto> aux = pilhaObjeto.peek();
00322 if (aux.put(valorRef, objeto) != null) {
00323 throw new ObjetoJaDeclaradoException(objeto.getClasse());
00324 }
00325 }
00326
00337 public void changeValor(Id idArg, Valor valorId)
00338 throws VariavelNaoDeclaradaException {
00339 Valor result = null;
00340 Stack<HashMap<Id, Valor>> auxStack = new Stack<HashMap<Id, Valor>>();
00341 while (result == null && !pilha.empty()) {
00342 HashMap<Id, Valor> aux = pilha.pop();
00343 auxStack.push(aux);
00344 result = aux.get(idArg);
00345 if(result != null) {
00346 aux.put(idArg, valorId);
00347 break;
00348 }
00349 }
00350 while (!auxStack.empty()) {
00351 pilha.push(auxStack.pop());
00352 }
00353 if (result == null) {
00354 throw new VariavelNaoDeclaradaException(idArg);
00355 }
00356 }
00357
00367 public Valor get( Id idArg )
00368 throws VariavelNaoDeclaradaException {
00369 Valor result = null;
00370 Stack<HashMap<Id, Valor>> auxStack = new Stack<HashMap<Id, Valor>>();
00371 while (result == null && !pilha.empty()) {
00372 HashMap<Id, Valor> aux = pilha.pop();
00373 auxStack.push(aux);
00374 result = aux.get(idArg);
00375 }
00376 while (!auxStack.empty()) {
00377 pilha.push(auxStack.pop());
00378 }
00379 if (result == null) {
00380 throw new VariavelNaoDeclaradaException(idArg);
00381 } else {
00382 return result;
00383 }
00384 }
00385
00386
00396 public DefClasse getDefClasse(Id idArg)
00397 throws ClasseNaoDeclaradaException {
00398 DefClasse result = null;
00399 result = this.mapDefClasse.get(idArg);
00400 return result;
00401 }
00402
00412 public Objeto getObjeto(ValorRef valorRef)
00413 throws ObjetoNaoDeclaradoException {
00414 Objeto result = null;
00415 Stack<HashMap<ValorRef, Objeto>> auxStack = new Stack<HashMap<ValorRef, Objeto>>();
00416 while (result == null && !pilhaObjeto.empty()) {
00417 HashMap<ValorRef, Objeto> aux = pilhaObjeto.pop();
00418 auxStack.push(aux);
00419 result = aux.get(valorRef);
00420 }
00421 while (!auxStack.empty()) {
00422 pilhaObjeto.push(auxStack.pop());
00423 }
00424 if (result == null) {
00425 throw new ObjetoNaoDeclaradoException(new Id(valorRef.toString()));
00426 } else {
00427 return result;
00428 }
00429 }
00430
00436 public ValorRef getProxRef() {
00437 ValorRef aux = new ValorRef(proxRef.valor());
00438 proxRef = proxRef.incrementa();
00439 return aux;
00440 }
00441
00447 public ValorRef getRef() {
00448 if (proxRef == null)
00449 proxRef = new ValorRef(ValorRef.VALOR_INICIAL);
00450 return proxRef;
00451 }
00452
00458 public String toString() {
00459 String resposta = null;
00460 Valor valor = null;
00461 Objeto objeto = null;
00462 Stack<HashMap<Id, Valor>> auxStack = new Stack<HashMap<Id, Valor>>();
00463 Stack<HashMap<ValorRef, Objeto>> auxStackObjeto = new Stack<HashMap<ValorRef, Objeto>>();
00464
00465 while (!pilha.empty()) {
00466 HashMap<Id, Valor> aux = pilha.pop();
00467 auxStack.push(aux);
00468 for (Id id : aux.keySet()) {
00469 valor = aux.get(id);
00470 resposta = id + " " + valor + "\n";
00471 }
00472 }
00473 while (!auxStack.empty()) {
00474 pilha.push(auxStack.pop());
00475 }
00476 while (!pilhaObjeto.empty()) {
00477 HashMap<ValorRef, Objeto> aux = pilhaObjeto.pop();
00478 auxStackObjeto.push(aux);
00479 for(ValorRef valorRef : aux.keySet()) {
00480 objeto = aux.get(valorRef);
00481 resposta = valorRef + " " + objeto + "\n";
00482 }
00483 }
00484 while (!auxStackObjeto.empty()) {
00485 pilhaObjeto.push(auxStackObjeto.pop());
00486 }
00487 return resposta;
00488 }
00489
00497 public ContextoExecucaoOO1 getContextoIdValor() {
00498 ContextoExecucaoOO1 ambiente = new ContextoExecucaoOO1(this.getEntrada());
00499 ambiente.pilha = this.pilha;
00500 ambiente.saida = this.saida;
00501 return ambiente;
00502 }
00503
00504 }