Skip to content

Commit 100a8b5

Browse files
authored
Merge pull request #5 from nathaliafab/op_ternario
Adicionado operador ternário
2 parents 01e1d2b + 90222cd commit 100a8b5

12 files changed

Lines changed: 313 additions & 19 deletions

File tree

Imperativa1/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<directory>src</directory>
1515
<excludes>
1616
<exclude>**/*.java</exclude>
17+
<exclude>**/*.jj</exclude>
1718
</excludes>
1819
</resource>
1920
</resources>

Imperativa1/run_tests.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ for TEST_FILE in "$TEST_DIR"/*; do
6969

7070
# Verificação de Sucesso ou Falha Esperada
7171
# Remove as linhas indesejadas e também remove a string do Parser do começo para extrair só a mensagem útil ou os outputs.
72-
ACTUAL_OUT=$(grep -vE "\[INFO\]|\[WARNING\]|WARNING:|sun.misc.Unsafe|Reading from file|parsed successfully" "$TMP_OUT" | sed -E 's/Imperativa 1 PLP Parser Version [0-9\.]+:[ \t]*//g' | tr '\n' ' ' | xargs)
73-
EXPECTED_OUT=$(echo "$EXPECTED_OUT" | xargs)
72+
ACTUAL_OUT=$(grep -vE "\[INFO\]|\[WARNING\]|WARNING:|sun.misc.Unsafe|Reading from file|parsed successfully" "$TMP_OUT" | sed -E 's/Imperativa 1 PLP Parser Version [0-9\.]+:[ \t]*//g' | tr '\n' ' ' | tr -d '\r' | xargs)
73+
EXPECTED_OUT=$(echo "$EXPECTED_OUT" | tr -d '\r' | xargs)
7474

7575
if [ -n "$EXPECTED_OUT" ]; then
7676
# Removemos logs desnecessarios e checamos se a saida contem ou eh igual ao esperado

Imperativa1/src/li1/plp/expressions1/util/TipoOptional.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public boolean eValido() {
5959
}
6060

6161
public Tipo intersecao(Tipo outroTipo) {
62+
if (this.eIgual(outroTipo)) {
63+
return this;
64+
}
6265
return null;
6366
}
6467

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package li1.plp.expressions2.expression;
2+
3+
import li1.plp.expressions1.util.Tipo;
4+
import li1.plp.expressions2.memory.AmbienteCompilacao;
5+
import li1.plp.expressions2.memory.AmbienteExecucao;
6+
import li1.plp.expressions2.memory.VariavelJaDeclaradaException;
7+
import li1.plp.expressions2.memory.VariavelNaoDeclaradaException;
8+
9+
public class ExpOpTernario extends ExpTernaria {
10+
11+
public ExpOpTernario(Expressao teste, Expressao thenExpressao,
12+
Expressao elseExpressao) {
13+
super(teste, thenExpressao, elseExpressao, "?", ":");
14+
}
15+
16+
public Valor avaliar(AmbienteExecucao ambiente)
17+
throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
18+
if (((ValorBooleano) getEsq().avaliar(ambiente)).valor())
19+
return getMei().avaliar(ambiente);
20+
else
21+
return getDir().avaliar(ambiente);
22+
}
23+
24+
/**
25+
* Realiza a verificacao de tipos desta expressao.
26+
*/
27+
@Override
28+
protected boolean checaTipoElementoTerminal(AmbienteCompilacao amb)
29+
throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
30+
Tipo condicaoTipo = getEsq().getTipo(amb);
31+
Tipo thenTipo = getMei().getTipo(amb);
32+
Tipo elseTipo = getDir().getTipo(amb);
33+
34+
boolean tiposIguais = thenTipo.eIgual(elseTipo) || thenTipo.eIgual(li1.plp.expressions1.util.TipoPrimitivo.NULO) || elseTipo.eIgual(li1.plp.expressions1.util.TipoPrimitivo.NULO);
35+
return condicaoTipo.eBooleano() && tiposIguais;
36+
}
37+
38+
/**
39+
* Retorna os tipos possiveis desta expressao.
40+
*/
41+
public Tipo getTipo(AmbienteCompilacao amb)
42+
throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
43+
Tipo thenTipo = getMei().getTipo(amb);
44+
Tipo elseTipo = getDir().getTipo(amb);
45+
46+
// Se o ramo 'then' for nulo, o tipo resultante é opcional do tipo do ramo 'else'
47+
if (thenTipo != null && thenTipo.eIgual(li1.plp.expressions1.util.TipoPrimitivo.NULO)) {
48+
return new li1.plp.expressions1.util.TipoOptional(elseTipo);
49+
}
50+
51+
// Se o ramo 'else' for nulo, o tipo resultante é opcional do tipo do ramo 'then'
52+
if (elseTipo != null && elseTipo.eIgual(li1.plp.expressions1.util.TipoPrimitivo.NULO)) {
53+
return new li1.plp.expressions1.util.TipoOptional(thenTipo);
54+
}
55+
56+
// Se nenhum for nulo, segue a lógica normal de interseção
57+
return thenTipo.intersecao(elseTipo);
58+
}
59+
60+
@Override
61+
public String toString() {
62+
return String.format("(%s) ? (%s) : (%s)", getEsq(), getMei(),
63+
getDir());
64+
}
65+
66+
public ExpOpTernario clone() {
67+
return new ExpOpTernario(getEsq().clone(), getMei().clone(), getDir().clone());
68+
}
69+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package li1.plp.expressions2.expression;
2+
3+
import li1.plp.expressions2.memory.AmbienteCompilacao;
4+
import li1.plp.expressions2.memory.AmbienteExecucao;
5+
import li1.plp.expressions2.memory.VariavelJaDeclaradaException;
6+
import li1.plp.expressions2.memory.VariavelNaoDeclaradaException;
7+
8+
/**
9+
* Uma expressao ternaria contem tres expressoes e dois operadores. Ha uma ordem
10+
* definida entre estas sub-expressoes
11+
*/
12+
public abstract class ExpTernaria implements Expressao {
13+
14+
/**
15+
* Expressao da esquerda
16+
*/
17+
protected Expressao esq;
18+
19+
/**
20+
* Expressao do meio
21+
*/
22+
protected Expressao mei;
23+
24+
/**
25+
* Expressao da direita
26+
*/
27+
protected Expressao dir;
28+
29+
/**
30+
* Operador 1 desta expressao ternaria
31+
*/
32+
private String operador1;
33+
34+
/**
35+
* Operador 2 desta expressao ternaria
36+
*/
37+
private String operador2;
38+
39+
/**
40+
* Construtor da classe.
41+
*
42+
* @param esq
43+
* a expressao da esquerda.
44+
* @param mei
45+
* a expressao do meio.
46+
* @param dir
47+
* a expressao da direita.
48+
* @param operador1
49+
* o operador1 desta expressao ternaria.
50+
* @param operador2
51+
* o operador2 desta expressao ternaria.
52+
*/
53+
public ExpTernaria(Expressao esq, Expressao mei, Expressao dir, String operador1, String operador2) {
54+
this.esq = esq;
55+
this.mei = mei;
56+
this.dir = dir;
57+
this.operador1 = operador1;
58+
this.operador2 = operador2;
59+
}
60+
61+
/**
62+
* Retorna a expressao da esquerda
63+
*
64+
* @return a expressao da esquerda
65+
*/
66+
public Expressao getEsq() {
67+
return esq;
68+
}
69+
70+
/**
71+
* Retorna a expressao do meio
72+
*
73+
* @return a expressao do meio
74+
*/
75+
public Expressao getMei() {
76+
return mei;
77+
}
78+
79+
/**
80+
* Retorna a expressao da direita
81+
*
82+
* @return a expressao da direita
83+
*/
84+
public Expressao getDir() {
85+
return dir;
86+
}
87+
88+
/**
89+
* Retorna o operador desta expressao ternaria
90+
*
91+
* @return o operador desta expressao ternaria
92+
*/
93+
public String getOperador1() {
94+
return operador1;
95+
}
96+
97+
/**
98+
* Retorna o operador desta expressao ternaria
99+
*
100+
* @return o operador desta expressao ternaria
101+
*/
102+
public String getOperador2() {
103+
return operador2;
104+
}
105+
106+
/**
107+
* Retorna uma representacao String desta expressao. Util para depuracao.
108+
*
109+
* @return uma representacao String desta expressao.
110+
*/
111+
@Override
112+
public String toString() {
113+
return String.format("%s %s %s %s %s", esq, operador1, mei, operador2, dir);
114+
}
115+
116+
/**
117+
* Realiza a verificacao de tipos desta expressao.
118+
*
119+
* @param amb
120+
* o ambiente de compila��o.
121+
* @return <code>true</code> se os tipos das subexpressoes sao validos;
122+
* <code>false</code> caso contrario.
123+
* @exception VariavelJaDeclaradaException
124+
* se a vari�vel j� est� declarada no ambiente
125+
* @exception VariavelNaoDeclaradaException
126+
* se a vari�vel ainda n�o foi declarada no ambiente.
127+
*/
128+
public boolean checaTipo(AmbienteCompilacao amb)
129+
throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
130+
boolean result = true;
131+
if (!getEsq().checaTipo(amb) || !getMei().checaTipo(amb) || !getDir().checaTipo(amb)) {
132+
result = false;
133+
} else {
134+
result = this.checaTipoElementoTerminal(amb);
135+
}
136+
return result;
137+
}
138+
139+
/**
140+
* M�todo 'template' que ser� implementado nas subclasses para checar o tipo
141+
* do head terminal
142+
*/
143+
protected abstract boolean checaTipoElementoTerminal(AmbienteCompilacao amb)
144+
throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException;
145+
146+
147+
public Expressao reduzir(AmbienteExecucao ambiente) {
148+
this.esq = this.esq.reduzir(ambiente);
149+
this.mei = this.mei.reduzir(ambiente);
150+
this.dir = this.dir.reduzir(ambiente);
151+
152+
return this;
153+
}
154+
155+
public abstract ExpTernaria clone();
156+
}

Imperativa1/src/li1/plp/expressions2/expression/ValorConcreto.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ public T valor() {
3838
* Determina igualdade entre objetos desta classe
3939
*/
4040
public boolean isEquals(ValorConcreto<T> obj) {
41+
if (valor() == null) {
42+
return obj.valor() == null;
43+
}
4144
return valor().equals(obj.valor());
42-
4345
}
4446

4547
/**

Imperativa1/src/li1/plp/imperative1/declaration/DeclaracaoOptional.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@ public boolean checaTipo(AmbienteCompilacaoImperativa ambiente)
2121
IdentificadorNaoDeclaradoException {
2222
boolean result = getExpressao().checaTipo(ambiente);
2323
if (result) {
24-
TipoOptional tipoOpt = new TipoOptional(getExpressao().getTipo(ambiente));
25-
ambiente.map(getId(), tipoOpt);
24+
li1.plp.expressions1.util.Tipo t = getExpressao().getTipo(ambiente);
25+
26+
// Se a expressão já é do tipo opcional (ex: vindo do ternário), usamos ela diretamente.
27+
// Caso contrário, envolvemos o tipo em um novo TipoOptional.
28+
li1.plp.expressions1.util.Tipo tipoFinal =
29+
(t instanceof li1.plp.expressions1.util.TipoOptional) ? t : new li1.plp.expressions1.util.TipoOptional(t);
30+
31+
ambiente.map(getId(), tipoFinal);
2632
}
2733
return result;
2834
}

Imperativa1/src/li1/plp/imperative1/declaration/DeclaracaoVariavel.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import li1.plp.expressions2.memory.IdentificadorNaoDeclaradoException;
77
import li1.plp.imperative1.memory.AmbienteCompilacaoImperativa;
88
import li1.plp.imperative1.memory.AmbienteExecucaoImperativa;
9+
import li1.plp.expressions1.util.Tipo;
10+
import li1.plp.expressions1.util.TipoPrimitivo;
911

1012
public class DeclaracaoVariavel extends Declaracao {
1113

@@ -64,10 +66,15 @@ public boolean checaTipo(AmbienteCompilacaoImperativa ambiente)
6466
IdentificadorNaoDeclaradoException {
6567
boolean result = getExpressao().checaTipo(ambiente);
6668
if (result) {
67-
if (!this.getClass().equals(DeclaracaoOptional.class) && getExpressao().getTipo(ambiente).eIgual(li1.plp.expressions1.util.TipoPrimitivo.NULO)) {
68-
return false;
69+
Tipo t = getExpressao().getTipo(ambiente);
70+
71+
// 1. Se é um TipoOptional (ex: vindo de um ternário com null)
72+
// 2. Se é o TipoPrimitivo.NULO (ex: var x = null)
73+
if (t instanceof li1.plp.expressions1.util.TipoOptional ||
74+
t.eIgual(TipoPrimitivo.NULO)) {
75+
return false; // Retorna erro de tipo para variáveis comuns
6976
}
70-
ambiente.map(getId(), getExpressao().getTipo(ambiente));
77+
ambiente.map(getId(), t);
7178
}
7279
return result;
7380
}

0 commit comments

Comments
 (0)