Exemple #1
0
        public object compilar(Entorno ent, Errores errores)
        {
            Retorno value;

            if (this.value == null)
            {
                value = new Retorno("0", false, new Tipo(Tipos.VOID));
            }
            else
            {
                value = this.value.compilar(ent);
            }
            SimboloFunction symFunc   = ent.actualFunc;
            Generator       generator = Generator.getInstance();

            if (symFunc == null)
            {
                throw new Error("Semántico", "Exit no esta dentro de una función", ent.obtenerAmbito(), linea, columna);
            }
            if (!this.sameType(symFunc.type, value.type))
            {
                throw new Error("Semántico", "Se esperaba en Exit un " + symFunc.type.tipoToString() + " y se obtuvo un " + value.type.tipoToString(), ent.obtenerAmbito(), linea, columna);
            }
            if (symFunc.type.tipo == Tipos.BOOLEAN)
            {
                string templabel = generator.newLabel();
                generator.addLabel(value.trueLabel);
                generator.addSetStack("SP", "1");
                generator.addGoto(templabel);
                generator.addLabel(value.falseLabel);
                generator.addSetStack("SP", "0");
                generator.addLabel(templabel);
            }
            else if (symFunc.type.tipo != Tipos.VOID)
            {
                generator.addSetStack("SP", value.getValue());
            }

            if (!isAsignacion)
            {
                generator.addGoto(ent.yreturn);
            }
            return(null);
        }
Exemple #2
0
        public Retorno compilar(Entorno ent)
        {
            if (this.anterior == null)
            {
                SimboloFunction symFunc = ent.searchFunc(this.id);
                if (symFunc == null)
                {
                    throw new Error("Semántico", "No se encontro la función: " + this.id, ent.obtenerAmbito(), linea, columna);
                }
                LinkedList <Retorno> paramsValues = new LinkedList <Retorno>();
                Generator            generator    = Generator.getInstance();
                int size = generator.saveTemps(ent); //Guardo temporales

                foreach (Expresion param in this.parametros)
                {
                    if (param is AccessId)
                    {
                        AccessId access = (AccessId)param;
                        access.vieneDeRelacional = true;
                    }
                    paramsValues.AddLast(param.compilar(ent));
                }

                //Verifico si viene el mismo numero de parametros
                if (paramsValues.Count != symFunc.parametros.Count)
                {
                    throw new Error("Semántico", "Faltan parametros a enviar en la llamada a la funcion:" + this.id, ent.obtenerAmbito(), linea, columna);
                }
                //Verifico si coninciden los tipos de los parametros
                if (!this.validarTipoParametros(paramsValues, symFunc.parametros))
                {
                    throw new Error("Semántico", "No coincide un tipo de parametro en la llamada a la funcion:" + this.id, ent.obtenerAmbito(), linea, columna);
                }

                string temp = generator.newTemporal();
                generator.freeTemp(temp);
                //Paso de parametros en cambio simulado
                if (paramsValues.Count != 0)
                {
                    generator.addExpression(temp, "SP", "" + (ent.size + 1), "+"); //+1 porque la posicion 0 es para el retorno;
                    int index = -1;
                    foreach (Retorno value in paramsValues)
                    {
                        index++;
                        Param param = symFunc.parametros.ElementAt(index);
                        if (param.isRef)
                        {
                            if (value.symbol.isGlobal)
                            {
                                generator.addSetStack(temp, "" + value.symbol.position);
                                generator.addExpression(temp, temp, "1", "+");
                                generator.addSetStack(temp, "1");
                            }
                            else if (value.symbol.isHeap)
                            {
                                generator.addSetStack(temp, "" + value.symbol.position);
                                generator.addExpression(temp, temp, "1", "+");
                                generator.addSetStack(temp, "0");
                            }
                            else
                            {
                                string temp2 = generator.newTemporal();
                                generator.freeTemp(temp2);
                                generator.addExpression(temp2, "SP", "" + value.symbol.position, "+");

                                generator.addSetStack(temp, temp2);
                                generator.addExpression(temp, temp, "1", "+");
                                generator.addSetStack(temp, "1");
                            }
                        }
                        else
                        {
                            generator.addSetStack(temp, value.getValue());
                        }

                        if (index != paramsValues.Count - 1)
                        {
                            generator.addExpression(temp, temp, "1", "+");
                        }
                    }
                }

                generator.addNextEnv(ent.size);
                generator.addCall(symFunc.uniqueId);
                if (symFunc.type.tipo != Tipos.VOID)
                {
                    generator.addGetStack(temp, "SP");
                }
                generator.addAntEnv(ent.size);

                generator.recoverTemps(ent, size);
                generator.addTemp(temp);

                if (symFunc.type.tipo != Tipos.BOOLEAN)
                {
                    return(new Retorno(temp, true, symFunc.type));
                }

                Retorno retorno = new Retorno("", false, symFunc.type);
                this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                generator.addIf(temp, "1", "==", this.trueLabel);
                generator.addGoto(this.falseLabel);
                retorno.trueLabel  = this.trueLabel;
                retorno.falseLabel = this.falseLabel;
                return(retorno);
            }
            else
            {
            }
            throw new Error("Semántico", "Funcion no implementada", ent.obtenerAmbito(), linea, columna);
        }
Exemple #3
0
        public object compilar(Entorno ent, Errores errores)
        {
            try
            {
                Generator generator = Generator.getInstance();
                generator.addComment("Inicia Asignacion");

                if (ent.ambito.Equals("FUNCTION"))
                {
                    SimboloFunction symFunc = ent.actualFunc;
                    if (symFunc != null)
                    {
                        AsignacionId mytarget = (AsignacionId)this.target;
                        if (mytarget.id.ToLower().Equals(symFunc.id.ToLower())) //Es un Return
                        {
                            Return @return = new Return(this.value, linea, columna);
                            @return.isAsignacion = true;
                            return(@return.compilar(ent, errores));
                        }
                    }
                }

                Retorno target = this.target.compilar(ent);
                Retorno value  = this.value.compilar(ent);

                Simbolo symbol = target.symbol;
                if (symbol.isConst)
                {
                    throw new Error("Semántico", "No se puede cambiar el valor de una constante", ent.obtenerAmbito(), linea, columna);
                }
                if (!sameType(target.type, value.type))
                {
                    throw new Error("Semántico", "No coincide el tipo de dato de la variable con el tipo de valor a asignar", ent.obtenerAmbito(), linea, columna);
                }
                if (symbol.isHeap == false) //ES GLOBAL
                {
                    if (target.type.tipo == Tipos.BOOLEAN)
                    {
                        //Mi modificacion
                        if (value.getValue().Equals("1"))
                        {
                            generator.addGoto(value.trueLabel);
                        }
                        else
                        {
                            generator.addGoto(value.falseLabel);
                        }

                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addSetStack(target.getValue(), "1");
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addSetStack(target.getValue(), "0");
                        generator.addLabel(templabel);
                    }
                    else
                    {
                        generator.addSetStack(target.getValue(), value.getValue());
                    }
                }
                else if (symbol.isHeap)
                {
                    if (target.type.tipo == Tipos.BOOLEAN)
                    {
                        //Mi modificacion
                        if (value.getValue().Equals("1"))
                        {
                            generator.addGoto(value.trueLabel);
                        }
                        else
                        {
                            generator.addGoto(value.falseLabel);
                        }

                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addSetHeap(target.getValue(), "1");
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addSetHeap(target.getValue(), "0");
                        generator.addLabel(templabel);
                    }
                    else
                    {
                        generator.addSetHeap(target.getValue(), value.getValue());
                    }
                }
                generator.addComment("Finaliza Asignacion");
            } catch (Error ex)
            {
                errores.agregarError(ex);
            }
            return(null);
        }