public static void generarC3D(ParseTreeNode sentencias)
        {
            foreach (ParseTreeNode sentencia in sentencias.ChildNodes)
            {
                switch (sentencia.Term.Name)
                {
                case "DECLARACION":
                    if (sentencia.ChildNodes.Count == 3)
                    {
                        declararAsignarC3D(sentencia);
                    }
                    break;

                case "ASIGNACION":
                    asignarC3D(sentencia);
                    break;

                case "SUPER":
                    if (sentencia.ChildNodes[1].Term.Name.Equals("ASIGNACION"))
                    {
                        asignarC3D(sentencia);
                    }
                    else if (sentencia.ChildNodes[1].Term.Name.Equals("ACCESO"))
                    {
                        // super + ACCESO
                        Acceso.generarC3DAcceso(sentencia.ChildNodes[1], Acceso.Tipo.SUPER, null);
                    }
                    else
                    {
                        // super + [ + EXPS + ]
                    }
                    break;

                case "ACCESO":
                    Acceso.generarC3DAcceso(sentencia, Acceso.Tipo.NINGUNO, null);
                    break;

                case "RETORNO":
                    if (procedimientoActual != null)
                    {
                        if (procedimientoActual.rol == (int)Simbolo.Tipo.FUNCION)
                        {
                            // Evaluar expresion
                            Nodo expRetorno = Expresion.expresionC3D(sentencia.ChildNodes[0]);
                            if (expRetorno != null)
                            {
                                // Guardar en retorno la posicion del objeto creado
                                String temp = C3DSentencias.retornarC3D(sentencia.Span.Location.Line, sentencia.Span.Location.Column);
                                if (!temp.Equals(""))
                                {
                                    GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO,
                                                                           "// Guardar el retorno en la posicion"));
                                    GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.VALOR, "Stack", temp,
                                                                           expRetorno.cadena));
                                    GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO,
                                                                           "// Salto al final de la funcion " + procedimientoActual.nombre));
                                    GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.INCONDICIONAL, eFinProcedimiento));
                                }
                            }
                        }
                        else
                        {
                            if (procedimientoActual.rol == (int)Simbolo.Tipo.METODO)
                            {
                                Errores.getInstance.agregar(new Error((int)Error.tipoError.SEMANTICO,
                                                                      "Retornar vino dentro de un metodo!", sentencia.Span.Location.Line,
                                                                      sentencia.Span.Location.Column));
                            }
                            else
                            {
                                Errores.getInstance.agregar(new Error((int)Error.tipoError.SEMANTICO,
                                                                      "Retornar vino dentro de un constructor!", sentencia.Span.Location.Line,
                                                                      sentencia.Span.Location.Column));
                            }
                        }
                    }
                    break;

                case "IMPRIMIR":
                    Nodo exp = Expresion.expresionC3D(sentencia.ChildNodes[1]);
                    // Recorrer e imprimir segun el caso
                    if (exp != null)
                    {
                        Imprimir.imprimirC3D(exp);
                    }
                    break;

                case "NATIVAS":
                    Nodo expN = Expresion.expresionC3D(sentencia.ChildNodes[1]);
                    if (expN != null)
                    {
                        Convertidor.generarC3D(sentencia.ChildNodes[0].Token.Text, expN);
                    }
                    break;

                case "CONTINUAR":
                    // continue;
                    String eInicio = GeneradorC3D.display.buscarInicio();
                    if (eInicio == null)
                    {
                        Errores.getInstance.agregar(new Error((int)Error.tipoError.SEMANTICO,
                                                              "Continuar vino fuera de un ciclo.", sentencia.Span.Location.Line,
                                                              sentencia.Span.Location.Column));
                    }
                    else
                    {
                        GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Continue"));
                        GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.INCONDICIONAL, eInicio));
                    }
                    break;

                case "INTERRUMPIR":
                    // break;
                    String eSalidaI = GeneradorC3D.display.buscarSalida();
                    if (eSalidaI == null)
                    {
                        Errores.getInstance.agregar(new Error((int)Error.tipoError.SEMANTICO,
                                                              "Interrumpir vino fuera de un ciclo.", sentencia.Span.Location.Line,
                                                              sentencia.Span.Location.Column));
                    }
                    else
                    {
                        GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.COMENTARIO, "// Break"));
                        GeneradorC3D.instrucciones.Add(new C3D((int)C3D.TipoC3D.INCONDICIONAL, eSalidaI));
                    }
                    break;

                case "IF1":
                    // IF1 -> EXP Sentencias
                    String eSalida = GeneradorC3D.getEtiqueta();
                    Si.evaluarSi(sentencia.ChildNodes[0], sentencia.ChildNodes[1], eSalida);
                    GeneradorC3D.generarEtiquetas(eSalida);
                    break;

                case "IF2":
                    // IF2 -> EXP Sentencias Sentencias
                    String eSalida2 = GeneradorC3D.getEtiqueta();
                    Si.evaluarSi(sentencia.ChildNodes[0], sentencia.ChildNodes[1], eSalida2);
                    Si.evaluarSino(sentencia.ChildNodes[2], eSalida2);
                    GeneradorC3D.generarEtiquetas(eSalida2);
                    break;

                case "IF3":
                    // IF3 -> EXP Sentencias IF4

                    /*
                     * IF4.Rule = IF4 EXP Sentencias
                     | EXP Sentencias;
                     * */
                    String eSalida3 = GeneradorC3D.getEtiqueta();
                    Si.evaluarSi(sentencia.ChildNodes[0], sentencia.ChildNodes[1], eSalida3);
                    Si.evaluarIF4(sentencia.ChildNodes[2], eSalida3);
                    GeneradorC3D.generarEtiquetas(eSalida3);
                    break;

                case "IF5":
                    // IF5 -> EXP Sentencias IF4 Sentencias
                    String eSalida4 = GeneradorC3D.getEtiqueta();
                    Si.evaluarSi(sentencia.ChildNodes[0], sentencia.ChildNodes[1], eSalida4);
                    Si.evaluarIF4(sentencia.ChildNodes[2], eSalida4);
                    Si.evaluarSino(sentencia.ChildNodes[3], eSalida4);
                    GeneradorC3D.generarEtiquetas(eSalida4);
                    break;

                case "FOR":
                    // FOR.Rule = Fasignar (D o A) EXP EXP Sentencias
                    // Declarar o asignar!
                    Para.evaluarParaC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1],
                                        sentencia.ChildNodes[2], sentencia.ChildNodes[3]);
                    break;

                case "WHILE":
                    //WHILE -> EXP Sentencias
                    Mientras.evaluarMientrasC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1]);
                    break;

                case "X":
                    X.evaluarXC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1], sentencia.ChildNodes[2]);
                    break;

                case "REPEAT":
                    Repetir.evaluarRepetirC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1]);
                    break;

                case "DO_WHILE":
                    Hacer.evaluarHacerC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1]);
                    break;

                case "SWITCH":
                    Elegir.evaluarElegirC3D(sentencia.ChildNodes[0], sentencia.ChildNodes[1]);
                    break;

                case "LOOP":
                    Loop.evaluarLoopC3D(sentencia.ChildNodes[0].ChildNodes[0]);
                    break;
                }
            }
        }
        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));
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        public static Nodo expresionC3D(ParseTreeNode nodo)
        {
            switch (nodo.ChildNodes.Count)
            {
                #region "3 hijos"
            case 3:
                //EXP -> 3 hijos
                ParseTreeNode nder = nodo.ChildNodes[1];
                String        operador;
                if (nder.Term.Name.Equals("EXP"))
                {
                    operador = nodo.ChildNodes[2].Token.Value.ToString();
                }
                else
                {
                    operador = nodo.ChildNodes[1].Token.Value.ToString();
                    nder     = nodo.ChildNodes[2];
                }
                if (operador.Equals("+") || operador.Equals("-") || operador.Equals("*") || operador.Equals("/") || operador.Equals("pow") || operador.Equals("^"))
                {
                    //ARITMETICAS!
                    Nodo aritmetica = Aritmetica.generarC3D(nodo.ChildNodes.ElementAt(0), operador, nder);
                    if (aritmetica != null)
                    {
                        aritmetica.referencia = "error";
                    }
                    return(aritmetica);
                }
                else if (operador.Equals("==") || operador.Equals("!=") || operador.Equals(">") || operador.Equals(">=") || operador.Equals("<") || operador.Equals("<="))
                {
                    //RELACIONALES!
                    Nodo relacional = Relacional.generarC3D(nodo.ChildNodes.ElementAt(0), operador, nder);
                    if (relacional != null)
                    {
                        relacional.referencia = "error";
                    }
                    return(relacional);
                }
                else
                {
                    //LOGICAS!
                    Nodo logica = Logica.generarC3D(nodo.ChildNodes.ElementAt(0), operador, nder);
                    if (logica != null)
                    {
                        logica.referencia = "error";
                    }
                    return(logica);
                }

                #endregion
                #region "2 hijos"
            case 2:
                ParseTreeNode n1 = nodo.ChildNodes[0];
                ParseTreeNode n2 = nodo.ChildNodes[1];

                /*
                 | EXP + ToTerm("-")
                 | EXP + ToTerm("not")
                 | ToTerm("-") + EXP
                 | ToTerm("not") + EXP
                 | super + punto + ACCESO
                 | self + punto + ACCESO
                 */
                if (n1.Term.Name.Equals("super") || n1.Term.Name.Equals("este") || n1.Term.Name.Equals("this"))
                {
                    // (super | self)  ACCESO)
                    if (n1.Term.Name.Equals("super"))
                    {
                        return(Acceso.generarC3DAcceso(n2, Acceso.Tipo.SUPER, null));
                    }
                    else
                    {
                        return(Acceso.generarC3DAcceso(n2, Acceso.Tipo.NINGUNO, null));
                    }
                }
                else
                {
                    // Ver si es de OLC++ o Tree
                    if (n1.Term.Name.Equals("EXP"))
                    {
                        ParseTreeNode aux = n2;
                        n2 = n1;
                        n1 = aux;
                    }
                    if (n1.Term.Name.Equals("not") || n1.Term.Name.Equals("!"))
                    {
                        // NEGACION
                        return(Logica.negacionC3D(n2));
                    }
                    else
                    {
                        // UNARIO
                        return(Aritmetica.unarioC3D(n2));
                    }
                }

                #endregion
                #region "1 hijo"
            default:
                //EXP -> 1 hijo
                String tipo = nodo.ChildNodes.ElementAt(0).Term.Name;
                Nodo   nval = new Nodo();
                switch (tipo)
                {
                case "NUEVO":
                    // Generar codigo 3D de llamara a constructor
                    return(Llamada.instanciaC3D(nodo.ChildNodes[0], Acceso.Tipo.NINGUNO));

                case "NATIVAS":
                    Nodo exp = expresionC3D(nodo.ChildNodes[1]);
                    if (exp != null)
                    {
                        return(Convertidor.generarC3D(nodo.ChildNodes[0].Token.Text, exp));
                    }
                    break;

                case "numero":
                    nval.tipo   = (int)Simbolo.Tipo.NUMERO;
                    nval.cadena = nodo.ChildNodes.ElementAt(0).Token.Value.ToString();
                    if (nval.cadena.Contains("."))
                    {
                        nval.tipo = (int)Simbolo.Tipo.DECIMAL;
                    }
                    return(nval);

                case "ACCESO":
                    return(Acceso.generarC3DAcceso(nodo.ChildNodes[0], Acceso.Tipo.NINGUNO, null));

                case "CRECE":
                    return(Aritmetica.generarCrecimientoC3D(nodo.ChildNodes[0]));

                case "cadena":
                    return(guardarCadenaC3D(nodo.ChildNodes[0].Token.Value.ToString().Replace("\"", "")));

                case "caracter":
                    nval.tipo = (int)Simbolo.Tipo.CARACTER;
                    String cadena = nodo.ChildNodes[0].Token.Value.ToString().Replace("'", "");
                    int    val    = (int)cadena.ElementAt(0);
                    nval.cadena = Convert.ToString(val);
                    return(nval);

                case "BANDERA":
                    return(Logica.banderaC3D(nodo.ChildNodes.ElementAt(0)));

                default:
                    return(expresionC3D(nodo.ChildNodes.ElementAt(0)));
                }
                break;
                #endregion
            }
            return(null);
        }