public static void declararAsignarC3D(ParseTreeNode declaracion)
 {
     /* OLC++
      * DECLARACION.Rule = TIPO + LISTA_IDS + asignarR *---*
      | TIPO + LISTA_IDS + DARREGLO -> INDICES (ARREGLO)? *---*
      | TIPO + LISTA_IDS;
      * Tree
      * DECLARACION.Rule = TIPO + LISTA_IDS + asignarR *---*
      | TIPO + LISTA_IDS
      | TIPO + NARREGLO;
      */
     if (declaracion.ChildNodes.Count == 3)
     {
         int           tipo = Simbolo.getTipo(declaracion.ChildNodes[0].Token.Text);
         ParseTreeNode ids  = declaracion.ChildNodes[1];
         foreach (ParseTreeNode id in ids.ChildNodes)
         {
             if (declaracion.ChildNodes[2].Term.Name.Equals("DARREGLO"))
             {
                 ParseTreeNode darr = declaracion.ChildNodes[2];
                 // Guardar espacio
                 if (darr.ChildNodes.Count == 2)
                 {
                     // DARREGLO -> INDICES ARREGLO
                     Arreglo.guardarC3D(id.Token.Text, darr.ChildNodes[1], Acceso.Tipo.NINGUNO);
                 }
                 else
                 {
                     Arreglo.guardarC3D(id.Token.Text, null, Acceso.Tipo.NINGUNO);
                 }
             }
             else
             {
                 // EXP
                 Acceso.actual = null;
                 Nodo exp  = Expresion.expresionC3D(declaracion.ChildNodes[2]);
                 Nodo nodo = Acceso.generarC3DID(id.Token.Text, Acceso.Tipo.NINGUNO,
                                                 "P", "Stack");
                 // Asignar la expresion
                 GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR,
                                                        nodo.estructura, nodo.referencia, exp.cadena));
             }
         }
     }
     else
     {
         // 2 hijos
         if (declaracion.ChildNodes[1].Term.Name.Equals("NARREGLO"))
         {
             ParseTreeNode id = declaracion.ChildNodes[1].ChildNodes[0];
             Arreglo.guardarC3D(id.Token.Text, null, Acceso.Tipo.NINGUNO);
         }
     }
 }
        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));
            }
        }
        private static void generarC3DThis(Clase clase, String puntero, String estructura)
        {
            Simbolo sclase = TablaSimbolos.getInstance.getClase(clase.nombre);

            if (sclase != null)
            {
                String t1 = getTemporal();
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar apuntador del this"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, t1, puntero, "+", "0"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar apuntador donde incia el this"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR, estructura, t1, "H"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Reservar espacio para globales de " + clase.nombre));
                aumentarHeap(Convert.ToString(sclase.tam));
                // Recorrer las variables globales y asignarles
                foreach (Atributo atr in clase.atributos)
                {
                    if (atr.esArreglo)
                    {
                        Arreglo.guardarC3D(atr.nombre, atr.valor, Acceso.Tipo.ESTE);
                    }
                    else
                    {
                        if (atr.valor != null)
                        {
                            instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener valor del atributo " + atr.nombre));
                            Nodo exp = Expresion.expresionC3D(atr.valor);
                            Acceso.actual = null;
                            instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener posicion del atributo " + atr.nombre));
                            Nodo nodo = Acceso.generarC3DID(atr.nombre, Acceso.Tipo.ESTE, "P", "Stack");
                            if (nodo != null)
                            {
                                // Asignar la expresion
                                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Asignar expresion al atributo " + atr.nombre));
                                instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR,
                                                          nodo.estructura, nodo.referencia, exp.cadena));
                            }
                        }
                    }
                }
            }
        }
        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);
        }
        private static void generarC3DSuper(Clase clase, String puntero, String estructura)
        {
            Simbolo sclase = TablaSimbolos.getInstance.getClase(clase.nombre);

            if (sclase != null)
            {
                String t1 = getTemporal();
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar apuntador del super"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.ASIGNACION, t1, puntero, "+", "1"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar posicion donde empieza super"));
                instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR, estructura, t1, "H"));
                // Buscar clase padre
                Clase padre;
                if (clase.padre != null)
                {
                    padre = getClasePadre(clase.padre);
                    if (padre == null)
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
                sclase = TablaSimbolos.getInstance.getClase(clase.padre);
                if (sclase == null)
                {
                    return;
                }
                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Reservar espacio para la clase padre" + sclase.nombre));
                aumentarHeap(Convert.ToString(sclase.tam));
                // Recorrer las variables globales y asignarles
                foreach (Atributo atr in padre.atributos)
                {
                    if (atr.visibilidad == (int)Simbolo.Visibilidad.PUBLICO ||
                        atr.visibilidad == (int)Simbolo.Visibilidad.PROTEGIDO)
                    {
                        if (atr.esArreglo)
                        {
                            Arreglo.guardarC3D(atr.nombre, atr.valor, Acceso.Tipo.SUPER);
                        }
                        else
                        {
                            if (atr.valor != null)
                            {
                                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener valor del atributo " + atr.nombre));
                                Nodo exp = Expresion.expresionC3D(atr.valor);
                                Acceso.actual = null;
                                instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Obtener posicion del atributo " + atr.nombre));
                                Nodo nodo = Acceso.generarC3DID(atr.nombre, Acceso.Tipo.SUPER,
                                                                "P", "Stack");
                                if (nodo != null)
                                {
                                    // Asignar la expresion
                                    instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Guardar valor del atributo " + atr.nombre));
                                    instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR,
                                                              nodo.estructura, nodo.referencia, exp.cadena));
                                }
                            }
                        }
                    }
                }
            }
        }