package loo1.plp.orientadaObjetos1.comando; import loo1.plp.expressions2.memory.VariavelJaDeclaradaException; import loo1.plp.expressions2.memory.VariavelNaoDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException; import loo1.plp.orientadaObjetos1.expressao.Expressao; import loo1.plp.orientadaObjetos1.expressao.leftExpression.AcessoAtributo; import loo1.plp.orientadaObjetos1.expressao.leftExpression.Id; import loo1.plp.orientadaObjetos1.expressao.leftExpression.LeftExpression; import loo1.plp.orientadaObjetos1.expressao.valor.ValorRef; import loo1.plp.orientadaObjetos1.memoria.AmbienteCompilacaoOO1; import loo1.plp.orientadaObjetos1.memoria.AmbienteExecucaoOO1; import loo1.plp.orientadaObjetos1.memoria.Objeto; import loo1.plp.orientadaObjetos1.util.TipoClasse; /** * Classe que representa um comando de atribui��o. */ public class Atribuicao implements Comando { /** * Lado esquerdo do comando de atribui��o. */ protected LeftExpression av; /** * Express�o cujo valor ser� atribu�do ao lado esquerdo. */ protected Expressao expressao; /** * Construtor. * @param av Lado esquerdo * @param expressao Express�o cujo valor ser� atribu�do ao lado esquerdo. */ public Atribuicao(LeftExpression av, Expressao expressao){ this.av = av; this.expressao = expressao; } /** * Executa a atribui��o. * * @param ambiente o ambiente que contem o mapeamento entre identificadores * e valores. * @return o ambiente modificado pela execu��o da atribui��o. * @throws ClasseNaoDeclaradaException * */ public AmbienteExecucaoOO1 executar(AmbienteExecucaoOO1 ambiente) throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException, ObjetoNaoDeclaradoException, ClasseNaoDeclaradaException { Id idVariavel = av.getId(); if ( av instanceof AcessoAtributo){ // se for acesso a atributo, tem de alterar o ambiente do objeto! Expressao expAV = ((AcessoAtributo)av).getExpressaoObjeto(); ValorRef referencia = (ValorRef)expAV.avaliar(ambiente); Objeto obj = ambiente.getObjeto(referencia); obj.changeAtributo(idVariavel, expressao.avaliar(ambiente)); } else ambiente.changeValor(idVariavel, expressao.avaliar(ambiente)); return ambiente; } /** * Um comando de atribui��o est� bem tipado, se o tipo do identificador � * o mesmo da express�o. O tipo de um identificador � determinado pelo * tipo da express�o que o inicializou (na declara��o). * * @param ambiente o ambiente que contem o mapeamento entre identificadores * e valores. * @return true se os tipos da atribui��o s�o v�lidos; * false caso contrario. * */ public boolean checaTipo(AmbienteCompilacaoOO1 ambiente) throws VariavelNaoDeclaradaException, ClasseNaoDeclaradaException { return expressao.checaTipo(ambiente) && (av.getTipo(ambiente).equals(expressao.getTipo(ambiente)) || expressao.getTipo(ambiente).equals(TipoClasse.TIPO_NULL)); } }