public static void asignarC3D(ParseTreeNode asignacion) { /* Tree * ASIGNACION.Rule = ACCESO + asignar + EXP; * OLC++ * ASIGNACION.Rule = self + punto + ACCESO + asignar + EXP | ACCESO + asignar + EXP; */ int indice = 0; Acceso.Tipo tipo = Acceso.Tipo.NINGUNO; if (asignacion.ChildNodes[0].Term.Name.Equals("self") || asignacion.ChildNodes[0].Term.Name.Equals("este")) { tipo = Acceso.Tipo.ESTE; indice++; } else if (asignacion.ChildNodes[0].Term.Name.Equals("super")) { tipo = Acceso.Tipo.SUPER; asignacion = asignacion.ChildNodes[1]; } GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener valor de la asignacion")); Nodo exp = Expresion.expresionC3D(asignacion.ChildNodes[indice + 1]); if (exp != null) { if (asignacion.ChildNodes[indice].Term.Name.Equals("ACCESO")) { GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Empezar a Realizar el acceso")); Acceso.generarC3DAcceso(asignacion.ChildNodes[indice], tipo, exp); } } }
public static void guardarC3D(string id, ParseTreeNode arreglo, Acceso.Tipo tipo) { Acceso.actual = null; Nodo nodo = Acceso.generarC3DID(id, tipo, "P", "Stack"); if (nodo == null) { return; } Simbolo sid; if (C3DSentencias.procedimientoActual == null) { sid = TablaSimbolos.getInstance.buscarVariable(id, C3DSentencias.claseActual.nombre, null, tipo); } else { sid = TablaSimbolos.getInstance.buscarVariable(id, C3DSentencias.claseActual.nombre, C3DSentencias.procedimientoActual.nombre, tipo); } // Recorrer los valores del arreglo y guardarlos en la posicion empezando en 0 if (arreglo != null && sid.dimensiones != null) { List <int> dimensiones = new List <int>(); dimensionesArreglo(arreglo, ref dimensiones); for (int i = 0; i < sid.dimensiones.Count; i++) { if (dimensiones[i] != sid.dimensiones[i]) { // Error semantico! No es de las dimensiones que solicita! return; } } // Todo bien! /* String t1 = GeneradorC3D.getTemporal(); * GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, * "// Obtener puntero al heap del arreglo " + id)); * GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ACCESO, nodo.estructura, t1, nodo.referencia)); */ int tamH = sid.getTamanioTotal(); String t1 = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar H disponible en " + id)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR, nodo.estructura, nodo.referencia, "H")); recorrerDimensiones(arreglo, "H"); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Incrementar H para reservar tam del arreglo " + id)); GeneradorC3D.aumentarHeap(Convert.ToString(tamH)); } }
public static Nodo generarAsignacionC3D(string id, ParseTreeNode indices, Acceso.Tipo tipo) { Simbolo sid; if (C3DSentencias.procedimientoActual == null) { sid = TablaSimbolos.getInstance.buscarVariable(id, C3DSentencias.claseActual.nombre, null, tipo); } else { sid = TablaSimbolos.getInstance.buscarVariable(id, C3DSentencias.claseActual.nombre, C3DSentencias.procedimientoActual.nombre, tipo); } if (sid == null) { // Error Semantico! return(null); } if (sid.dimensiones == null) { // Error Semantico! No es un arreglo! return(null); } Nodo nodo = Acceso.generarC3DID(id, tipo, "P", "Stack"); String tpos = generarParametrizacionC3D(indices, sid); if (nodo != null && tpos != null) { GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Sumar la posicion del Heap del arreglo y la posicion del arreglo")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, nodo.referencia, nodo.cadena, "+", tpos)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener el valor en la posicion del arreglo " + id)); nodo.cadena = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ACCESO, "Heap", nodo.cadena, nodo.referencia)); } return(nodo); }
public static Nodo instanciaC3D(ParseTreeNode nuevo, Acceso.Tipo tipo) { // NUEVO -> new id EXPS // SUPER -> super [ EXPS ] Nodo nodo = new Nodo(); // NUEVO String idC = nuevo.ChildNodes[1].Token.Text; // Buscar que la clase exista Clase instancia = GeneradorC3D.getClasePadre(idC); if (instancia != null) { List <Nodo> expresiones = new List <Nodo>(); String llave = getExpresiones(nuevo.ChildNodes[2], ref expresiones); if (llave != null) { llave = "constructor" + llave; Simbolo procedimiento = TablaSimbolos.getInstance.getProcedimiento( instancia.nombre, llave); if (procedimiento == null || procedimiento.visibilidad == (int)Simbolo.Visibilidad.PRIVADO) { // Error Semantico! No se puede hacer instancia por ser privado return(null); } // Get parametros List <Simbolo> sparametros = TablaSimbolos.getInstance.getParametros( instancia.nombre, procedimiento); if (expresiones.Count == sparametros.Count) { int tam = GeneradorC3D.tamMain; if (C3DSentencias.procedimientoActual != null) { // Esta en el main! tam = C3DSentencias.procedimientoActual.tam; } GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Pasar los parametros")); String taux = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Crear un temporal auxiliar para el incremento del ambito")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, taux, "P", "+", Convert.ToString(tam))); parametrosC3D(taux, sparametros, expresiones); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Incrementar el ambito")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, "P", "P", "+", Convert.ToString(tam))); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Llamar al procedimiento " + llave)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.LLAMADA, instancia.nombre + "_" + llave)); // Ver si hay retorno Y guardarlo String temp = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener posicion del retorno en el ambito actual ")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, temp, "P", "+", "2")); nodo.cadena = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener valor del retorno de la funcion " + llave)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ACCESO, "Stack", nodo.cadena, temp)); nodo.tipo = (int)Simbolo.Tipo.CLASE; GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Disminuir el ambito ")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, "P", "P", "-", Convert.ToString(tam))); } } } return(nodo); }
public static Nodo llamadaC3D(ParseTreeNode llamada, Acceso.Tipo tipo) { // LLAMADA.Rule = id + apar + EXPS + CPAR Nodo nodo = new Nodo(); String id = llamada.ChildNodes[0].Token.Text; // Evaluar las expresiones List <Nodo> expresiones = new List <Nodo>(); String llave = getExpresiones(llamada.ChildNodes[1], ref expresiones); if (llave != null) { llave = id + llave; Simbolo procedimiento; // Buscar en la clase que se necesita List <Simbolo> sparametros; if (tipo == Acceso.Tipo.SUPER) { // Buscar en el padre if (C3DSentencias.claseActual.padre == null) { return(null); } procedimiento = TablaSimbolos.getInstance.getProcedimiento( C3DSentencias.claseActual.padre, llave); if (procedimiento == null) { // Error! No existe el procedimiento en la clase padre return(null); } else { if (procedimiento.visibilidad == (int)Simbolo.Visibilidad.PRIVADO) { // Error! No se puede acceder a un procedimiento privado! return(null); } } sparametros = TablaSimbolos.getInstance.getParametros( C3DSentencias.claseActual.padre, procedimiento); } else { // Buscar en la clase actual procedimiento = TablaSimbolos.getInstance.getProcedimiento( C3DSentencias.claseActual.nombre, llave); if (procedimiento == null) { // Error! No existe el procedimiento en la clase } sparametros = TablaSimbolos.getInstance.getParametros( C3DSentencias.claseActual.nombre, procedimiento); } if (expresiones.Count == sparametros.Count) { int tam = GeneradorC3D.tamMain; if (C3DSentencias.procedimientoActual != null) { // Esta en el main! tam = C3DSentencias.procedimientoActual.tam; } GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Pasar los parametros")); String taux = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Crear un temporal auxiliar para el incremento del ambito")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, taux, "P", "+", Convert.ToString(tam))); parametrosC3D(taux, sparametros, expresiones); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Incrementar el ambito")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, "P", "P", "+", Convert.ToString(tam))); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Llamar al procedimiento " + llave)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.LLAMADA, procedimiento.padre + "_" + llave)); // Ver si hay retorno Y guardarlo if (procedimiento.rol == (int)Simbolo.Tipo.FUNCION) { String temp = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener posicion del retorno en el ambito actual ")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, temp, "P", "+", "2")); nodo.cadena = GeneradorC3D.getTemporal(); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener valor del retorno de la funcion " + llave)); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ACCESO, "Stack", nodo.cadena, temp)); nodo.tipo = procedimiento.tipo; } GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Disminuir el ambito ")); GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, "P", "P", "-", Convert.ToString(tam))); } else { // Error! Faltan parametros! return(null); } } return(nodo); }
public Simbolo buscarVariable(String nombre, String clase, String procedimiento, Acceso.Tipo tipo) { if (tipo == Acceso.Tipo.NINGUNO) { return(getVariable(nombre, clase, procedimiento)); } else if (tipo == Acceso.Tipo.ESTE) { return(getVariableGlobal(nombre, clase)); } else { return(getVariableHeredada(nombre, clase)); } }