public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isDeclaracion, bool isObjeto, LinkedList <Error> errores) { if (!isDeclaracion) { Debugger(e, "Clase"); } Result result = new Result(); Sim clase = e.GetClase(Id); if (!isDeclaracion) { if (clase != null) { Ent local = new Ent(Id, e); /*Verificar*/ local.Size = clase.Tam; /*Guardo Clases*/ /*Guardar Funciones*/ foreach (Nodo sentencia in Bloque.Sentencias) { if (sentencia is Funcion) { Funcion fun = ((Funcion)sentencia); fun.GetC3D(local, false, false, true, isObjeto, errores); } } /*Buscar si hay constructor*/ /*Genero Constructor*/ result.Codigo += "proc " + Id + "_" + Id + "() begin\n"; /*Verificar si hay returns, error*/ string tmp = NuevoTemporal(); result.Codigo += tmp + " = P + 0;\n"; result.Codigo += "stack[" + tmp + "] = H;\n"; /*Guardo Posición self en 1*/ string tmp2 = NuevoTemporal(); result.Codigo += tmp2 + " = P + 1;\n"; result.Codigo += "stack[" + tmp2 + "] = H;\n"; result.Codigo += "H = H + " + local.Size + ";\n"; //reservo memoria /*Ejecuto sentencias que estan en la clase*/ foreach (Nodo sentencia in Bloque.Sentencias) { if (!(sentencia is Funcion) && !(sentencia is Clase)) { Result rsNodo = null; if (sentencia is Instruccion) { if (sentencia is Asignacion) //Solo sentencias de asignación { rsNodo = ((Instruccion)sentencia).GetC3D(local, false, false, false, true, errores); } if (sentencia is Global) { ((Global)sentencia).GetC3D(local, false, false, false, true, errores); } } if (rsNodo != null) { if (rsNodo.Codigo != null) { result.Codigo += rsNodo.Codigo; } } } } //reservo memoria //Posicion 1 siempre vendra self result.Codigo += "end\n\n"; /*Obtener C3D Funciones*/ foreach (Nodo sentencia in Bloque.Sentencias) { if (sentencia is Funcion) { Result rsNodo = ((Funcion)sentencia).GetC3D(local, false, false, false, isObjeto, errores); if (rsNodo != null) { if (rsNodo.Codigo != null) { result.Codigo += rsNodo.Codigo; } } } } //PrintTabla t = new PrintTabla(0,0); //t.GetC3D(clase.Entorno, false, false, false, errores); foreach (Sim s in local.Simbolos) { clase.Entorno.Add(s); } } } else { if (clase == null) { Ent local = new Ent(Id, e); foreach (Nodo sentencia in Bloque.Sentencias) { if (sentencia is Instruccion) { if (!(sentencia is Funcion) && !(sentencia is Clase))/*ojo*/ { ((Instruccion)sentencia).GetC3D(local, false, false, true, isObjeto, errores); } } } clase = new Sim(Id, new Tipo(Id), Rol.CLASE, local.Pos, -1, e.Ambito, -1, -1); clase.Entorno = local; e.Add(clase); } else { errores.AddLast(new Error("Semántico", "Ya se declaró una clase con el mismo id: " + Id + ".", Linea, Columna)); } } return(result); //return Bloque.GetC3D(e, funcion, ciclo, isDeclaracion, errores); }
public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores) { Result result = new Result(); Result rsExpresion; if (Acceso) { /*Puede que sea global*/ if (Expresion is Identificador) { Sim clase = e.GetClase(((Identificador)Expresion).Id); if (clase != null) { Sim atributo = clase.Entorno.Get(Id); if (atributo != null) { result.Simbolo = atributo; if (atributo.Rol == Rol.GLOBAL) { result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + "heap[" + atributo.Pos + "];\n"; Tipo = atributo.Tipo; return(result); } } } } rsExpresion = Expresion.GetC3D(e, funcion, ciclo, isObjeto, errores); if (rsExpresion != null) { Sim var = null; if (Expresion is Identificador) { var = ((Identificador)Expresion).Simbolo; } else if (Expresion is Referencia) { var = ((Referencia)Expresion).Simbolo; } if (var != null) { Sim clase = e.GetClase(var.Tipo.Objeto); if (clase != null) { Sim atributo = clase.Entorno.Get(Id); if (atributo != null) { result.Simbolo = atributo; result.Codigo += rsExpresion.Codigo; string ptrHeap = NuevoTemporal(); result.Codigo += ptrHeap + " = " + rsExpresion.Valor + " + " + atributo.Pos + ";\n"; result.Valor = NuevoTemporal(); result.Codigo += result.Valor + " = " + "heap[" + ptrHeap + "];\n"; Tipo = atributo.Tipo; } else { errores.AddLast(new Error("Semántico", "El atributo: " + Id + " no está declarado.", Linea, Columna)); return(null); } } } } else { errores.AddLast(new Error("Semántico", "Error obteniendo la referencia", Linea, Columna)); return(null); } } else { /*Puede que sea global*/ if (Expresion is Identificador) { Sim clase = e.GetClase(((Identificador)Expresion).Id); if (clase != null) { Sim atributo = clase.Entorno.Get(Id); if (atributo != null) { if (atributo.Rol == Rol.GLOBAL) { result.Simbolo = atributo; result.Valor = NuevoTemporal(); result.Valor = "heap[" + atributo.Pos + "]"; Tipo = atributo.Tipo; return(result); } } } } if (Expresion is Identificador) { ((Identificador)Expresion).Acceso = false; } else if (Expresion is Referencia) { ((Referencia)Expresion).Acceso = false; } rsExpresion = Expresion.GetC3D(e, funcion, ciclo, isObjeto, errores); if (rsExpresion != null) { Tipo = Expresion.GetTipo(); result.Codigo += rsExpresion.Codigo; result.Valor = rsExpresion.Valor; if (Expresion is Identificador) { Simbolo = ((Identificador)Expresion).Simbolo; } else if (Expresion is Referencia) { Simbolo = ((Referencia)Expresion).Simbolo; } if (ObtenerValor) { if (Simbolo != null) { Sim clase = e.GetClase(Simbolo.Tipo.Objeto); if (clase != null) { Sim atributo = clase.Entorno.Get(Id); if (atributo != null) { result.Simbolo = atributo; string valor = NuevoTemporal(); result.Codigo += valor + " = " + rsExpresion.Valor + ";\n"; string ptrHeap = NuevoTemporal(); result.Codigo += ptrHeap + " = " + valor + " + " + atributo.Pos + ";\n"; result.Valor = NuevoTemporal(); result.Valor = "heap[" + ptrHeap + "]"; PtrVariable = atributo.Pos + ""; Tipo = atributo.Tipo; } } } } } else { errores.AddLast(new Error("Semántico", "Error obteniendo la referencia", Linea, Columna)); return(null); } } 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); }