package Portugol.Language.Analisador;
import Portugol.Language.Calcular.*;
import Portugol.Language.Criar.BloqueSubrutine;
import Portugol.Language.Utilitario.IteratorElements;
import Portugol.Language.Utilitario.IteratorExpression;
import Portugol.Language.Utilitario.LanguageException;
import Portugol.Language.Utilitario.Values;
import java.util.Stack;
import java.util.Vector;
public class Expressao {
public static String VERSION = "Versão:2.0 \t(c)Augusto Bilabila e David Silva Barrera";
static public String ErroDeCalculo = "ERRO DE CALCULO";
public static Vector ReplaceVariablesToValues(Vector expr, Vector memory, boolean safe) throws LanguageException {
//System.out.print("Entra: " + expr + "\n");
Vector newExpr = new Vector();
Object CurrentElem;
Object NextElem;
Stack pilha = new Stack();
for (int i = 0; i < expr.size(); i++) {
CurrentElem = expr.get(i);
NextElem = i + 1 < expr.size() - 1 ? expr.get(i + 1) : null;
if (NextElem != null && NextElem instanceof String && NextElem.equals("(")) {
Vector e = new Vector();
e.add(CurrentElem);
e.add(NextElem);
pilha.push(e);
i++;
continue;
} else if (CurrentElem != null && CurrentElem instanceof String && CurrentElem.equals(")")) {
if (pilha.isEmpty()) {
throw new LanguageException(
"Os parêntesis não estão bem colocados na expressão",
"Verifique os parêntesis");
}
Vector e = (Vector) pilha.pop();
e.add(CurrentElem);
CurrentElem = e;
}
if (pilha.isEmpty()) {
Object val = GetValueElement(CurrentElem, memory, safe);
newExpr.add(val);
} else {
Vector v = new Vector();
v.add(CurrentElem);
CurrentElem = ReplaceVariablesToValues(v, memory, safe);
Vector e = (Vector) pilha.pop();
for (int j = 0; j < ((Vector) CurrentElem).size(); j++) {
e.add(((Vector) CurrentElem).get(j));
}
pilha.push(e);
}
}
//System.out.print("Sale: " + newExpr.toString().trim() + "\n");
return newExpr;
}
public static Vector ExpresionStringToVector(String expr) throws LanguageException {
//System.out.print("Entra: " + expr + "\n");
Vector newExpr = new Vector();
String CurrentElem;
IteratorElements tok = new IteratorElements(expr);
while (tok.hasMoreElements()) {
CurrentElem = tok.current();
tok.next();
if (CurrentElem.startsWith(".")) {
if (newExpr.isEmpty() || newExpr.lastElement() instanceof String && ((String) newExpr.lastElement()).trim().equals(")")) {
//David: Não é permitido utilizar um campo na mesma chamada á função
//throw new Exception("()."); //David: revisar ortografia
throw new LanguageException(
"Não é permitido utilizar um campo na mesma chamada da função. \nGuarde o resultado da função numa variável e depois utilize o campo desejado",
"Em caso de dúvida, consulte a documentação"); //David: revisar ortografia
}
String s = (String) newExpr.remove(newExpr.size() - 1);
newExpr.add(CurrentElem);
} else {
newExpr.add(CurrentElem);
}
}
return newExpr;
}
public static Object GetValueElement(Object elemento, Vector memory, boolean safe) throws LanguageException {
String elem = "";
if (elemento instanceof String) {
elem = (String) elemento;
} else if (elemento instanceof Vector) {
elem = (String) ((Vector) elemento).get(0);
} else if (elemento instanceof Simbolo) {
return elemento;
}
ParteDeExpresion pde;
boolean minus = false;
//------------------------- sinal - -------------
if (!elem.isEmpty() && elem.charAt(0) == '-') {
minus = true;
}
//-------------------------------------------------------------
// variavel sem valor negativo
//------------------------------------------------------------
pde = Variavel.getVariable(elemento, memory);
if (pde == null) {
if (minus) {
return "(" + elem + "* -1)";
} else {
return elem;
} //David: tener en cuenta los parentesis de las operaciones
} else if (pde instanceof Operador) {
return pde.TextoOrigen;
} else if (pde instanceof SymbolArray) {
if (elem.contains("[") && elem.contains("]")) {
SymbolArray a = (SymbolArray) pde;
a.SetIndex(elem, memory);
String RetVal;
if (safe) {
RetVal = ((Simbolo) a.getDefaultValue()).getValue().toString();
} else {
RetVal = ((Simbolo) a.getValue()).getValue().toString();
}
if (minus) {
return "(" + RetVal + "* -1)";
} else {
return RetVal;
}
} else {
return pde;
}
} else if (pde instanceof SymbolComposto) {
return pde;
} else if (pde instanceof SymbolObjeto) {
return pde;
} else {
return (Simbolo) pde;
}
}
public static boolean IsExpression(String express, Vector memory) throws LanguageException {
Vector exp = ReplaceVariablesToValues(ExpresionStringToVector(express), memory, true);
for (int i = 0; i < exp.size(); i++) {
Object elem = exp.get(i);
if (!Calculador.IsCalculus(elem)
&& !Values.IsValue(elem)
&& !Keyword.DefineRegisto(elem)
&& !Keyword.DefineClasse(elem)
&& !(elem instanceof Simbolo)
&& elem instanceof String
&& !(Variavel.getVariable(elem, memory) instanceof Simbolo)
&& (!elem.equals("(") && !elem.equals(")")
&& !elem.equals(","))) {
return false;
}
}
return true;
}
public static String ErrorExpression(String express, Vector memory) throws LanguageException {
String exp = (String) ReplaceVariablesToValues(ExpresionStringToVector(express), memory, true).get(0);
IteratorExpression it = new IteratorExpression(exp);
while (it.hasMoreElements()) {
String elem = it.current();
if (!elem.equals("(") && !elem.equals(")")
&& !elem.equals(",")
&& !Calculador.IsCalculus(elem)
&& !Values.IsValue(elem)
&& !Keyword.DefineRegisto(elem)
&& !(Variavel.getVariable(elem, memory) instanceof Simbolo)) {
return it.current();
}
it.next();
}
return "NAO ERRO";
}
public static int TypeExpression(String elem, Vector memory) {
try {
Vector exp = ReplaceVariablesToValues(ExpresionStringToVector(elem), memory, true);
Object result = Calculador.CalulateValue(exp);
if (Values.IsBoolean(result)) {
return Simbolo.LOGICO;
}
if (Values.IsInteger(result)) {
return Simbolo.INTEIRO;
}
if (Values.IsCharacter(result)) {
return Simbolo.CARACTER;
}
if (Values.IsString(result)) {
return Simbolo.TEXTO;
}
if (Values.IsReal(result)) {
return Simbolo.REAL;
}
return Simbolo.DESCONHECIDO;
} catch (Exception e) {
return Simbolo.DESCONHECIDO;
}
}
/**
*
* @param expression
* @param memory
* @return
*/
public static Object Evaluate(String expression, Vector memory) throws LanguageException {
return Evaluate(ExpresionStringToVector(expression), memory, false);
}
public static Object Evaluate(String expression, Vector memory, boolean safe) throws LanguageException {
return Evaluate(ExpresionStringToVector(expression), memory, safe);
}
public static Object Evaluate(Vector expression, Vector memory, boolean safe) throws LanguageException {
try {
Vector exp = ReplaceVariablesToValues(expression, memory, safe);
return exp.size() > 0 ? Calculador.CalulateValue(exp) : "";
} catch (Exception e) {
if (safe && e.getMessage().equals(Aritmeticos.ErroDivPorZero)) {
return "1";
} else if (e.getMessage().equals(Aritmeticos.ErroDivPorZero)) {
return Aritmeticos.ErroDivPorZero;
} else if (e.getMessage().startsWith(SymbolArray.ErroForaLimites)) {
return SymbolArray.ErroForaLimites;
} else if (e.getMessage().startsWith(BloqueSubrutine.ErroRecursividad)) {
return BloqueSubrutine.ErroRecursividad;
} else {
if (e instanceof LanguageException) {
throw (LanguageException) e;
}
throw new LanguageException(
e.getMessage(),
"Verifique a expressão");
//return ErroDeCalculo;
}
}
}
}