public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.IfNode.CheckSemantics(scope, errors);
            this.ThenNode.CheckSemantics(scope, errors);
            this.ElseNode.CheckSemantics(scope, errors);

            //--------------------------------------------------
            // Poner El Valor De Retorno De La Expresión A 'Error'
            // Por Default.
            //--------------------------------------------------
            this.ExpressionType = PredefinedTypes.ErrorType;

            //--------------------------------------------------
            // Si Ha Ocurrido Un Error En Alguno De Los Hijos,
            // Parar De Reportar Errores.
            //--------------------------------------------------
            if (this.IfNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.ThenNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.ElseNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // La Condición Debe Ser De Tipo <int>.
            //--------------------------------------------------
            if (this.IfNode.ExpressionType != PredefinedTypes.IntType)
            {
                errors.Add(SemanticError.InvalidTypeConvertion(PredefinedTypes.IntType, this.IfNode.ExpressionType, this.IfNode));
            }
            else
            {
                //--------------------------------------------------
                // Debe Haber Conversión Entre El Tipo Del 'Then' Y
                // Del 'Else'.
                //--------------------------------------------------
                if (SemanticError.CompatibleTypes(this.ThenNode.ExpressionType, this.ElseNode.ExpressionType))
                {
                    this.ExpressionType = this.ThenNode.ExpressionType;
                }
                else if (SemanticError.CompatibleTypes(this.ElseNode.ExpressionType, this.ThenNode.ExpressionType))
                {
                    this.ExpressionType = this.ElseNode.ExpressionType;
                }
                else
                {
                    errors.Add(SemanticError.IncompatibleTypesInIfThenElse(this));
                }
            }
        }
Beispiel #2
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.IfNode.CheckSemantics(scope, errors);
            this.ThenNode.CheckSemantics(scope, errors);

            //--------------------------------------------------
            // Poner El Valor De Retorno De La Expresión A 'Error'
            // Por Default.
            //--------------------------------------------------
            this.ExpressionType = PredefinedTypes.ErrorType;

            //--------------------------------------------------
            // Si Ha Ocurrido Un Error En Alguno De Los Hijos,
            // Parar De Reportar Errores.
            //--------------------------------------------------
            if (this.IfNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.ThenNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // La Condición Debe Ser De Tipo <int>.
            //--------------------------------------------------
            if (this.IfNode.ExpressionType != PredefinedTypes.IntType)
            {
                errors.Add(SemanticError.InvalidTypeConvertion(PredefinedTypes.IntType,
                                                               this.IfNode.ExpressionType, this.IfNode
                                                               ));
                return;
            }

            //--------------------------------------------------
            // El Cuerpo Del IfThen No Puede Devolver.
            //--------------------------------------------------
            if (this.ThenNode.ExpressionType != PredefinedTypes.VoidType)
            {
                errors.Add(SemanticError.ExpectedType(PredefinedTypes.VoidType,
                                                      this.ThenNode.ExpressionType, this.ThenNode
                                                      ));
            }
            else
            {
                this.ExpressionType = PredefinedTypes.VoidType;
            }
        }
Beispiel #3
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Por Default, El Nodo No Tiene Errores.
            //--------------------------------------------------
            this.IsOk = true;

            //--------------------------------------------------
            // Hacer  'CheckSemantics'  A  Cada  Función.
            //--------------------------------------------------
            foreach (var declaration in this.Declarations)
            {
                declaration.CheckSemantics(scope, errors);
                this.IsOk &= declaration.IsOk;
            }

            if (!this.IsOk)
            {
                return;
            }

            //--------------------------------------------------
            // Hacer 'CheckSemantics' Al Cuerpo De Las Funciones.
            // Esto Es Una Segunda Pasada.
            //--------------------------------------------------
            foreach (var declaration in this.Declarations)
            {
                Scope InnerScope = scope.CreateChildScope();
                foreach (var parameter in declaration.FunctionInfo.Parameters)
                {
                    InnerScope.Add(parameter);
                }

                //--------------------------------------------------
                // Mantener La Referencia Del Scope Definido En
                // El Function Info.
                //--------------------------------------------------
                declaration.FunctionInfo.Scope = InnerScope;

                declaration.Body.CheckSemantics(InnerScope, errors);

                //--------------------------------------------------
                // Parar De Reportar Errores Si El Cuerpo De La Función
                // Tiene Error.
                //--------------------------------------------------
                if (declaration.Body.ExpressionType == PredefinedTypes.ErrorType)
                {
                    declaration.IsOk = false;
                }

                this.IsOk &= declaration.IsOk;

                if (!declaration.IsOk)
                {
                    continue;
                }

                //--------------------------------------------------
                // Comprobar  Que  El  Tipo  De  Retorno De La Función
                // Sea Igual Al Del Cuerpo De La Misma. Comprobar Tres
                // Casos:
                // 1 - La Función No Devuelve & El Cuerpo Devuelve
                // 2 - La Función Devuelve & El Cuerpo No Devuelve
                // 3 - La Función Y El Cuerpo Devuelven Pero Tipos Incompatibles.
                //   - Tener En Cuenta El Caso <object_type> = <nil>
                //--------------------------------------------------
                if (declaration.FunctionInfo.ReturnType == PredefinedTypes.VoidType)
                {
                    //--------------------------------------------------
                    // La Función Es Un Procedimiento ( No Devuelve )...
                    //--------------------------------------------------
                    if (declaration.Body.ExpressionType != PredefinedTypes.VoidType)
                    {
                        errors.Add(SemanticError.ProcedureCannotReturn(declaration.ID.Name, declaration));
                        declaration.IsOk = false;
                    }
                }
                else
                {
                    //--------------------------------------------------
                    // La Función Devuelve ...
                    //--------------------------------------------------
                    if (declaration.Body.ExpressionType == PredefinedTypes.VoidType)
                    {
                        errors.Add(SemanticError.FunctionMustReturn(declaration.ID.Name, declaration));
                        declaration.IsOk = false;
                    }
                    else
                    {
                        if (declaration.Body.ExpressionType == PredefinedTypes.NilType)
                        {
                            if (declaration.FunctionInfo.ReturnType == PredefinedTypes.IntType)
                            {
                                errors.Add(SemanticError.InvalidIntNilAssignation(declaration));
                                declaration.IsOk = false;
                            }
                        }
                        else if (declaration.Body.ExpressionType != declaration.FunctionInfo.ReturnType)
                        {
                            errors.Add(SemanticError.InvalidTypeConvertion(declaration.FunctionInfo.ReturnType, declaration.Body.ExpressionType, declaration));
                            declaration.IsOk = false;
                        }
                    }
                }

                this.IsOk &= declaration.IsOk;
            }
        }
Beispiel #4
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Buscar El FunctionInfo Correspondiente.
            //--------------------------------------------------
            this.FunctionInfo = scope.FindFunctionInfo(ID.Name);

            //--------------------------------------------------
            // Poner Por Defecto Que Hay Errores.
            //--------------------------------------------------
            this.ExpressionType = PredefinedTypes.ErrorType;

            //--------------------------------------------------
            // Si La Función No Existe, Reportar Error.
            //--------------------------------------------------
            if (this.FunctionInfo == null)
            {
                errors.Add(SemanticError.FunctionDoesNotExist(this.ID.Name, this));
                return;
            }

            //--------------------------------------------------
            // Si La Cantidad De Argumentos Es Diferente A La
            // Cantidad De Parámetros, Reportar Error.
            //--------------------------------------------------
            var parameters = this.FunctionInfo.Parameters;

            if (this.Arguments.Count() != parameters.Length)
            {
                errors.Add(SemanticError.WrongParameterNumber(this.ID.Name, parameters.Length, this.Arguments.Count(), this));
                return;
            }

            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Cada Argumento.
            //--------------------------------------------------
            bool IsOk = true;

            foreach (var argument in this.Arguments)
            {
                argument.CheckSemantics(scope, errors);
                if (argument.ExpressionType == PredefinedTypes.ErrorType)
                {
                    IsOk = false;
                }
            }

            //--------------------------------------------------
            // Si Hay Errores En Los Argumentos, Parar De
            // Reportar Errores.
            //--------------------------------------------------
            if (!IsOk)
            {
                return;
            }

            //--------------------------------------------------
            // Comprobar Que Los Tipos De Los Argumentos Son Iguales
            // A Los Tipos De Los Parámetros Correspondientes.
            //--------------------------------------------------
            for (int i = 0; i < parameters.Length; i++)
            {
                var arg = this.Arguments.ElementAt(i);
                if (!SemanticError.CompatibleTypes(parameters[i].TypeNode, arg.ExpressionType))
                {
                    errors.Add(SemanticError.InvalidTypeConvertion(parameters[i].TypeNode, arg.ExpressionType, arg));
                    IsOk = false;
                }
            }

            if (IsOk)
            {
                this.ExpressionType = this.FunctionInfo.ReturnType;
            }
        }
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Por Default, El Nodo No Tiene Errores.
            //--------------------------------------------------
            this.IsOk = true;

            //--------------------------------------------------
            // Si Existe Una Función O Una Variable Con El Mismo
            // Nombre En El Scope Local, Reportar Error.
            //--------------------------------------------------
            if (scope.FindLocalFunctionInfo(this.ID.Name) != null || scope.FindLocalVariableInfo(this.ID.Name) != null)
            {
                errors.Add(SemanticError.PreviousVariableOrFunctionDeclaration(this.ID.Name, this));
                this.IsOk = false;
            }

            //--------------------------------------------------
            // Hacer 'CheckSemantics' Al Valor De La Variable.
            //--------------------------------------------------
            this.Expression.CheckSemantics(scope, errors);

            //--------------------------------------------------
            // Si El Valor De La Expresión Tiene Algún Error,
            // Parar De Reportar Errores.
            //--------------------------------------------------
            if (this.Expression.ExpressionType == PredefinedTypes.ErrorType)
            {
                this.IsOk = false;
            }

            if (!this.IsOk)
            {
                return;
            }

            if (this.ChildCount == 3)
            {
                //--------------------------------------------------
                // Si La Variable Tiene El Tipo Explícitamente Entonces
                // Es De La Siguiente Forma:
                //
                // var id : type-id := expr
                //--------------------------------------------------
                var typeID = this.Children[2] as IdNode;

                //--------------------------------------------------
                // Si El Tipo No Existe, Entonces Reportar El Error.
                //--------------------------------------------------
                var TI = scope.FindTypeInfo(typeID.Name);

                if (TI == null)
                {
                    errors.Add(SemanticError.TypeDoesNotExist(typeID.Name, this));
                    this.IsOk = false;
                    return;
                }

                if (this.Expression.ExpressionType == PredefinedTypes.NilType)
                {
                    //--------------------------------------------------
                    // Si El Valor De La Expresión Es <nil>, Entonces  El
                    // Tipo De La Variable, Escrito Explícitamente; Puede
                    // Ser Cualquiera, Excepto 'int'.
                    //
                    // var id : type-id := nil
                    //--------------------------------------------------
                    if (TI.TypeNode == PredefinedTypes.IntType)
                    {
                        errors.Add(SemanticError.InvalidIntNilAssignation(this));
                        this.IsOk = false;
                        return;
                    }
                }
                else if (TI.TypeNode != this.Expression.ExpressionType)
                {
                    //--------------------------------------------------
                    // Si Los Tipos Son Diferentes, Reportar Error.
                    //--------------------------------------------------
                    this.IsOk = false;
                    errors.Add(SemanticError.InvalidTypeConvertion(TI.TypeNode, this.Expression.ExpressionType, this));
                    return;
                }

                //--------------------------------------------------
                // Crear 'VariableInfo'.
                //--------------------------------------------------
                this.VariableInfo = new VariableInfo(this.ID.Name, TI.TypeNode);
            }
            else
            {
                //--------------------------------------------------
                // En Este Caso Se Omite El Tipo De La Variable, Por
                // Tanto Se Debe Inferir De La Parte Derecha. Se Debe
                // Comprobar Que La Parte Derecha No Sea <nil> o <void>.
                //
                // var id := expr
                //--------------------------------------------------
                if (this.Expression.ExpressionType == PredefinedTypes.NilType ||
                    this.Expression.ExpressionType == PredefinedTypes.VoidType)
                {
                    errors.Add(SemanticError.InvalidTypeInference(this.Expression.ExpressionType, this));
                    this.IsOk = false;
                    return;
                }

                //--------------------------------------------------
                // Crear 'VariableInfo'.
                //--------------------------------------------------
                this.VariableInfo = new VariableInfo(this.ID.Name, this.Expression.ExpressionType);
            }

            //--------------------------------------------------
            // Actualizar 'Scope' Con La Variable Actual.
            //--------------------------------------------------
            scope.Add(this.VariableInfo);
        }