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 Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { Result result = new Result(); Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores); if (Op2 != null) { Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores); TipoDominante(Op1.GetTipo(), Op2.GetTipo()); if (!Tipo.IsIndefinido()) { result.Codigo += rsOp1.Codigo; result.Codigo += rsOp2.Codigo; if (Tipo.IsString()) { if (!Op1.GetTipo().IsString()) { ConvertirString(Op1, rsOp1, result); } if (!Op2.GetTipo().IsString()) { ConvertirString(Op2, rsOp2, result); } result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); string etqCiclo = NuevaEtiqueta(); string tmpCiclo = NuevoTemporal(); result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = H;\n"; result.Codigo += tmpCiclo + " = heap[" + rsOp1.Valor + "];\n"; result.Codigo += etqCiclo + ":\n"; result.Codigo += "if (" + tmpCiclo + " == 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += "heap[H] = " + tmpCiclo + ";\n"; result.Codigo += "H = H + 1;\n"; result.Codigo += rsOp1.Valor + " = " + rsOp1.Valor + " + 1;\n"; result.Codigo += tmpCiclo + " = heap[" + rsOp1.Valor + "];\n"; result.Codigo += "goto " + etqCiclo + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); etqCiclo = NuevaEtiqueta(); tmpCiclo = NuevoTemporal(); result.Codigo += tmpCiclo + " = heap[" + rsOp2.Valor + "];\n"; result.Codigo += etqCiclo + ":\n"; result.Codigo += "if (" + tmpCiclo + " == 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += "heap[H] = " + tmpCiclo + ";\n"; result.Codigo += "H = H + 1;\n"; result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " + 1;\n"; result.Codigo += tmpCiclo + " = heap[" + rsOp2.Valor + "];\n"; result.Codigo += "goto " + etqCiclo + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += "heap[H] = 0;\n"; result.Codigo += "H = H + 1;\n"; } else { switch (Op) { case Operador.SUMA: result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " + " + rsOp2.Valor + ";\n"; break; case Operador.RESTA: result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " - " + rsOp2.Valor + ";\n"; break; case Operador.MULTIPLICACION: result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " * " + rsOp2.Valor + ";\n"; break; case Operador.DIVISION: result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " / " + rsOp2.Valor + ";\n"; break; case Operador.MODULO: result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " % " + rsOp2.Valor + ";\n"; break; case Operador.FLOOR: result.EtiquetaV = NuevaEtiqueta(); string etqSalida = NuevaEtiqueta(); if (Op1 is Literal) { string tmpOp1 = NuevoTemporal(); result.Codigo += tmpOp1 + " = " + rsOp1.Valor + ";\n"; rsOp1.Valor = tmpOp1; } if (Op2 is Literal) { string tmpOp2 = NuevoTemporal(); result.Codigo += tmpOp2 + " = " + rsOp2.Valor + ";\n"; rsOp2.Valor = tmpOp2; } result.Valor = NuevoTemporal(); result.Codigo += "if (" + rsOp2.Valor + " != 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + etqSalida + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; string tmpCond = NuevoTemporal(); result.Codigo += tmpCond + " = 0;\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + rsOp2.Valor + " > 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += tmpCond + " = 1;\n"; string menos = NuevoTemporal(); result.Codigo += menos + " = 0 - 1;\n"; result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " * " + menos + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; string tmpCond2 = NuevoTemporal(); result.Codigo += tmpCond2 + " = 0;\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + rsOp1.Valor + " >= 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += tmpCond2 + " = 1;\n"; menos = NuevoTemporal(); result.Codigo += menos + " = 0 - 1;\n"; result.Codigo += rsOp1.Valor + " = " + rsOp1.Valor + " * " + menos + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "if (" + rsOp2.Valor + " > " + rsOp1.Valor + ") goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += result.Valor + " = 0;\n"; result.Codigo += result.EtiquetaF + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); string etqCiclo = NuevaEtiqueta(); string tmp = NuevoTemporal(); result.Codigo += tmp + " = " + rsOp1.Valor + " - " + rsOp2.Valor + ";\n"; result.Codigo += etqCiclo + ":\n"; result.Codigo += tmp + " = " + tmp + " - " + rsOp2.Valor + ";\n"; result.Codigo += "if (" + tmp + " >= 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += result.Valor + " = " + result.Valor + " + 1;\n"; result.Codigo += "goto " + etqCiclo + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + tmpCond + " == 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; string etqVerd = result.EtiquetaV; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + tmpCond2 + " == 1) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += result.Valor + " = " + result.Valor + " + 1;\n"; menos = NuevoTemporal(); result.Codigo += menos + " = 0 - 1;\n"; result.Codigo += result.Valor + " = " + result.Valor + " * " + menos + ";\n"; result.Codigo += etqVerd + ":\n"; result.Codigo += result.EtiquetaV + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + tmpCond2 + " == 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; etqVerd = result.EtiquetaV; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "if (" + tmpCond + " == 1) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += result.Valor + " = " + result.Valor + " + 1;\n"; menos = NuevoTemporal(); result.Codigo += menos + " = 0 - 1;\n"; result.Codigo += result.Valor + " = " + result.Valor + " * " + menos + ";\n"; result.Codigo += etqVerd + ":\n"; result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += etqSalida + ":\n"; break; case Operador.POTENCIA: if (Op1 is Literal) { string tmpOp1 = NuevoTemporal(); result.Codigo += tmpOp1 + " = " + rsOp1.Valor + ";\n"; rsOp1.Valor = tmpOp1; } if (Op2 is Literal) { string tmpOp2 = NuevoTemporal(); result.Codigo += tmpOp2 + " = " + rsOp2.Valor + ";\n"; rsOp2.Valor = tmpOp2; } else if (Op2 is Aritmetica) { if (((Aritmetica)Op2).Op2 == null && ((Aritmetica)Op2).Op == Operador.RESTA) { Tipo.Tip = Tipo.Type.DOUBLE; } } result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); string factorNeg = NuevoTemporal(); string nuevoValor = NuevoTemporal(); string etqSalida2 = NuevaEtiqueta(); //string etqError = NuevaEtiqueta(); result.Codigo += "if (" + rsOp2.Valor + " >= 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += factorNeg + " = 0 - 1;\n"; result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " * " + factorNeg + ";\n"; //result.Codigo += "if (" + rsOp1.Valor + " == 0) goto " + etqError + ";\n";/*0**-num*/ result.Codigo += nuevoValor + " = 1.0 / " + rsOp1.Valor + ";\n"; result.Codigo += "goto " + etqSalida2 + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += nuevoValor + " = " + rsOp1.Valor + ";\n"; result.Codigo += etqSalida2 + ":\n"; result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); string etqCiclo2 = NuevaEtiqueta(); result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = 1;\n"; result.Codigo += etqCiclo2 + ":\n"; result.Codigo += "if (" + rsOp2.Valor + " <= 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += result.Valor + " = " + result.Valor + " * " + nuevoValor + ";\n"; result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " - 1;\n"; result.Codigo += "goto " + etqCiclo2 + ";\n"; result.Codigo += result.EtiquetaV + ":\n"; break; } } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación aritmética.", Linea, Columna)); } } else { Tipo tipOp1 = Op1.GetTipo(); if (tipOp1.IsNumeric() || tipOp1.IsBoolean()) { if (tipOp1.IsNumeric()) { Tipo = Op1.GetTipo(); } else { Tipo = new Tipo(Tipo.Type.INT); } result.Codigo += rsOp1.Codigo; result.Valor = NuevoTemporal(); switch (Op) { case Operador.SUMA: result.Codigo += result.Valor + " = " + rsOp1.Valor + " * 1;\n"; break; case Operador.RESTA: result.Codigo += result.Valor + " = 0 - 1;\n"; string tmp = result.Valor; result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + " * " + tmp + ";\n"; break; } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación aritmética.", Linea, Columna)); } } return(result); }
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 Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { Result result = new Result(); if (Op1 is Relacional) { ((Relacional)Op1).Cortocircuito = true; } else if (Op1 is Logica) { ((Logica)Op1).Evaluar = true; } Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores); if (Op2 != null) { if (Op2 is Relacional) { ((Relacional)Op2).Cortocircuito = true; } else if (Op2 is Logica) { ((Logica)Op2).Evaluar = true; } Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores); TipoResultante(Op1.GetTipo(), Op2.GetTipo()); if (!Tipo.IsIndefinido()) { if (Tipo.IsBoolean()) /*Si los dos son booleanos*/ { if (Op1 is Literal) { rsOp1.EtiquetaV = NuevaEtiqueta(); rsOp1.EtiquetaF = NuevaEtiqueta(); rsOp1.Codigo += "ifFalse (" + rsOp1.Valor + " == 1) goto " + rsOp1.EtiquetaV + ";\n"; rsOp1.Codigo += "goto " + rsOp1.EtiquetaF + ";\n"; rsOp1.EtiquetaV += ":\n"; rsOp1.EtiquetaF += ":\n"; } if (Op2 is Literal) { rsOp2.EtiquetaV = NuevaEtiqueta(); rsOp2.EtiquetaF = NuevaEtiqueta(); rsOp2.Codigo += "ifFalse (" + rsOp2.Valor + " == 1) goto " + rsOp2.EtiquetaV + ";\n"; rsOp2.Codigo += "goto " + rsOp2.EtiquetaF + ";\n"; rsOp2.EtiquetaV += ":\n"; rsOp2.EtiquetaF += ":\n"; } if (Op == Operador.AND) { result.Codigo += rsOp1.Codigo; if (Op1 is Relacional || Op1 is Literal) { result.Codigo += rsOp1.EtiquetaF; rsOp1.EtiquetaF = rsOp1.EtiquetaV; rsOp1.EtiquetaV = null; } else if (Op1 is Logica) { result.Codigo += rsOp1.EtiquetaV; rsOp1.EtiquetaV = null; } result.Codigo += rsOp2.Codigo; if (Op2 is Relacional || Op2 is Literal) { string copy = rsOp2.EtiquetaV; rsOp2.EtiquetaV = rsOp2.EtiquetaF; rsOp2.EtiquetaF = copy; } /* * if(Op2 is Relacional) * result.Codigo += rsOp2.EtiquetaF;*/ if (!Evaluar) { result.Valor = NuevoTemporal(); string etiquetaS = NuevaEtiqueta(); if (rsOp1.EtiquetaV != null) { result.Codigo += rsOp1.EtiquetaV; } if (rsOp2.EtiquetaV != null) { result.Codigo += rsOp2.EtiquetaV; } result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; if (rsOp1.EtiquetaF != null) { result.Codigo += rsOp1.EtiquetaF; } if (rsOp2.EtiquetaF != null) { result.Codigo += rsOp2.EtiquetaF; } result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { if (rsOp1.EtiquetaV != null) { result.EtiquetaV += rsOp1.EtiquetaV; } if (rsOp1.EtiquetaF != null) { result.EtiquetaF += rsOp1.EtiquetaF; } if (rsOp2.EtiquetaV != null) { result.EtiquetaV += rsOp2.EtiquetaV; } if (rsOp2.EtiquetaF != null) { result.EtiquetaF += rsOp2.EtiquetaF; } } } else { result.Codigo += rsOp1.Codigo; if (Op1 is Relacional || Op1 is Literal) { result.Codigo += rsOp1.EtiquetaV; rsOp1.EtiquetaV = rsOp1.EtiquetaF; rsOp1.EtiquetaF = null; } else if (Op1 is Logica) { result.Codigo += rsOp1.EtiquetaF; rsOp1.EtiquetaF = null; } result.Codigo += rsOp2.Codigo; if (Op2 is Relacional || Op2 is Literal) { string copy = rsOp2.EtiquetaV; rsOp2.EtiquetaV = rsOp2.EtiquetaF; rsOp2.EtiquetaF = copy; } if (!Evaluar) { result.Valor = NuevoTemporal(); string etiquetaS = NuevaEtiqueta(); if (rsOp1.EtiquetaV != null) { result.Codigo += rsOp1.EtiquetaV; } if (rsOp2.EtiquetaV != null) { result.Codigo += rsOp2.EtiquetaV; } result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; if (rsOp1.EtiquetaF != null) { result.Codigo += rsOp1.EtiquetaF; } if (rsOp2.EtiquetaF != null) { result.Codigo += rsOp2.EtiquetaF; } result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { if (rsOp1.EtiquetaV != null) { result.EtiquetaV += rsOp1.EtiquetaV; } if (rsOp1.EtiquetaF != null) { result.EtiquetaF += rsOp1.EtiquetaF; } if (rsOp2.EtiquetaV != null) { result.EtiquetaV += rsOp2.EtiquetaV; } if (rsOp2.EtiquetaF != null) { result.EtiquetaF += rsOp2.EtiquetaF; } } } } else { if (Op == Operador.AND) { if (Op2 is Literal && !Op2.GetTipo().IsNone()) { result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp2.Valor + ";\n"; } else { result.Codigo += rsOp2.Codigo; result.Valor = rsOp2.Valor; if (Op2 is Relacional || Op2 is Logica) { if (!Evaluar) { result.Valor = NuevoTemporal(); string etiquetaS = NuevaEtiqueta(); if (rsOp2.EtiquetaV != null) { result.Codigo += rsOp2.EtiquetaV; } result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; if (rsOp2.EtiquetaF != null) { result.Codigo += rsOp2.EtiquetaF; } result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { result.EtiquetaV = rsOp2.EtiquetaV; result.EtiquetaF = rsOp2.EtiquetaF; } } } Tipo = Op2.GetTipo(); } else { if (Op1 is Literal && !Op1.GetTipo().IsNone()) { result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + rsOp1.Valor + ";\n"; } else { result.Codigo += rsOp1.Codigo; result.Valor = rsOp1.Valor; if (Op1 is Relacional || Op1 is Logica) { if (!Evaluar) { result.Valor = NuevoTemporal(); string etiquetaS = NuevaEtiqueta(); if (rsOp1.EtiquetaV != null) { result.Codigo += rsOp1.EtiquetaV; } result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; if (rsOp1.EtiquetaF != null) { result.Codigo += rsOp1.EtiquetaF; } result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { result.EtiquetaV = rsOp1.EtiquetaV; result.EtiquetaF = rsOp1.EtiquetaF; } } } Tipo = Op1.GetTipo(); } } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación lógica.", Linea, Columna)); } } else /*NOT*/ { Tipo.Tip = Tipo.Type.BOOLEAN; if (Op1.GetTipo().IsBoolean()) /*Boolean, exp logica y relacional*/ { if (Op1 is Literal) { rsOp1.EtiquetaV = NuevaEtiqueta(); rsOp1.EtiquetaF = NuevaEtiqueta(); rsOp1.Codigo += "ifFalse (" + rsOp1.Valor + " == 1) goto " + rsOp1.EtiquetaV + ";\n"; rsOp1.Codigo += "goto " + rsOp1.EtiquetaF + ";\n"; rsOp1.EtiquetaV += ":\n"; rsOp1.EtiquetaF += ":\n"; } result.Codigo += rsOp1.Codigo; if (!Evaluar) { result.Valor = NuevoTemporal(); string etiquetaS = NuevaEtiqueta(); if (rsOp1.EtiquetaV != null) { result.Codigo += rsOp1.EtiquetaV; } result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; if (rsOp1.EtiquetaF != null) { result.Codigo += rsOp1.EtiquetaF; } result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { if (rsOp1.EtiquetaV != null) { result.EtiquetaF = rsOp1.EtiquetaV; } if (rsOp1.EtiquetaF != null) { result.EtiquetaV = rsOp1.EtiquetaF; } } } else { if (Op1 is Literal) { string tmp = NuevoTemporal(); rsOp1.Codigo += tmp + " = " + rsOp1.Valor + ";\n"; rsOp1.Valor = tmp; } if (Op1.GetTipo().IsString()) { rsOp1.Codigo += rsOp1.Valor + " = 0 - 1;\n"; } result.Codigo += rsOp1.Codigo; if (!Evaluar) { result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = 0;\n"; result.Codigo += "ifFalse (" + rsOp1.Valor + " == 0) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += result.Valor + " = 1;\n"; result.Codigo += result.EtiquetaV + ":\n"; } else { result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "ifFalse (" + rsOp1.Valor + " == 0) goto " + result.EtiquetaF + ";\n"; result.Codigo += "goto " + result.EtiquetaV + ";\n"; result.EtiquetaV += ":\n"; result.EtiquetaF += ":\n"; } } } return(result); }
public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { Result result = new Result(); if (Op != Operador.IS && Op != Operador.ISNOT) { Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores); Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores); TipoResultante(Op1.GetTipo(), Op2.GetTipo()); if (!Tipo.IsIndefinido()) { if (!Op1.GetTipo().IsObject() && !Op2.GetTipo().IsObject()) /*si los dos no son objetos*/ { /* * if (Op == Operador.IGUAL) * { * if (Op1.GetTipo() != Op2.GetTipo()) * { * result.Codigo += rsOp1.Codigo; * result.Codigo += rsOp2.Codigo; * result.Valor = NuevoTemporal(); * result.Codigo += result.Valor + " = 0;\n"; * return result; * } * } * * if (Op == Operador.DIFERENTE) * { * if (Op1.GetTipo() != Op2.GetTipo()) * { * result.Codigo += rsOp1.Codigo; * result.Codigo += rsOp2.Codigo; * result.Valor = NuevoTemporal(); * result.Codigo += result.Valor + " = 1;\n"; * return result; * } * } */ if (Op1.GetTipo().IsNumeric() || Op1.GetTipo().IsString() || Op1.GetTipo().IsBoolean()) { if (Op2.GetTipo().IsNumeric() || Op2.GetTipo().IsString() || Op2.GetTipo().IsBoolean()) { result.Codigo += rsOp1.Codigo; result.Codigo += rsOp2.Codigo; if (Op1.GetTipo().IsString()) { ObtenerValor(rsOp1, result); } if (Op2.GetTipo().IsString()) { ObtenerValor(rsOp2, result); } result.Valor = NuevoTemporal(); string op = ""; switch (Op) { case Operador.MAYORQUE: op = ">"; break; case Operador.MENORQUE: op = "<"; break; case Operador.MAYORIGUALQUE: op = ">="; break; case Operador.MENORIGUALQUE: op = "<="; break; case Operador.IGUAL: op = "=="; break; case Operador.DIFERENTE: op = "!="; break; } result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); if (!Cortocircuito) { result.Codigo += "if (" + rsOp1.Valor + " " + op + " " + rsOp2.Valor + ") goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; string etiquetaS = NuevaEtiqueta(); result.Codigo += result.EtiquetaV + ":\n"; result.Codigo += result.Valor + " = 1;\n"; result.Codigo += "goto " + etiquetaS + ";\n"; result.Codigo += result.EtiquetaF + ":\n"; result.Codigo += result.Valor + " = 0;\n"; result.Codigo += etiquetaS + ":\n"; } else { result.Codigo += "ifFalse (" + rsOp1.Valor + " " + op + " " + rsOp2.Valor + ") goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.EtiquetaV += ":\n"; result.EtiquetaF += ":\n"; } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna)); } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna)); } } else { if (Op == Operador.IGUAL || Op == Operador.DIFERENTE) /*con objetos solo se puede == !=*/ { result.Codigo += rsOp1.Codigo; result.Codigo += rsOp2.Codigo; result.Valor = NuevoTemporal(); if (Op == Operador.IGUAL) { if (Op1.GetTipo().Tip == Op2.GetTipo().Tip) { /*comparar objetos*/ } else { result.Codigo += result.Valor + " = 0;\n"; } } else { if (Op1.GetTipo().Tip == Op2.GetTipo().Tip) { /*comparar objetos*/ } else { result.Codigo += result.Valor + " = 1;\n"; } } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna)); } } } else { errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna)); } } else { if (Op1 is Identificador objeto) { if (Op2 is Identificador c) { Sim sim = e.GetGlobal(objeto.Id); if (sim != null) { if (sim.Tipo.IsObject()) { Sim clase = e.GetClase(c.Id); if (clase != null) { Tipo.Tip = Tipo.Type.BOOLEAN; if (sim.Tipo.Objeto.Equals(c.Id)) { if (Op == Operador.IS) { result.Valor = "1"; } else { result.Valor = "0"; } } else { if (Op == Operador.IS) { result.Valor = "0"; } else { result.Valor = "1"; } } result.EtiquetaV = NuevaEtiqueta(); result.EtiquetaF = NuevaEtiqueta(); result.Codigo += "ifFalse (" + result.Valor + " == 1) goto " + result.EtiquetaV + ";\n"; result.Codigo += "goto " + result.EtiquetaF + ";\n"; result.EtiquetaV += ":\n"; result.EtiquetaF += ":\n"; return(result); } } } } } errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna)); } return(result); }