public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { if (funcion) { Result result = new Result(); Sim ret = e.GetGlobal("return"); if (Valor != null) { if (!ret.Tipo.IsVoid()) { Result rsValor = Valor.GetC3D(e, funcion, ciclo, isObjeto, errores); if (!Valor.GetTipo().IsIndefinido()) { if (rsValor.Valor != null) { if (ret.Tipo.Tip == Valor.GetTipo().Tip) { result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = P + " + ret.Pos + ";\n"; result.Codigo += rsValor.Codigo; result.Codigo += "stack[" + result.Valor + "] = " + rsValor.Valor + ";\n"; } else { errores.AddLast(new Error("Semántico", "El tipo de return no es el mismo de la función: " + ret.Tipo.ToString() + ".", Linea, Columna)); return(null); } } else { errores.AddLast(new Error("Semántico", "El valor del return contiene errores.", Linea, Columna)); return(null); } } else { errores.AddLast(new Error("Semántico", "El valor del return contiene errores.", Linea, Columna)); return(null); } } else { errores.AddLast(new Error("Semántico", "No se espera valor en return.", Linea, Columna)); } } else { if (!ret.Tipo.IsVoid()) { errores.AddLast(new Error("Semántico", "Se espera valor en return.", Linea, Columna)); return(null); } } result.Codigo += "goto " + e.EtiquetaSalida + ";\n"; return(result); } else { errores.AddLast(new Error("Semántico", "El return no se encuentra dentro de una función", Linea, Columna)); return(null); } }
public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { Sim s = null; if (GetLocal) { s = e.Get(Id); } else { s = e.GetGlobal(Id); } if (s != null) { Tipo = s.Tipo; Result result = new Result(); PtrVariable = s.Pos + ""; Simbolo = s; result.Simbolo = s; if (!IsDeclaracion) { if (Acceso) { result.Valor = NuevoTemporal(); if (s.Rol == Rol.GLOBAL) { result.Codigo += result.Valor + " = heap[" + s.Pos + "];\n"; } else if (s.IsAtributo) { string ptrStack = NuevoTemporal(); string ptrHeap = NuevoTemporal(); string valorHeap = NuevoTemporal(); result.Codigo = ptrStack + " = P + 1;\n"; result.Codigo += valorHeap + " = stack[" + ptrStack + "];\n"; result.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n"; result.Codigo += result.Valor + " = heap[" + ptrHeap + "]"; } else { string ptrStack = NuevoTemporal(); result.Codigo = ptrStack + " = P + " + s.Pos + ";\n"; result.Codigo += result.Valor + " = stack[" + ptrStack + "];\n"; } } else { result.PtrStack = s.Pos; if (s.Rol == Rol.GLOBAL) { result.Valor = "heap[" + s.Pos + "]"; } else if (s.IsAtributo) { string ptrStack = NuevoTemporal(); string ptrHeap = NuevoTemporal(); string valorHeap = NuevoTemporal(); result.Codigo = ptrStack + " = P + 1;\n"; result.Codigo += valorHeap + " = stack[" + ptrStack + "];\n"; result.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n"; result.Valor = "heap[" + ptrHeap + "]"; } else { string ptrStack = NuevoTemporal(); result.Codigo = ptrStack + " = P + " + s.Pos + ";\n"; result.Valor = "stack[" + ptrStack + "]"; } } } return(result); } else { if (Acceso) { errores.AddLast(new Error("Semántico", "La variable: " + Id + " no está declarada.", Linea, Columna)); } } return(null); }
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); }