コード例 #1
0
        public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores)
        {
            if (funcion)
            {
                Result result = new Result();
                Sim    ret    = e.GetGlobal("return");

                if (Valor != null)
                {
                    if (!ret.Tipo.IsVoid())
                    {
                        Result rsValor = Valor.GetC3D(e, funcion, ciclo, isObjeto, errores);

                        if (!Valor.GetTipo().IsIndefinido())
                        {
                            if (rsValor.Valor != null)
                            {
                                if (ret.Tipo.Tip == Valor.GetTipo().Tip)
                                {
                                    result.Valor   = NuevoTemporal();
                                    result.Codigo += result.Valor + " = P + " + ret.Pos + ";\n";

                                    result.Codigo += rsValor.Codigo;
                                    result.Codigo += "stack[" + result.Valor + "] = " + rsValor.Valor + ";\n";
                                }
                                else
                                {
                                    errores.AddLast(new Error("Semántico", "El tipo de return no es el mismo de la función: " + ret.Tipo.ToString() + ".", Linea, Columna));
                                    return(null);
                                }
                            }
                            else
                            {
                                errores.AddLast(new Error("Semántico", "El valor del return contiene errores.", Linea, Columna));
                                return(null);
                            }
                        }
                        else
                        {
                            errores.AddLast(new Error("Semántico", "El valor del return contiene errores.", Linea, Columna));
                            return(null);
                        }
                    }
                    else
                    {
                        errores.AddLast(new Error("Semántico", "No se espera valor en return.", Linea, Columna));
                    }
                }
                else
                {
                    if (!ret.Tipo.IsVoid())
                    {
                        errores.AddLast(new Error("Semántico", "Se espera valor en return.", Linea, Columna));
                        return(null);
                    }
                }

                result.Codigo += "goto " + e.EtiquetaSalida + ";\n";

                return(result);
            }
            else
            {
                errores.AddLast(new Error("Semántico", "El return no se encuentra dentro de una función", Linea, Columna));
                return(null);
            }
        }
コード例 #2
0
        public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores)
        {
            Sim s = null;

            if (GetLocal)
            {
                s = e.Get(Id);
            }
            else
            {
                s = e.GetGlobal(Id);
            }

            if (s != null)
            {
                Tipo = s.Tipo;
                Result result = new Result();

                PtrVariable    = s.Pos + "";
                Simbolo        = s;
                result.Simbolo = s;

                if (!IsDeclaracion)
                {
                    if (Acceso)
                    {
                        result.Valor = NuevoTemporal();

                        if (s.Rol == Rol.GLOBAL)
                        {
                            result.Codigo += result.Valor + " = heap[" + s.Pos + "];\n";
                        }
                        else if (s.IsAtributo)
                        {
                            string ptrStack  = NuevoTemporal();
                            string ptrHeap   = NuevoTemporal();
                            string valorHeap = NuevoTemporal();

                            result.Codigo  = ptrStack + " = P + 1;\n";
                            result.Codigo += valorHeap + " = stack[" + ptrStack + "];\n";
                            result.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n";
                            result.Codigo += result.Valor + " = heap[" + ptrHeap + "]";
                        }
                        else
                        {
                            string ptrStack = NuevoTemporal();
                            result.Codigo  = ptrStack + " = P + " + s.Pos + ";\n";
                            result.Codigo += result.Valor + " = stack[" + ptrStack + "];\n";
                        }
                    }
                    else
                    {
                        result.PtrStack = s.Pos;
                        if (s.Rol == Rol.GLOBAL)
                        {
                            result.Valor = "heap[" + s.Pos + "]";
                        }
                        else if (s.IsAtributo)
                        {
                            string ptrStack  = NuevoTemporal();
                            string ptrHeap   = NuevoTemporal();
                            string valorHeap = NuevoTemporal();

                            result.Codigo  = ptrStack + " = P + 1;\n";
                            result.Codigo += valorHeap + " = stack[" + ptrStack + "];\n";
                            result.Codigo += ptrHeap + " = " + valorHeap + " + " + s.Pos + ";\n";
                            result.Valor   = "heap[" + ptrHeap + "]";
                        }
                        else
                        {
                            string ptrStack = NuevoTemporal();
                            result.Codigo = ptrStack + " = P + " + s.Pos + ";\n";
                            result.Valor  = "stack[" + ptrStack + "]";
                        }
                    }
                }
                return(result);
            }
            else
            {
                if (Acceso)
                {
                    errores.AddLast(new Error("Semántico", "La variable: " + Id + " no está declarada.", Linea, Columna));
                }
            }
            return(null);
        }
コード例 #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);
        }