public override object GetValor(Entorno e, LinkedList <Salida> log, LinkedList <Error> errores) { object valOp1 = Op1.GetValor(e, log, errores); if (valOp1 != null) { if (valOp1 is Throw) { return(valOp1); } if (Op != Operador.NOT) { object valOp2 = Op2.GetValor(e, log, errores); if (valOp2 != null) { if (valOp2 is Throw) { return(valOp2); } Tipo = new Tipo(Type.BOOLEAN); if (Op1.Tipo.IsBoolean() && Op2.Tipo.IsBoolean()) { switch (Op) { case Operador.OR: return((bool)valOp1 || (bool)valOp2); case Operador.AND: return((bool)valOp1 && (bool)valOp2); case Operador.XOR: return((bool)valOp1 ^ (bool)valOp2); } } errores.AddLast(new Error("Semántico", "No se pudo realizar la operación lógica.", Linea, Columna)); } } else { Tipo = new Tipo(Type.BOOLEAN); if (Op1.Tipo.IsBoolean()) { return(!(bool)valOp1); } errores.AddLast(new Error("Semántico", "No se pudo realizar la operación lógica.", Linea, Columna)); } } return(null); }
public override Tipo GetTipo(Entorno e) { if (!(Op1 is Operacion) && !(Op2 is Operacion)) { Tipo tip1 = Op1.GetTipo(e); Tipo tip2 = Op2.GetTipo(e); if (tip1 != Tipo.NULL && tip2 != Tipo.NULL) { if ((tip1 == Tipo.DECIMAL || tip1 == Tipo.ENTERO) && (tip2 == Tipo.DECIMAL || tip2 == Tipo.ENTERO)) { try { if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { double val1 = Convert.ToDouble(Op1.GetValor()); double val2 = Convert.ToDouble(Op2.GetValor()); switch (Op) { case Operador.MENORQUE: valor = val1 < val2 ? 1 : 0; return(Tipo.DECIMAL); case Operador.MAYORQUE: valor = val1 > val2 ? 1 : 0; return(Tipo.DECIMAL); case Operador.MENORIGUAL: valor = val1 <= val2 ? 1 : 0; return(Tipo.DECIMAL); case Operador.MAYORIGUAL: valor = val1 >= val2 ? 1 : 0; return(Tipo.DECIMAL); case Operador.IGUAL: valor = val1 == val2 ? 1 : 0; return(Tipo.DECIMAL); case Operador.DIFERENTE: valor = val1 != val2 ? 1 : 0; return(Tipo.DECIMAL); } } else { int val1 = Convert.ToInt32(Op1.GetValor()); int val2 = Convert.ToInt32(Op2.GetValor()); switch (Op) { case Operador.MENORQUE: valor = val1 < val2 ? 1 : 0; return(Tipo.ENTERO); case Operador.MAYORQUE: valor = val1 > val2 ? 1 : 0; return(Tipo.ENTERO); case Operador.MENORIGUAL: valor = val1 <= val2 ? 1 : 0; return(Tipo.ENTERO); case Operador.MAYORIGUAL: valor = val1 >= val2 ? 1 : 0; return(Tipo.ENTERO); case Operador.IGUAL: valor = val1 == val2 ? 1 : 0; return(Tipo.ENTERO); case Operador.DIFERENTE: valor = val1 != val2 ? 1 : 0; return(Tipo.ENTERO); } } } catch (Exception) { Console.WriteLine("Error, no se puede realizar la operación relacional. Línea: " + Linea); } } else { Console.WriteLine("Error, no se puede realizar la operación relacional. Línea: " + Linea); } } } else { Console.WriteLine("Error, se esta usando más de 3 direcciones. Línea: " + Linea); } return(Tipo.NULL); }
public override Tipo GetTipo(Entorno e) { if (!(Op1 is Operacion) && !(Op2 is Operacion)) { Tipo tip1 = Op1.GetTipo(e); Tipo tip2 = Op2.GetTipo(e); if (tip1 != Tipo.NULL && tip2 != Tipo.NULL) { if ((tip1 == Tipo.ENTERO || tip1 == Tipo.DECIMAL) && (tip2 == Tipo.ENTERO || tip2 == Tipo.DECIMAL)) { Object val1 = Op1.GetValor(); Object val2 = Op2.GetValor(); try { switch (Op) { case Operador.MAS: if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { valor = Convert.ToDouble(val1) + Convert.ToDouble(val2); return(Tipo.DECIMAL); } else { int val = Convert.ToInt32(val1) + Convert.ToInt32(val2); valor = val; return(Tipo.ENTERO); } case Operador.MENOS: if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { valor = Convert.ToDouble(val1) - Convert.ToDouble(val2); return(Tipo.DECIMAL); } else { int val = Convert.ToInt32(val1) - Convert.ToInt32(val2); valor = val; return(Tipo.ENTERO); } case Operador.POR: if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { valor = Convert.ToDouble(val1) * Convert.ToDouble(val2); return(Tipo.DECIMAL); } else { int val = Convert.ToInt32(val1) * Convert.ToInt32(val2); valor = val; return(Tipo.ENTERO); } case Operador.DIVIDIO: if (Convert.ToInt32(val2) != 0) { if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { valor = Convert.ToDouble(val1) / Convert.ToDouble(val2); return(Tipo.DECIMAL); } else { double val = Convert.ToDouble(val1) / Convert.ToDouble(val2); valor = Math.Truncate(val); return(Tipo.ENTERO); } } else { Console.WriteLine("Division entre 0-> linea: " + Op2.Linea + " columna: " + Op2.Columna); return(Tipo.NULL); } case Operador.MODULO: if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL) { valor = Math.Truncate(Convert.ToDouble(val1) % Convert.ToDouble(val2)); return(Tipo.DECIMAL); } else { double val = Convert.ToDouble(val1) % Convert.ToDouble(val2); valor = Math.Truncate(val); return(Tipo.ENTERO); } } } catch (Exception) { Console.WriteLine("Error, no se puede realizar la operación aritmética. Línea: " + Linea); } } else { Console.WriteLine("Error, no se puede realizar la operación aritmética. Línea: " + Linea); } } } else { Console.WriteLine("Error, se esta usando más de 3 direcciones. Línea: " + Linea); } return(Tipo.NULL); }
public override object GetValor(Entorno e, LinkedList <Salida> log, LinkedList <Error> errores) { object valOp1 = Op1.GetValor(e, log, errores); object valOp2 = Op2.GetValor(e, log, errores); if (valOp1 != null && valOp2 != null) { if (valOp1 is Throw) { return(valOp1); } if (valOp2 is Throw) { return(valOp2); } TipoDominante(errores); if (Tipo != null) { switch (Tipo.Type) { case Type.STRING: Cadena cad = new Cadena { Valor = valOp1.ToString() + valOp2.ToString() }; return(cad); case Type.DOUBLE: switch (Op) { case Operador.SUMA: return(Convert.ToDouble(valOp1) + Convert.ToDouble(valOp2)); case Operador.RESTA: return(Convert.ToDouble(valOp1) - Convert.ToDouble(valOp2)); case Operador.MULTIPLICACION: return(Convert.ToDouble(valOp1) * Convert.ToDouble(valOp2)); case Operador.POTENCIA: return(Math.Pow(Convert.ToDouble(valOp1), Convert.ToDouble(valOp2))); case Operador.MODULO: return(Convert.ToDouble(valOp1) % Convert.ToDouble(valOp2)); case Operador.DIVISION: if (Convert.ToDouble(valOp2) != 0) { return(Convert.ToDouble(valOp1) / Convert.ToDouble(valOp2)); } //errores.AddLast(new Error("Semántico", "División entre 0.", Linea, Columna)); return(new Throw("ArithmeticException", Linea, Columna)); } break; case Type.INT: switch (Op) { case Operador.SUMA: return(Convert.ToInt32(valOp1) + Convert.ToInt32(valOp2)); case Operador.RESTA: return(Convert.ToInt32(valOp1) - Convert.ToInt32(valOp2)); case Operador.MULTIPLICACION: return(Convert.ToInt32(valOp1) * Convert.ToInt32(valOp2)); case Operador.POTENCIA: return(Math.Pow(Convert.ToInt32(valOp1), Convert.ToInt32(valOp2))); case Operador.MODULO: return(Convert.ToInt32(valOp1) % Convert.ToInt32(valOp2)); case Operador.DIVISION: if (Convert.ToInt32(valOp2) != 0) { return(Convert.ToInt32(valOp1) / Convert.ToInt32(valOp2)); } //errores.AddLast(new Error("Semántico", "División entre 0.", Linea, Columna)); return(new Throw("ArithmeticException", Linea, Columna)); } break; case Type.MAP: if (valOp1 is Null) { return(new Throw("NullPointerException", Linea, Columna)); } if (valOp2 is Null) { return(new Throw("NullPointerException", Linea, Columna)); } Collection map1 = (Collection)valOp1; Collection map2 = (Collection)valOp2; foreach (CollectionValue value in map2.Valores) { if (Op == Operador.SUMA) { if (map1.Tipo.Clave.Equals(map2.Tipo.Clave) && map1.Tipo.Valor.Equals(map2.Tipo.Valor)) { if (map1.Get(value.Clave) == null) { map1.Insert(value.Clave, value.Valor); } else { map1.Set(value.Clave, value.Valor); //errores.AddLast(new Error("Semántico", "Ya existe un valor con la clave: " + value.Clave.ToString() + " en Map.", Linea, Columna)); } } else { Casteo cast1 = new Casteo(map1.Tipo.Clave, new Literal(map2.Tipo.Clave, value.Clave, 0, 0), 0, 0) { Mostrar = false }; Casteo cast2 = new Casteo(map1.Tipo.Valor, new Literal(map2.Tipo.Valor, value.Valor, 0, 0), 0, 0) { Mostrar = false }; object clave = cast1.GetValor(e, log, errores); object valor = cast2.GetValor(e, log, errores); if (clave != null && valor != null) { if (clave is Throw) { return(clave); } if (valor is Throw) { return(valor); } if (map1.Get(clave) == null) { map1.Insert(clave, valor); } else { map1.Set(clave, valor); //errores.AddLast(new Error("Semántico", "Ya existe un valor con la clave: " + clave.ToString() + " en Map.", Linea, Columna)); } continue; } errores.AddLast(new Error("Semántico", "Los tipos de los parametros no coinciden con la clave:valor del Map.", Linea, Columna)); return(null); } } else if (Op == Operador.RESTA) { if (map1.Tipo.Clave.Equals(map2.Tipo.Valor)) { if (!map1.Remove(value.Valor)) { errores.AddLast(new Error("Semántico", "No existe un valor con la clave: " + value.Valor.ToString() + " en Map.", Linea, Columna)); } } else { Casteo cast = new Casteo(map1.Tipo.Clave, new Literal(map2.Tipo.Valor, value.Valor, 0, 0), 0, 0) { Mostrar = false }; object clave = cast.GetValor(e, log, errores); if (clave != null) { if (!map1.Remove(clave)) { errores.AddLast(new Error("Semántico", "No existe un valor con la clave: " + clave.ToString() + " en Map.", Linea, Columna)); } } } } else { return(new Throw("ArithmeticException", Linea, Columna)); } } return(map1); case Type.LIST: case Type.SET: if (valOp1 is Null) { return(new Throw("NullPointerException", Linea, Columna)); } if (valOp2 is Null) { return(new Throw("NullPointerException", Linea, Columna)); } Collection set1 = (Collection)valOp1; Collection set2 = (Collection)valOp2; foreach (CollectionValue value in set2.Valores) { if (Op == Operador.SUMA) { if (set1.Tipo.Valor.Equals(set2.Tipo.Valor)) { set1.Insert(set1.Posicion++, value.Valor); } else { Casteo cast = new Casteo(set1.Tipo.Valor, new Literal(set2.Tipo.Valor, value.Valor, 0, 0), 0, 0) { Mostrar = false }; object valor = cast.GetValor(e, log, errores); if (valor != null) { if (valor is Throw) { return(valor); } set1.Insert(set1.Posicion++, valor); continue; } errores.AddLast(new Error("Semántico", "El tipo del parametro no coinciden con el valor de la Collection.", Linea, Columna)); return(null); } } else if (Op == Operador.RESTA) { if (set1.Tipo.Valor.Equals(set2.Tipo.Valor)) { if (!set1.RemoveValor(value.Valor)) { errores.AddLast(new Error("Semántico", "No existe un valor: " + value.Valor.ToString() + " en Collection.", Linea, Columna)); } } else { Casteo cast = new Casteo(set1.Tipo.Valor, new Literal(set2.Tipo.Valor, value.Valor, 0, 0), 0, 0) { Mostrar = false }; object valor = cast.GetValor(e, log, errores); if (valor != null) { if (valor is Throw) { return(valor); } if (!set1.RemoveValor(valor)) { errores.AddLast(new Error("Semántico", "No existe un valor: " + valor.ToString() + " en Collection.", Linea, Columna)); } continue; } errores.AddLast(new Error("Semántico", "El tipo del parametro no coinciden con el valor de la Collection.", Linea, Columna)); return(null); } } else { return(new Throw("ArithmeticException", Linea, Columna)); } } return(set1); } } return(new Throw("ArithmeticException", Linea, Columna)); } return(null); }
public override object GetValor(Entorno e, LinkedList <Salida> log, LinkedList <Error> errores) { object valOp1 = Op1.GetValor(e, log, errores); object valOp2 = Op2.GetValor(e, log, errores); if (valOp1 != null && valOp2 != null) { if (valOp1 is Throw) { return(valOp1); } if (valOp2 is Throw) { return(valOp2); } Tipo = new Tipo(Type.BOOLEAN); if (Op1.Tipo.IsNumeric() && Op2.Tipo.IsNumeric()) { double op1 = Convert.ToDouble(valOp1); double op2 = Convert.ToDouble(valOp2); switch (Op) { case Operador.MAYORQUE: return(op1 > op2); case Operador.MENORQUE: return(op1 < op2); case Operador.IGUAL: return(op1 == op2); case Operador.MENORIGUAL: return(op1 <= op2); case Operador.MAYORIGUAL: return(op1 >= op2); case Operador.DIFERENTE: return(op1 != op2); } } else if (Op1.Tipo.IsDate() && Op2.Tipo.IsDate()) { Date op1 = (Date)valOp1; Date op2 = (Date)valOp2; int res = op1.CompareTo(op2); switch (Op) { case Operador.MAYORQUE: return(res == 1); case Operador.MENORQUE: return(res == -1); case Operador.IGUAL: return(res == 0); case Operador.MENORIGUAL: return(res == -1 || res == 0); case Operador.MAYORIGUAL: return(res == 1 || res == 0); case Operador.DIFERENTE: return(!(res == 0)); } } else if (Op1.Tipo.IsTime() && Op2.Tipo.IsTime()) { Time op1 = (Time)valOp1; Time op2 = (Time)valOp2; int res = op1.CompareTo(op2); switch (Op) { case Operador.MAYORQUE: return(res == 1); case Operador.MENORQUE: return(res == -1); case Operador.IGUAL: return(res == 0); case Operador.MENORIGUAL: return(res == -1 || res == 0); case Operador.MAYORIGUAL: return(res == 1 || res == 0); case Operador.DIFERENTE: return(!(res == 0)); } } else if ((Op1.Tipo.IsBoolean() && Op2.Tipo.IsBoolean()) || (Op1.Tipo.IsString() && Op2.Tipo.IsString())) { if (Op == Operador.IGUAL) { return(valOp1.ToString().Equals(valOp2.ToString())); } else if (Op == Operador.DIFERENTE) { return(!valOp1.ToString().Equals(valOp2.ToString())); } errores.AddLast(new Error("Semántico", "Con " + Op1.Tipo.Type + " solo se puede operar el igual y diferente.", Linea, Columna)); return(null); } else if (Op1.Tipo.IsNull() || Op2.Tipo.IsNull()) { if (Op1.Tipo.IsNull() && Op2.Tipo.IsNullable()) { if (Op == Operador.IGUAL) { return(valOp2 is Null); } else if (Op == Operador.DIFERENTE) { return(!(valOp2 is Null)); } errores.AddLast(new Error("Semántico", "Con Null solo se puede operar el igual y diferente.", Linea, Columna)); return(null); } else if (Op2.Tipo.IsNull() && Op1.Tipo.IsNullable()) { if (Op == Operador.IGUAL) { return(valOp1 is Null); } else if (Op == Operador.DIFERENTE) { return(!(valOp1 is Null)); } errores.AddLast(new Error("Semántico", "Con Null solo se puede operar el igual y diferente.", Linea, Columna)); return(null); } } errores.AddLast(new Error("Semántico", "No se pudo realizar la operación relacional.", Linea, Columna)); } return(null); }