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.Enumeration;
00007
00008 import plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException;
00009 import plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException;
00010 import plp.orientadaObjetos1.excecao.declaracao.ObjetoJaDeclaradoException;
00011 import plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException;
00012 import plp.orientadaObjetos1.excecao.declaracao.VariavelJaDeclaradaException;
00013 import plp.orientadaObjetos1.excecao.declaracao.VariavelNaoDeclaradaException;
00014 import plp.orientadaObjetos1.excecao.execucao.EntradaInvalidaException;
00015 import plp.orientadaObjetos1.expressao.leftExpression.Id;
00016 import plp.orientadaObjetos1.expressao.valor.Valor;
00017 import plp.orientadaObjetos1.expressao.valor.ValorBooleano;
00018 import plp.orientadaObjetos1.expressao.valor.ValorInteiro;
00019 import plp.orientadaObjetos1.expressao.valor.ValorNull;
00020 import plp.orientadaObjetos1.expressao.valor.ValorRef;
00021 import plp.orientadaObjetos1.expressao.valor.ValorString;
00022 import plp.orientadaObjetos1.memoria.colecao.HashIdDefClasse;
00023 import plp.orientadaObjetos1.memoria.colecao.HashIdValor;
00024 import plp.orientadaObjetos1.memoria.colecao.HashTipoTipo;
00025 import plp.orientadaObjetos1.memoria.colecao.HashValorObjeto;
00026 import plp.orientadaObjetos1.memoria.colecao.ListaValor;
00027 import plp.orientadaObjetos1.memoria.colecao.StackHashIdDefClasse;
00028 import plp.orientadaObjetos1.memoria.colecao.StackHashIdValor;
00029 import plp.orientadaObjetos1.memoria.colecao.StackHashTipoTipo;
00030 import plp.orientadaObjetos1.memoria.colecao.StackHashValorObjeto;
00031 import plp.orientadaObjetos1.util.Tipo;
00032 import plp.orientadaObjetos1.util.TipoPrimitivo;
00033
00034 public class ContextoExecucao implements AmbienteExecucao {
00035
00039 private StackHashIdValor pilha;
00040
00044 private StackHashTipoTipo pilhaTipoReal;
00045
00049 private StackHashIdDefClasse pilhaDefClasse;
00050
00055 private StackHashValorObjeto pilhaObjeto;
00056
00060 private ListaValor entrada;
00061
00065 private ListaValor saida;
00066
00070 private ValorRef proxRef;
00071
00075 public ContextoExecucao(){
00076 pilha = new StackHashIdValor();
00077 pilhaTipoReal = new StackHashTipoTipo();
00078
00079 pilhaObjeto = new StackHashValorObjeto();
00080 pilhaObjeto.push(new HashValorObjeto());
00081
00082 pilhaDefClasse = new StackHashIdDefClasse();
00083 pilhaDefClasse.push(new HashIdDefClasse());
00084
00085 this.entrada = null;
00086 this.saida = new ListaValor();
00087 }
00088
00092 public ContextoExecucao(AmbienteExecucao ambiente) throws VariavelJaDeclaradaException{
00093 this.proxRef = ambiente.getRef();
00094 this.pilhaObjeto = ambiente.getPilhaObjeto();
00095 this.pilhaDefClasse = ambiente.getPilhaDefClasse();
00096 this.entrada = ambiente.getEntrada();
00097 this.saida = ambiente.getSaida();
00098 pilhaTipoReal = ambiente.getPilhaTipoTipo();
00099 pilha = new StackHashIdValor();
00100 HashIdValor aux = new HashIdValor();
00101 aux.put(new Id("this"), new ValorNull());
00102 pilha.push(aux);
00103
00104 }
00105
00110 public ContextoExecucao(ListaValor entrada){
00111 pilha = new StackHashIdValor();
00112 pilhaTipoReal = new StackHashTipoTipo();
00113
00114 pilhaObjeto = new StackHashValorObjeto();
00115 pilhaObjeto.push(new HashValorObjeto());
00116
00117 pilhaDefClasse = new StackHashIdDefClasse();
00118 pilhaDefClasse.push(new HashIdDefClasse());
00119
00120 this.entrada = entrada;
00121 this.saida = new ListaValor();
00122 }
00123
00128 public StackHashIdValor getPilha(){
00129 return this.pilha;
00130 }
00131
00136 public StackHashTipoTipo getPilhaTipoTipo(){
00137 return this.pilhaTipoReal;
00138 }
00139
00144 public StackHashIdDefClasse getPilhaDefClasse(){
00145 return this.pilhaDefClasse;
00146 }
00147
00152 public StackHashValorObjeto getPilhaObjeto(){
00153 return this.pilhaObjeto;
00154 }
00155
00164 public Valor read(Tipo tipoIdLido) throws EntradaInvalidaException {
00165 String valorLido = leEntrada(tipoIdLido);
00166 if (valorLido!=null){
00167 valorLido = valorLido.trim();
00168 if (tipoIdLido instanceof TipoPrimitivo){
00169 TipoPrimitivo tipo = (TipoPrimitivo) tipoIdLido;
00170 try {
00171 if (tipo.eBooleano()){
00172 return new ValorBooleano(Boolean.getBoolean(valorLido));
00173 } else if (tipo.eInteiro()){
00174 return new ValorInteiro(Integer.parseInt(valorLido));
00175 } else if (tipo.eString()){
00176 return new ValorString(valorLido);
00177 }
00178 }
00179 catch(NumberFormatException e){
00180 throw new EntradaInvalidaException("O tipo da entrada e o da variável"+
00181 " a ser lida são diferentes!");
00182 }
00183 }
00184 }
00185 throw new EntradaInvalidaException("O tipo da variável a ser lida não é um tipo Primitivo!");
00186 }
00187
00193 private String leEntrada(Tipo tipoIdLido) throws EntradaInvalidaException{
00194 if(this.entrada==null) {
00195 return leDaEntradaPadrao(tipoIdLido);
00196 } else {
00197
00198 if(entrada.length()==0) {
00199 throw new EntradaInvalidaException("Número de argumentos menor do que o número de reads!");
00200 }
00201 return leDaListaValor();
00202 }
00203 }
00208 private String leDaEntradaPadrao(Tipo tipoIdLido){
00209 try {
00210 System.out.println("Digite um " +tipoIdLido.toString());
00211 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
00212 return in.readLine();
00213 }
00214 catch (IOException e){
00215 System.out.println("Erro no valor lido da entrada padrão");
00216 }
00217 return "";
00218 }
00219
00224 private String leDaListaValor(){
00225 String retorno = entrada.head().toString();
00226 entrada = entrada.tail();
00227 return retorno;
00228 }
00229
00234 public ListaValor getSaida() {
00235 return saida;
00236 }
00237
00242 public ListaValor getEntrada(){
00243 return entrada;
00244 }
00245
00251 public AmbienteExecucao write(Valor v){
00252 saida.write(v);
00253 return this;
00254 }
00258 public void incrementa() {
00259 pilha.push(new HashIdValor());
00260 pilhaTipoReal.push(new HashTipoTipo());
00261
00262
00263 }
00264
00268 public void restaura(){
00269 pilha.pop();
00270 pilhaTipoReal.pop();
00271
00272
00273 }
00274
00282 public void mapValor(Id idArg, Valor valorId)
00283 throws VariavelJaDeclaradaException {
00284 HashIdValor aux = pilha.peek();
00285 if (aux.put(idArg, valorId) != null) {
00286 throw new VariavelJaDeclaradaException(idArg);
00287 }
00288 }
00289
00296 public void mapTipoReal(Tipo tipoGeneric, Tipo tipoReal)
00297 throws ClasseJaDeclaradaException {
00298 HashTipoTipo aux = pilhaTipoReal.peek();
00299 if (aux.put(tipoGeneric, tipoReal) != null) {
00300 throw new ClasseJaDeclaradaException(tipoGeneric.getTipo());
00301 }
00302 }
00303
00304
00311 public void mapDefClasse(Id idArg, DefClasse defClasse)
00312 throws ClasseJaDeclaradaException {
00313 HashIdDefClasse aux = (HashIdDefClasse)pilhaDefClasse.peek();
00314 if (aux.put(idArg, defClasse) != null) {
00315 throw new ClasseJaDeclaradaException(idArg);
00316 }
00317 }
00318
00325 public void mapObjeto(ValorRef valorRef, Objeto objeto)
00326 throws ObjetoJaDeclaradoException {
00327 HashValorObjeto aux = pilhaObjeto.peek();
00328 if (aux.put(valorRef, objeto) != null) {
00329 throw new ObjetoJaDeclaradoException(objeto.getClasse());
00330 }
00331 }
00332
00340 public void changeValor(Id idArg, Valor valorId)
00341 throws VariavelNaoDeclaradaException {
00342 Valor result = null;
00343 StackHashIdValor auxStack = new StackHashIdValor();
00344 while (result == null && !pilha.empty()) {
00345 HashIdValor aux = pilha.pop();
00346 auxStack.push(aux);
00347 result = aux.get(idArg);
00348 if(result != null) {
00349 aux.change(idArg, valorId);
00350 break;
00351 }
00352 }
00353 while (!auxStack.empty()) {
00354 pilha.push(auxStack.pop());
00355 }
00356 if (result == null) {
00357 throw new VariavelNaoDeclaradaException(idArg);
00358 }
00359 }
00360
00368 public Valor getValor( Id idArg )
00369 throws VariavelNaoDeclaradaException {
00370 Valor result = null;
00371 StackHashIdValor auxStack = new StackHashIdValor();
00372 while (result == null && !pilha.empty()) {
00373 HashIdValor aux = pilha.pop();
00374 auxStack.push(aux);
00375 result = aux.get(idArg);
00376 }
00377 while (!auxStack.empty()) {
00378 pilha.push(auxStack.pop());
00379 }
00380 if (result == null) {
00381 throw new VariavelNaoDeclaradaException(idArg);
00382 } else {
00383 return result;
00384 }
00385 }
00386
00393 public Tipo getTipoReal( Tipo tipoGeneric)
00394 throws ClasseNaoDeclaradaException {
00395 Tipo result = null;
00396 StackHashTipoTipo auxStack = new StackHashTipoTipo();
00397 while (result == null && !pilhaTipoReal.empty()) {
00398 HashTipoTipo aux = pilhaTipoReal.pop();
00399 auxStack.push(aux);
00400 result = aux.get(tipoGeneric);
00401 }
00402 while (!auxStack.empty()) {
00403 pilhaTipoReal.push(auxStack.pop());
00404 }
00405 if (result == null) {
00406 throw new ClasseNaoDeclaradaException(tipoGeneric.getTipo());
00407 } else {
00408 return result;
00409 }
00410 }
00411
00412
00420 public DefClasse getDefClasse(Id idArg)
00421 throws ClasseNaoDeclaradaException {
00422 DefClasse result = null;
00423 StackHashIdDefClasse auxStack = new StackHashIdDefClasse();
00424 while (result == null && !pilhaDefClasse.empty()) {
00425 HashIdDefClasse aux = pilhaDefClasse.pop();
00426 auxStack.push(aux);
00427 result = aux.get(idArg);
00428 }
00429 while (!auxStack.empty()) {
00430 pilhaDefClasse.push(auxStack.pop());
00431 }
00432 if (result == null) {
00433 throw new ClasseNaoDeclaradaException(idArg);
00434 } else {
00435 return result;
00436 }
00437 }
00438
00439
00440
00447 public Objeto getObjeto(ValorRef valorRef)
00448 throws ObjetoNaoDeclaradoException {
00449 Objeto result = null;
00450 StackHashValorObjeto auxStack = new StackHashValorObjeto();
00451 while (result == null && !pilhaObjeto.empty()) {
00452 HashValorObjeto aux = pilhaObjeto.pop();
00453 auxStack.push(aux);
00454 result = aux.get(valorRef);
00455 }
00456 while (!auxStack.empty()) {
00457 pilhaObjeto.push(auxStack.pop());
00458 }
00459 if (result == null) {
00460 throw new ObjetoNaoDeclaradoException(new Id(valorRef.toString()));
00461 } else {
00462 return result;
00463 }
00464 }
00465
00470 public ValorRef getProxRef() {
00471 ValorRef aux = new ValorRef(proxRef.valor());
00472 proxRef = proxRef.incrementa();
00473 return aux;
00474 }
00475
00480 public ValorRef getRef() {
00481 if (proxRef == null)
00482 proxRef = new ValorRef(proxRef.VALOR_INICIAL);
00483 return proxRef;
00484 }
00485
00490 public String toString() {
00491 String resposta = null;
00492 Valor valor = null;
00493 ValorRef valorRef = null;
00494 Objeto objeto = null;
00495 Id id = null;
00496 StackHashIdValor auxStack = new StackHashIdValor();
00497 StackHashValorObjeto auxStackObjeto = new StackHashValorObjeto();
00498
00499 while (!pilha.empty()) {
00500 HashIdValor aux = pilha.pop();
00501 auxStack.push(aux);
00502 Enumeration enumeration = aux.keys();
00503 while(enumeration.hasMoreElements()) {
00504 id = (Id)enumeration.nextElement();
00505 valor = aux.get(id);
00506 resposta = id + " " + valor + "\n";
00507 }
00508 }
00509 while (!auxStack.empty()) {
00510 pilha.push(auxStack.pop());
00511 }
00512 while (!pilhaObjeto.empty()) {
00513 HashValorObjeto aux = pilhaObjeto.pop();
00514 auxStackObjeto.push(aux);
00515 Enumeration enumeration = aux.keys();
00516 while(enumeration.hasMoreElements()) {
00517 valorRef = (ValorRef)enumeration.nextElement();
00518 objeto = aux.get(valorRef);
00519 resposta = valorRef + " " + objeto + "\n";
00520 }
00521 }
00522 while (!auxStackObjeto.empty()) {
00523 pilhaObjeto.push(auxStackObjeto.pop());
00524 }
00525 return resposta;
00526 }
00527
00534 public ContextoExecucao getContextoIdValor() {
00535 ContextoExecucao ambiente = new ContextoExecucao(this.getEntrada());
00536 ambiente.pilha = this.pilha;
00537 ambiente.saida = this.saida;
00538 return ambiente;
00539 }
00540 }