Example #1
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            Metodo transformado = obj as Metodo;

            if (transformado == null)
            {
                return(false);
            }
            return(Equals(transformado));
        }
Example #2
0
        private void agregarFuncion(ParseNode raiz, string ambito)//espera
        {
            Metodo nuevo   = new Metodo(raiz, ambito);
            int    fila    = raiz.childNodes[1].Fila;    //fila del id
            int    columna = raiz.childNodes[1].Columna; //columna del id

            if (!existeMetodo(nuevo))                    //si no existe
            {
                lista_metodos.Add(nuevo);
            }
            else
            {
                addError(new Nodo(fila, columna, "El metodo:" + nuevo.Nombre + " ya fue declarado", "<error>"));
            }
        }
Example #3
0
 private bool Equals(Metodo otro)
 {
     return(ToString().Equals(otro.ToString()));
 }
Example #4
0
 private bool existeMetodo(Metodo nuevo)
 {
     return(lista_metodos.Contains(nuevo));
 }
Example #5
0
        private Nodo llamada(ParseNode raiz)
        {
            //los hijos de llamada tienen la forma: nombre_funcion <VALORES>
            //1.-recuperamos el nombre del metodo
            string id_metodo = raiz.izq().ToString();

            //2.-Verificamos si existe el metodo, en este punto todavia no vemos si el no. de parametros es correcto
            if (!existeMetodo(id_metodo))
            {
                return(null);
            }
            //3.-Una vez que revisamos que existe el metodo revisamos si hay valores para recuperar el metodo
            Metodo funcion = null;
            Nodo   retorno = null;

            if (raiz.der() == null)//no hay valores
            {
                funcion = getMetodo(id_metodo);
                //4.-Si no encontramos un metodo sin parametros, es error
                if (funcion == null)
                {
                    addError(new Nodo(raiz.Fila, raiz.Columna, "El metodo:" + id_metodo + " no existe", "<error>"));
                    return(new Nodo(raiz.Fila, raiz.Columna, "1", "Int"));//retornamos un entero por si acaso, para continuar con la ejecucion
                }
                //5.-Si no es null entonces ejecutamos el metodo sin parametros
                TablaSimbolo aux = tabla_local;        //se guarda la tabla actual
                tabla_local = new TablaSimbolo();      //pasamos a una tabla para if
                tabla_local.cambiarAmbito(aux);        //pasamos los valores de aux a local
                pila_ambito.Push(id_metodo);           //agregamos el nuevo ambito
                retorno = ejecutar(funcion.Sentencia); //llamamos la raiz de las sentencias de funcion y las mandamos a ejecutar
                //6.-Solo aqui sabemos el tipo de la funcion y el tipo de retorno, asi que revisamos y lanzamos un error de ser necesario

                tabla_local = aux;//recuperamos la tabla local
            }
            else//si hay valores
            {
                //4.-calculamos los valores y los metemos en una lista
                List <Nodo> valores   = new List <Nodo>();
                Nodo        resultado = null;
                foreach (ParseNode valor in raiz.der().childNodes) //llamada->valores
                {
                    resultado = calculo(valor);                    //calculo agrega cualquier error, no retorna null en ningun caso
                    valores.Add(resultado);
                }
                //5.-Teniendo los valores generamos el id extra
                string id_extra = "";
                foreach (Nodo val in valores)
                {
                    id_extra += val.Tipo;
                }
                //6.-Con el id extra buscamos otra vez a funcion pero con id_metodo+id_extra
                funcion = getMetodo(id_metodo + id_extra);
                //7.-Si no encontramos un metodo con esos parametros, es error, no se puede hacer typecasting para parametros, eso se haria con templates y no lo maneja nuestra gramatica
                if (funcion == null)
                {
                    addError(new Nodo(raiz.Fila, raiz.Columna, "El metodo:" + id_metodo + "con parametros:" + id_extra + " no existe", "<error>"));
                    pila_ambito.Pop();                                     //nuevo
                    return(new Nodo(raiz.Fila, raiz.Columna, "1", "Int")); //retornamos un entero por si acaso, para continuar con la ejecucion
                }
                //8.-Si no es null ejecutamos el metodo, pero antes agregamos a su tabla, simbolos que corresponden a sus parametros
                //esta forma de agregar es distinda, pues si el metodo es recursivo y declara una variable, en lugar de intentar declararla otra vez, cambiamos su valor
                TablaSimbolo aux = tabla_local;   //se guarda la tabla actual
                tabla_local = new TablaSimbolo(); //pasamos a una tabla para if
                tabla_local.cambiarAmbito(aux);   //pasamos los valores de aux a local
                pila_ambito.Push(id_metodo);      //agregamos el nuevo ambito
                //8.1.-Aqui agregamos los parametros como simbolo
                int     limite       = valores.Count;
                Simbolo actual       = null;
                Nodo    valor_actual = null;
                for (int i = 0; i < limite; i++)
                {
                    actual       = funcion.parametros[i];
                    valor_actual = valores[i];
                    actual.asignar(valor_actual);
                    tabla_local.replace(actual);//esta es la funcion que agrega o reemplaza cuando es requerido
                }
                //9.-ejecutamos
                retorno     = ejecutar(funcion.Sentencia); //llamamos la raiz de las sentencias de funcion y las mandamos a ejecutar
                tabla_local = aux;                         //recuperamos la tabla local
            }
            if ("<RETORNO>".Equals(retorno.Tipo))
            {
                retorno.Tipo = retorno.Sub_tipo;
            }
            pila_ambito.Pop();
            return(retorno);
        }