Esempio n. 1
0
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            countOfClicles++;
            bool problem = false; //para no meter una variable que esta mal en el Scope

            //hay que ver que no exista una variable ni una funcion con el mismo nombre que la del for
            foreach (Scope scope in scope_list)
            {
                if (scope.Vars.Any(s => s.Key.Equals(this.Name))) //pregunto por las variables
                {
                    errors.Add(new Error(line, column, "Ya existe una variable con el nombre: " + Name));
                    problem = true;                                     //no puedo anadirla porque ya existe
                }
                else if (scope.Funcs.Any(s => s.Key.Equals(this.Name))) //pregunto por las funciones
                {
                    errors.Add(new Error(line, column, "Ya existe una funcion con el nombre: " + Name));
                    problem = true; //no puedo anadirla porque ya existe
                }
            }

            TypeReturn typeOfAsign = Asig.CheckSemantics(scope_list, errors);

            if (!(typeOfAsign is ReturnInt))
            {
                errors.Add(new Error(line, column, "La expresion de asignacion debe retonar un entero"));
                problem = true; //no puedo anadirla porque la variable no es un entero
            }

            TypeReturn typeOfTo = To.CheckSemantics(scope_list, errors);

            if (!(typeOfTo is ReturnInt))
            {
                errors.Add(new Error(line, column, "La expresion del To debe retornar un entero"));
            }

            if (!problem) //si no preguntara esto podria estar anadiendo una variable con problemas al Scope (en el Scope no hay nada con errores!)
            {
                varFor = new Var_Scope(Name, typeOfAsign, true);
                Dictionary <string, Var_Scope> param = new Dictionary <string, Var_Scope>();
                param.Add(Name, varFor);
                Scope scopeBodyFor = new Scope(param, new Dictionary <string, TypeReturn>(), new Dictionary <string, Fun_Scope>()); //el scope para la variable del for

                scope_list.Add(scopeBodyFor);                                                                                       //agrego la variable del for a la lista de scope para que el body del for pueda verla

                //if(Body!=null)
                TypeReturn typeOfBody = Body.CheckSemantics(scope_list, errors);
                if (!(typeOfBody is ReturnNotValue))
                {
                    errors.Add(new Error(line, column, "La expresion del body del for no debe devolver nada"));
                }
                scope_list.Remove(scopeBodyFor); //remuevo la variable del for
            }

            countOfClicles--;
            return(new ReturnNotValue());
        }
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            int cant = errors.Count;//me da la cant de errores que hay hasta el momento

            TypeReturn typeOfAsign = Asig.CheckSemantics(scope_list, errors);
            TypeReturn typeVar;

            if (typeOfAsign == null) //cuando no existe la asignación
            {
                return(new ReturnNotValue());
            }

            if (VarType == null)                                                   //no tiene tipo la variable
            {
                if ((typeOfAsign is ReturnNil) || (typeOfAsign is ReturnNotValue)) //si es nil o no retorna valor no se puede inferir el tipo
                {
                    errors.Add(new Error(line, column, "No se puede inferir el tipo"));
                    return(new ReturnNotValue());
                }
                //Var_type = typeOfAsign.ToString(); //se infiere el tipo
                typeVar = typeOfAsign;
            }

            //tiene tipo la variable (VarType!=null)
            else
            {
                typeVar = Utils.FindType(scope_list, VarType); //busco el tipo de la variable
                if (typeVar == null)
                {
                    errors.Add(new Error(line, column, "El tipo de la variable '" + Name + "' no existe"));
                    //añado el error
                    return(null);
                }
                // el tipo de la variable existe
                if (typeOfAsign is ReturnNil) //pregunto si la asignacion es nil y el Lvalue permite nil
                {
                    if (typeVar is ReturnInt)
                    {
                        errors.Add(new Error(line, column,
                                             "No se le puede asignar un '" + typeOfAsign.ToString() + "' a un '" +
                                             typeVar + "'")); //añado el error
                    }
                }
                else if (!typeVar.Equals(typeOfAsign))
                {
                    errors.Add(new Error(line, column,
                                         "No se le puede asignar un '" + typeOfAsign.ToString() + "' a un '" +
                                         typeVar + "'")); //añado el error
                }
            }

            if (scope_list[scope_list.Count - 1].Vars.ContainsKey(Name) || scope_list[scope_list.Count - 1].Funcs.ContainsKey(Name)) //ver si hay una funcion o una variable con ese nombre
            {
                errors.Add(new Error(line, column, "El nombre de la variable '" + Name + "' ya esta en uso"));                       //añado el error
            }
            if (cant == errors.Count)                                                                                                //si no hubo errores
            {
                v = new Var_Scope(Name, typeVar);
                scope_list[scope_list.Count - 1].Vars.Add(Name, v); //añado la variable al scope
            }
            return(new ReturnNotValue());
        }