public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            TypeReturn typeOfAsign = Asign.CheckSemantics(scope_list, errors); //hago el chequeo semantico de la asignacion

            if (typeOfAsign is ReturnNotValue)                                 //verifico que devuelva algun valor
            {
                errors.Add(new Error(line, column, "La parte derecha de la asignacion debe devolver algun valor"));
            }

            TypeReturn typeOfLvalue = LValue.CheckSemantics(scope_list, errors); //hago el chequeo semantico del Lvalue

            if (LValue is VariableNode && Utils.NoAsignVar(scope_list, ((VariableNode)LValue).Name))
            {
                errors.Add(new Error(line, column,
                                     "No se le puede asignar ningún valor a la variable '" +
                                     ((VariableNode)LValue).Name + "'"));
            }

            if (typeOfAsign is ReturnNil)      //pregunto si la parte derecha es nil
            {
                if (typeOfLvalue is ReturnInt) //un entero no permite nil (todos los demas tipos si)
                {
                    errors.Add(new Error(line, column,
                                         "No se le puede asignar un '" + typeOfAsign + "' a un '" + typeOfLvalue + "'"));
                }
            }
            else if (typeOfLvalue != null && typeOfAsign != null &&           //pregunto si no hubo problema con el chequeo de las variables
                     !typeOfLvalue.ToString().Equals(typeOfAsign.ToString())) //chequeo que los tipos sean iguales
            {
                errors.Add(new Error(line, column,
                                     "No se le puede asignar un '" + typeOfAsign + "' a un '" + typeOfLvalue + "'"));
            }

            return(new ReturnNotValue()); //la asignacion no devuelve valor
        }
Beispiel #2
0
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            TypeReturn t = Left.CheckSemantics(scope_list, errors);

            if (!(t is ReturnInt || t is ReturnString || t is ReturnNil))//Mira si la parte izquierda es valida(solo pueden ser entera o string)
            {
                errors.Add(new Error(line, column, "La expresión izquierda de la operación relacional debe ser 'int' o 'string'"));
            }

            TypeReturn t1 = Right.CheckSemantics(scope_list, errors);

            if (!(t1 is ReturnInt || t1 is ReturnString || t1 is ReturnNil))//Mira si la parte derecha es valida(solo pueden ser entera o string)
            {
                errors.Add(new Error(line, column, "La expresión derecha de la operación relacional debe ser 'int' o 'string'"));
            }

            if (t1 == null || t == null || t1.ToString() != t.ToString())
            {
                if ((t is ReturnInt && t1 is ReturnNil) || (t is ReturnNil && t1 is ReturnInt) || (t is ReturnNil && t1 is ReturnNil))
                {
                    errors.Add(new Error(line, column, "Las expresiones comparadas son invalidas"));
                }
                else
                if (!(t is ReturnNil) && !(t1 is ReturnNil))
                {
                    errors.Add(new Error(line, column, "Ambas expresiones deben ser de tipo 'int' o de tipo 'string'"));
                }
            }
            return(new ReturnInt());
        }
Beispiel #3
0
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            Scope s = new Scope();

            foreach (var p in types)
            {
                s.Vars.Add(p.Item1, p.Item2);
            }
            scope_list.Add(s);

            TypeReturn r = Body.CheckSemantics(scope_list, errors);

            if (r != null && r is ReturnNil)//ver si el valor de retorno es distinto a lo que deberia devolver
            {
                if (Retu == "int")
                {
                    errors.Add(new Error(line, column, "No coincide el tipo de retorno con el que debería retornar"));
                }
            }
            else if (r != null && r.ToString() != Retu)
            {
                errors.Add(new Error(line, column, "No coincide el tipo de retorno con el que debería retornar"));
            }

            scope_list.RemoveAt(scope_list.Count - 1);

            return(new ReturnNotValue());
        }
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            Scope s = new Scope();

            foreach (var p in types)
            {
                s.Vars.Add(p.Item1, p.Item2);
            }
            scope_list.Add(s);

            TypeReturn typeOfBody = Body.CheckSemantics(scope_list, errors);

            if (typeOfBody == null) //pregunto si hubo problemas con el body del procedimiento
            {
                return(null);
            }
            if (typeOfBody.ToString() != "No valor")//ver que no retorna valor
            {
                errors.Add(new Error(line, column, "El procedimiento '" + Name + "' no debe retornar valor"));
            }

            scope_list.RemoveAt(scope_list.Count - 1);

            return(new ReturnNotValue());
        }
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            //chequeamos si el tipo del array ya se definio anteriormente
            TypeReturn typeOfArray = Utils.FindType(scope_list, Name);

            if (typeOfArray == null)
            {
                errors.Add(new Error(line, column, "El tipo " + this.Name + "no se ha delcarado todavia"));
            }

            //verificamos que la expresion de inicializacion devuelva algun valor(puede ser nil)
            TypeReturn typeOfInitial = Initial.CheckSemantics(scope_list, errors);

            if (typeOfInitial is ReturnNotValue || typeOfInitial == null) //pregunto por null porque si hubo un error devuelvo null
            {
                errors.Add(new Error(line, column, "La expresion de la inicializacion del array debe devolver algun valor"));
            }

            if (!(typeOfArray is ReturnArray)) //el tipo no es un array
            {
                errors.Add(new Error(line, column, "El tipo " + "'" + this.Name + "'" + " no es de tipo array"));
            }

            else
            {
                if (typeOfInitial is ReturnNil) //si es nil no pueden ser int los valores del array
                {
                    if ((typeOfArray as ReturnArray).Type_Of_Elements is ReturnInt)
                    {
                        errors.Add(new Error(line, column, "El array no permite 'nil' porque los valores del array son 'int'"));
                    }
                }
                else if (((ReturnArray)typeOfArray).Type_Of_Elements.ToString() != typeOfInitial.ToString())
                {
                    errors.Add(new Error(line, column, "Los elementos del array son de tipo '" + ((ReturnArray)typeOfArray).Type_Of_Elements.ToString() + "' y no de tipo '" + typeOfInitial.ToString() + "'"));
                }
            }

            //verificamos que el size es un entero
            TypeReturn typeOfSize = Size.CheckSemantics(scope_list, errors);

            if (!(typeOfSize is ReturnInt))
            {
                errors.Add(new Error(line, column, "La expresion del tamaño del array no devuelve un entero"));
            }
            Array = typeOfArray as ReturnArray;                                                      //para usarlo en la generacion de codigo
            return((typeOfArray != null) ? typeOfArray : new ReturnArray(this.Name, typeOfInitial)); //retorno el array
        }
Beispiel #6
0
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            TypeReturn typeOfFun = Utils.FindFunction(scope_list, Name, out fun, ref NumLevelUp); //chequear que la funcion este definida en el scope

            if (typeOfFun == null)
            {
                errors.Add(new Error(line, column, "La funcion '" + Name + "' no esta declarada en este ambito"));
                return(null); //no se encontro la funcion en el scope
            }

            //para no irme de rango en el for y no tener que estar preguntando cual es menor o mayor
            int min = Math.Min(Param.Count, fun.Param.Count); //me quedo con el minimo de la cantidad de parametros entre la functioncall y la declarada

            //voy comparando los parametros y viendo que devuelvan lo mismo
            for (int i = 0; i < min; i++)
            {
                TypeReturn type = Param[i].CheckSemantics(scope_list, errors); //le hago el chequeo semantico a cada parametro (tienen que devolver algun valor)
                if (type == null)
                {
                    continue;
                }

                if (type is ReturnNil)
                {
                    if (fun.Param[i].Item2 is ReturnInt)
                    {
                        errors.Add(new Error(line, column, "No se le puede asignar un '" + type + "' a un '" + fun.Param[i].Item2 + "'")); //añado el error
                    }
                }
                else if (!type.ToString().Equals(fun.Param[i].Item2.ToString())) //pregunto si el parametro i-esimo de la functioncall es del mismo tipo que del declarado
                {
                    errors.Add(new Error(line, column, "El parametro '" + fun.Param[i].Item1 + "' no es de tipo '" + fun.Param[i].Item2 + "'"));
                }

                if (type is ReturnNotValue) //pregunto si el i-esimo parametro devuelve algun valor (tienen que hacerlo)
                {
                    errors.Add(new Error(line, column, "La expresion del parametro " + i + "-esimo no devuelve valor"));
                }
            }

            if (fun.Param.Count != Param.Count) //para saber si tienen la misma cantidad de parametros la funcioncall que la declarada
            {
                errors.Add(new Error(line, column, "La funcion '" + Name + "' no tiene " + Param.Count + " parametros"));
            }

            return(typeOfFun); //es null si la funcion no se encontro en el Scope
        }
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            this.CheckCondition(scope_list, errors); //chequea que la expresion de la condicion sea un entero

            //hago el chequeo semantico del then y del else
            TypeReturn typeOfBody     = Body.CheckSemantics(scope_list, errors);
            TypeReturn typeOfBodyElse = Body_else.CheckSemantics(scope_list, errors);

            if (typeOfBody == null || typeOfBodyElse == null) //pregunto si hubo problemas en el then y en el else
            {
                return(null);
            }
            //chequeamos que los tipos devueltos por el then y el else sean iguales (puede ser nil uno de las exp mientras la otra no sea int)
            if (typeOfBody is ReturnNil)
            {
                if (typeOfBodyElse is ReturnInt)
                {
                    errors.Add(new Error(line, column, "Los tipos retornados por las expresiones del then y del else tienen que ser iguales"));
                }
                else
                {
                    return(typeOfBodyElse);
                }
            }
            else
            {
                if (typeOfBodyElse is ReturnNil)
                {
                    if (typeOfBody is ReturnInt)
                    {
                        errors.Add(new Error(line, column, "Los tipos retornados por las expresiones del then y del else tienen que ser iguales"));
                    }
                    else
                    {
                        return(typeOfBody);
                    }
                }

                else if (!typeOfBody.ToString().Equals(typeOfBodyElse.ToString())) //el tipo del then y el del else tienen que ser iguales
                {
                    errors.Add(new Error(line, column, "Los tipos retornados por las expresiones del then y del else tienen que ser iguales"));
                }
            }
            //tanto la exp del then como la del else retornan el mismo tipo => retorno el tipo de cualquiera de las dos
            return(typeOfBody); //VER AQUI CUANDO LOS TIPOS SEAN != SI DEVUELVO NULL
        }
Beispiel #8
0
        protected TypeReturn CheckSemanticsForEqualAndDistinct(List <Scope> scope_list, List <Error> errors)
        {
            TypeReturn tLeft  = Left.CheckSemantics(scope_list, errors);
            TypeReturn tRight = Right.CheckSemantics(scope_list, errors);

            if (tLeft == null || tRight == null) //si alguna de las dos variables tuvo problemas no se hace la comparacion
            {
                return(new ReturnInt());
            }

            if (tLeft is ReturnNotValue || tRight is ReturnNotValue)
            {
                errors.Add(new Error(line, column, "De las expresiones comparadas hay al menos una que no tiene valor"));
            }

            if (tLeft is ReturnInt && !(tRight is ReturnInt))
            {
                errors.Add(new Error(line, column, "Las expresiones comparadas no son del mismo tipo,no se puede comparar una expresion del Tipo 'int' con una del tipo '" + tRight.ToString() + "'"));
            }

            if (tLeft is ReturnString && !(tRight is ReturnString || tRight is ReturnNil))
            {
                errors.Add(new Error(line, column, "Las expresiones comparadas no son del mismo tipo,no se puede comparar una expresion del Tipo 'string' con una del tipo '" + tRight.ToString() + "'"));
            }

            if (tLeft is ReturnArray && !(tRight is ReturnNil || tLeft.Equals(tRight)))
            {
                errors.Add(new Error(line, column, "Las expresiones comparadas no son del mismo tipo,no se puede comparar una expresion del Tipo '" + tLeft.ToString() + "' con una del tipo '" + tRight.ToString() + "'"));
            }

            if (tLeft is ReturnRecord && !(tRight is ReturnNil || tLeft.Equals(tRight)))
            {
                errors.Add(new Error(line, column, "Las expresiones comparadas no son del mismo tipo,no se puede comparar una expresion del Tipo '" + tLeft.ToString() + "' con una del tipo '" + tRight.ToString() + "'"));
            }

            if (tLeft is ReturnNil && ((tRight is ReturnInt) || (tRight is ReturnNil)))
            {
                errors.Add(new Error(line, column, "Las expresiones comparadas no son del mismo tipo,no se puede comparar una expresion del Tipo Nil con una del tipo " + tRight.ToString() + "'"));
            }

            return(new ReturnInt());
        }
        public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors)
        {
            ReturnRecord recordDeclared = null;
            //chequear si el tipo del record ya existe en el scope
            KeyValuePair <string, TypeReturn> pair = default(KeyValuePair <string, TypeReturn>);

            for (int i = 0; i < scope_list.Count; i++)
            {
                Scope scope = scope_list[i];
                pair = scope.Types.FirstOrDefault(s => s.Key.Equals(this.Name)); //busco el tipo (nombre) del record en el scope

                if (!pair.Equals(default(KeyValuePair <string, TypeReturn>)))    //pregunto si existe el nombre del tipo en este ambito
                {
                    //chequeo si el tipo es un record
                    if (pair.Value is ReturnRecord)
                    {
                        recordDeclared = pair.Value as ReturnRecord;
                    }
                    else
                    {
                        errors.Add(new Error(line, column, "El tipo '" + Name + "' no es de tipo record"));
                    }
                    break;
                }
            }

            if (pair.Equals(default(KeyValuePair <string, TypeReturn>))) //pregunto si se encontro el el tipo del record en el scope
            {
                errors.Add(new Error(line, column, "El tipo '" + Name + "' no existe en este ambito"));
                return(null); //el record no esta declarado en este scope
            }

            //el menor de la cantidad de campos entre el instanciado y el declarado para no irme de rango en el for
            int min = Math.Min(recordDeclared.Fields.Count, Dict.Count);

            //chequear que concuerden los nombres de los campos y sus tipos de retorno (entre el record declarado y el instanciado)
            for (int i = 0; i < min; i++) //por cada campo
            {
                //chequeo que los nombres sean los mismos
                string keyRecordInstanced = Dict.ElementAt(i).Item1;                  //cojo el nombre del campo i-esimo del record instanciado
                string keyRecordDeclared  = recordDeclared.Fields.ElementAt(i).Item1; //el nombre del campo i-esimo del record declarado
                if (!keyRecordInstanced.Equals(keyRecordDeclared))                    //pregunto si los nombres de los campos son distintos
                {
                    errors.Add(new Error(line, column, "El " + i + "-esimo campo no se llama " + keyRecordDeclared + " sino " + keyRecordInstanced));
                }

                //chequeo que los tipos de los campos sean los mismos
                TypeReturn typeOfParameterDeclared = recordDeclared.Fields.ElementAt(i).Item2; //el tipo del campo i-esimo del record declarado
                if (typeOfParameterDeclared == null)                                           //si es null es porque no se encontro el tipo en este ambito
                {
                    errors.Add(new Error(line, column, "El tipo '" + recordDeclared.Fields.ElementAt(i).Item2 + "' no se encuentra declarado en este ambito"));
                }


                TypeReturn typeOfParameterInstanced = Dict.ElementAt(i).Item2.CheckSemantics(scope_list, errors); //el tipo del campo i-esimo cuando se instancio el record

                if (typeOfParameterInstanced is ReturnNil)                                                        //chequeo si el campo del record instanciado es nil
                {
                    //hay que chequear que el tipo del parametro no sea ni int ni string
                    if (typeOfParameterDeclared is ReturnInt)
                    {
                        errors.Add(new Error(line, column, "Solo se puede asignar nil a un tipo record, array o string"));
                    }
                }
                //pregunto si los TypeReturn de los campos son != de null para que no me de NullException al pedirle el GetType()
                else if (typeOfParameterDeclared != null && typeOfParameterInstanced != null && !typeOfParameterDeclared.GetType().Equals(typeOfParameterInstanced.GetType()))  //pregunto si los tipos de retorno son iguales
                {
                    errors.Add(new Error(line, column, "El record '" + recordDeclared.Record_name + "'. El tipo del campo '" + keyRecordDeclared + "' es '" + typeOfParameterDeclared.ToString() + "' y no '" + typeOfParameterInstanced.ToString() + "'"));
                }
            }

            if (Dict.Count != recordDeclared.Fields.Count) //para saber si los records tienen la misma cantidad de campos
            {
                errors.Add(new Error(line, column, "El record '" + Name + "' no tiene " + Dict.Count + " campos"));
            }

            record = recordDeclared;
            return(recordDeclared); //retorno el mismo record que estaba en el scope
        }
        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());
        }