public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isDeclaracion, bool isObjeto, LinkedList <Error> errores) { if (!isDeclaracion) { Debugger(e, "Global"); } Result result = new Result(); foreach (string id in Ids) { if (!isDeclaracion) { e.Add(new Sim(id, Tipo, Rol.GLOBAL, 1, H++, e.Ambito, -1, -1)); } } return(result); }
public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isDeclaracion, bool isObjeto, LinkedList <Error> errores) { if (!isDeclaracion) { Debugger(e, "Asignacion"); } Result result = new Result(); foreach (LinkedList <Expresion> valList in Valor) { if (Objetivo.Count() != valList.Count()) { if (isDeclaracion) { errores.AddLast(new Error("Semántico", "La lista de ids debe ser simétrica", Linea, Columna)); } return(null); } } for (int i = 0; i < Objetivo.Count(); i++) { Expresion obj = Objetivo.ElementAt(i); if (obj is Identificador || obj is Referencia || obj is AccesoLista) //verifico que sea id o referencia a atributo { Identificador idObjetivo = null; Referencia refObjetivo = null; AccesoLista listObjetivo = null; Result rsObj = null; if (obj is Identificador) { idObjetivo = (Identificador)obj; idObjetivo.Acceso = false; idObjetivo.IsDeclaracion = isDeclaracion; if (!Tipo.IsIndefinido()) { idObjetivo.GetLocal = true; } rsObj = idObjetivo.GetC3D(e, funcion, ciclo, isObjeto, errores); } if (obj is Referencia) { refObjetivo = (Referencia)obj; refObjetivo.Acceso = false; refObjetivo.ObtenerValor = true; if (!isDeclaracion) { rsObj = refObjetivo.GetC3D(e, funcion, ciclo, isObjeto, errores); } else { rsObj = null; } } if (obj is AccesoLista) { listObjetivo = (AccesoLista)obj; listObjetivo.Acceso = false; //listObjetivo.IsDeclaracion = isDeclaracion; if (!isDeclaracion) { rsObj = listObjetivo.GetC3D(e, funcion, ciclo, isObjeto, errores); } else { rsObj = null; } } if (rsObj == null && obj is Identificador) //si no existe, creo la variable si viene con tipo { if (!Tipo.IsIndefinido()) { idObjetivo.Tipo = Tipo; rsObj = new Result(); Sim s = new Sim(((Identificador)obj).Id, Tipo, Rol.LOCAL, 1, e.GetPos(), e.Ambito, -1, -1); rsObj.Simbolo = s; if (isObjeto) { s.IsAtributo = true; } e.Add(s); if (!isDeclaracion) { idObjetivo.PtrVariable = s.Pos + ""; string ptrStack = NuevoTemporal(); if (!isObjeto) { rsObj.Codigo = ptrStack + " = P + " + s.Pos + ";\n"; rsObj.Valor = "stack[" + ptrStack + "]"; } else { string ptrHeap = NuevoTemporal(); string valorHeap = NuevoTemporal(); rsObj.Codigo = ptrStack + " = P + " + 1 + ";\n"; rsObj.Codigo += valorHeap + " = stack[" + ptrStack + "];\n"; rsObj.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n"; rsObj.Valor = "heap[" + ptrHeap + "]"; } } } else { if (!isDeclaracion) { errores.AddLast(new Error("Semántico", "No se pudo encontrar la variable: " + idObjetivo.Id + ".", Linea, Columna)); } return(null); } } else { if (!Tipo.IsIndefinido() && obj is Identificador) { if (!isDeclaracion) { errores.AddLast(new Error("Semántico", "Ya se declaró una variable con el id: " + idObjetivo.Id + ".", Linea, Columna)); } return(null); } } LinkedList <Result> rsList = new LinkedList <Result>(); for (int j = 0; j < Valor.Count(); j++) { LinkedList <Expresion> valList = Valor.ElementAt(j); Expresion expI = valList.ElementAt(i); if (j + 1 == Valor.Count()) { if (!isDeclaracion) { if (expI is Llamada) { ((Llamada)expI).PtrVariable = idObjetivo.PtrVariable; } Result rsTemp = expI.GetC3D(e, funcion, ciclo, isObjeto, errores); if (rsTemp != null) { if (obj is Identificador) { if (expI.GetTipo().Tip != idObjetivo.Tipo.Tip) { errores.AddLast(new Error("Semántico", "El valor a asignar no es del mismo tipo.", Linea, Columna)); return(null); } } else if (obj is Referencia) { if (expI.GetTipo().Tip != refObjetivo.Tipo.Tip) { errores.AddLast(new Error("Semántico", "El valor a asignar no es del mismo tipo.", Linea, Columna)); return(null); } } else if (obj is AccesoLista) { if (expI.GetTipo().Tip != listObjetivo.Tipo.Tip) { errores.AddLast(new Error("Semántico", "El valor a asignar no es del mismo tipo.", Linea, Columna)); return(null); } } rsList.AddLast(rsTemp); } else { errores.AddLast(new Error("Semántico", "El valor contiene errores.", Linea, Columna)); return(null); } } } else { if (expI is Identificador) { if (!Tipo.IsIndefinido()) { ((Identificador)expI).GetLocal = true; } ((Identificador)expI).Acceso = false; Result rsTemp = expI.GetC3D(e, funcion, ciclo, isObjeto, errores); if (rsTemp == null) //si no existe, creo la variable { if (!Tipo.IsIndefinido()) { rsTemp = new Result(); Sim s = new Sim(((Identificador)expI).Id, Tipo, Rol.LOCAL, 1, e.GetPos(), e.Ambito, -1, -1); rsTemp.Simbolo = s; if (isObjeto) { s.IsAtributo = true; } e.Add(s); if (!isDeclaracion) { string ptrStack = NuevoTemporal(); if (!isObjeto) { rsTemp.Codigo = ptrStack + " = P + " + s.Pos + ";\n"; rsTemp.Valor = "stack[" + ptrStack + "]"; } else { string ptrHeap = NuevoTemporal(); string valorHeap = NuevoTemporal(); rsTemp.Codigo = ptrStack + " = P + " + 1 + ";\n"; rsTemp.Codigo += valorHeap + " = stack[" + ptrStack + "];\n"; rsTemp.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n"; rsTemp.Valor = "heap[" + ptrHeap + "]"; } rsTemp.PtrStack = s.Pos; } } else { if (!isDeclaracion) { errores.AddLast(new Error("Semántico", "El valor contiene errores.", Linea, Columna)); } return(null); } } else { if (!Tipo.IsIndefinido()) { if (!isDeclaracion) { errores.AddLast(new Error("Semántico", "Ya se declaró una variable con el id: " + idObjetivo.Id + ".", Linea, Columna)); } return(null); } } rsList.AddLast(rsTemp); } else { return(null); /*No implementado otro tipo de valores(listas)*/ } } } if (!isDeclaracion) { if (rsList.Count() == 1) { if (rsObj.Simbolo != null) { if (rsObj.Simbolo.Tipo.IsList()) { if (rsList.ElementAt(0).Tipo != null) { rsObj.Simbolo.Tipo = rsList.ElementAt(0).Tipo; } } } //rsObj.Tipo = rsList.ElementAt(0).Tipo; rsObj.Codigo += rsList.ElementAt(0).Codigo; rsObj.Codigo += rsObj.Valor + " = " + rsList.ElementAt(0).Valor + ";\n"; } else { Result rsAnt = rsList.ElementAt(rsList.Count() - 1); for (int k = rsList.Count() - 2; k >= 0; k--) { Result rsAct = rsList.ElementAt(k); rsAct.Codigo += rsAnt.Codigo; rsAct.Codigo += rsAct.Valor + " = " + rsAnt.Valor + ";\n"; /*Esto solo funciona con ids*/ string ptrStack = NuevoTemporal(); rsAct.Codigo += ptrStack + " = P + " + rsAct.PtrStack + ";\n"; rsAct.Valor = NuevoTemporal(); rsAct.Codigo += rsAct.Valor + " = stack[" + ptrStack + "];\n"; rsAnt = rsAct; } if (rsObj.Simbolo != null) { if (rsObj.Simbolo.Tipo.IsList()) { if (rsAnt.Tipo != null) { rsObj.Simbolo.Tipo = rsAnt.Tipo; } } } rsObj.Codigo += rsAnt.Codigo; rsObj.Codigo += rsObj.Valor + " = " + rsAnt.Valor + ";\n"; } } if (rsObj != null) { result.Codigo += rsObj.Codigo; } } } return(result); }
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 isDeclaracion, bool isObjeto, LinkedList <Error> errores) { if (!isDeclaracion) { Debugger(e, "Funcion"); } Result result = new Result(); /*Si esto da problemas dejar firma solo con Id*/ string firma = Id; if (Parametros != null) { for (int i = 1; i < Parametros.Count(); i++)/*en 1 porque el self no lo cuento*/ { firma += "_" + Parametros.ElementAt(i).GetTipo().ToString(); } } Sim fun = e.GetMetodo(firma); if (!isDeclaracion) { if (fun != null) { Ent local = new Ent(firma, e); local.Size = fun.Tam; /*Agrego return*/ local.Add(new Sim("return", Tipo, Rol.RETURN, 1, local.GetPos(), local.Ambito, -1, -1)); /*Agrego parametros*/ int parametros = 0; if (Parametros != null) { foreach (Identificador id in Parametros) { local.Add(new Sim(id.Id, id.Tipo, Rol.PARAMETER, 1, local.GetPos(), local.Ambito, -1, 0)); parametros++; } } /*Agrego etiqueta salida*/ local.EtiquetaSalida = NuevaEtiqueta(); result.Codigo += "proc " + e.Ambito + "_" + firma + "() begin\n"; result.Codigo += Bloque.GetC3D(local, true, false, false, isObjeto, errores).Codigo; result.Codigo += local.EtiquetaSalida + ":\n"; result.Codigo += "end\n\n"; fun.Entorno = local; } } else { if (fun == null) { Ent local = new Ent(firma); //local.Pos++; /*Para self*/ local.Add(new Sim("return", Tipo, Rol.RETURN, 1, local.GetPos(), local.Ambito, -1, -1)); local.GetPos(); /*Para return*/ int parametros = 0; if (Parametros != null) { foreach (Identificador id in Parametros) { parametros++; local.GetPos(); } } /*Recorro declaraciones*/ foreach (Nodo sentencia in Bloque.Sentencias) { if (sentencia is Instruccion) { ((Instruccion)sentencia).GetC3D(local, true, false, true, isObjeto, errores); } else { //((Expresion)sentencia).GetC3D(local, true, false, errores); no genera espacios } } fun = new Sim(firma, Tipo, Rol.FUNCION, local.Pos - 1, -1, e.Ambito, parametros, -1); fun.Firma = firma; fun.Entorno = local; e.Add(fun); } else { errores.AddLast(new Error("Semántico", "Ya se declaró una función con la misma firma: " + firma + ".", Linea, Columna)); } } //local.Recorrer(); return(result); }