示例#1
0
文件: Clase.cs 项目: Oshhcar/Colette
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }