Exemplo n.º 1
0
        public override void VisitIdentifierName(IdentifierNameSyntax identifierName, BindingScope bindingScope)
        {
            if (!bindingScope.Lookup(identifierName.Name, out var binding))
            {
                return;
            }
            var shadowedBy = binding.WasShadowedBy.LastOrDefault();

            if (shadowedBy == null)
            {
                return;
            }
            diagnostics.Add(SemanticError.CantShadow(function.File, shadowedBy.NameSpan, identifierName.Span));
            function.Poison();
        }
Exemplo n.º 2
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Dos Hijos.
            //--------------------------------------------------
            this.LeftOperandNode.CheckSemantics(scope, errors);
            this.RightOperandNode.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.LeftOperandNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.RightOperandNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // Comprobar Que Ambas Expresiones Devuelvan 'int'.
            //--------------------------------------------------
            bool IsOk = true;

            if (this.LeftOperandNode.ExpressionType != PredefinedTypes.IntType)
            {
                IsOk = false;
                errors.Add(SemanticError.InvalidUseOfBinaryArithmeticOperator(
                               this.OperatorName, "left", this.LeftOperandNode));
            }

            if (this.RightOperandNode.ExpressionType != PredefinedTypes.IntType)
            {
                IsOk = false;
                errors.Add(SemanticError.InvalidUseOfBinaryArithmeticOperator(
                               this.OperatorName, "right", this.RightOperandNode));
            }

            if (IsOk)
            {
                this.ExpressionType = PredefinedTypes.IntType;
            }
        }
Exemplo n.º 3
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            LeftOperand.CheckSemantics(scope, errors);
            RightOperand.CheckSemantics(scope, errors);

            if (errors.Any())
            {
                return;
            }

            if (!SupportType(LeftOperand.Type))
            {
                errors.Add(SemanticError.InvalidUseOfOperator("binary relational", "valid", "left", LeftOperand));
            }

            if (!SupportType(RightOperand.Type))
            {
                errors.Add(SemanticError.InvalidUseOfOperator("binary relational", "valid", "right", RightOperand));
            }

            if (RightOperand.Type != LeftOperand.Type)
            {
                errors.Add(new SemanticError
                {
                    Message = "Types of left and right operands of the binary relational operator do not match",
                    Node    = this
                });
            }

            if (LeftOperand.Type.Equals(Types.Nil) && RightOperand.Type.Equals(Types.Nil))
            {
                errors.Add(new SemanticError
                {
                    Message = $"Types of left and right operands of the binary relational operator can't be both '{Types.Nil}'",
                    Node    = this
                });
            }

            if (LeftOperand is ComparisonNode || RightOperand is ComparisonNode)
            {
                errors.Add(new SemanticError
                {
                    Message = "Comparison operators do not associate",
                    Node    = this
                });
            }
        }
Exemplo n.º 4
0
 public override void VisitVariableDeclarationStatement(VariableDeclarationStatementSyntax variableDeclaration, BindingScope bindingScope)
 {
     base.VisitVariableDeclarationStatement(variableDeclaration, bindingScope);
     if (bindingScope.Lookup(variableDeclaration.Name, out var binding))
     {
         if (binding.MutableBinding)
         {
             diagnostics.Add(SemanticError.CantRebindMutableBinding(function.File, variableDeclaration.NameSpan));
             function.Poison();
         }
         else if (variableDeclaration.MutableBinding)
         {
             diagnostics.Add(SemanticError.CantRebindAsMutableBinding(function.File, variableDeclaration.NameSpan));
             function.Poison();
         }
     }
 }
Exemplo n.º 5
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            LeftOperand.CheckSemantics(scope, errors);
            RightOperand.CheckSemantics(scope, errors);

            if (LeftOperand.Type != Type)
            {
                errors.Add(SemanticError.InvalidUseOfOperator(
                               "binary logical", LeftOperand.Type.Equals(Types.Nil) ? "valued" : "integer", "left", LeftOperand));
            }

            if (RightOperand.Type != Type)
            {
                errors.Add(SemanticError.InvalidUseOfOperator(
                               "binary logical", RightOperand.Type.Equals(Types.Nil) ? "valued" : "integer", "right", RightOperand));
            }
        }
Exemplo n.º 6
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Dos Hijos.
            //--------------------------------------------------
            this.LeftOperandNode.CheckSemantics(scope, errors);
            this.RightOperandNode.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.LeftOperandNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.RightOperandNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // Solamente Se Pueden Comprar Enteros Y Cadenas.
            //--------------------------------------------------
            if (this.LeftOperandNode.ExpressionType != this.RightOperandNode.ExpressionType)
            {
                errors.Add(SemanticError.InvalidCompareOperation(this.LeftOperandNode.ExpressionType,
                                                                 this.RightOperandNode.ExpressionType, this));
            }
            else
            {
                if (this.LeftOperandNode.ExpressionType != PredefinedTypes.IntType &&
                    this.LeftOperandNode.ExpressionType != PredefinedTypes.StrType)
                {
                    errors.Add(SemanticError.InvalidCompareOperation(this.LeftOperandNode.ExpressionType,
                                                                     this.RightOperandNode.ExpressionType, this));
                }
                else
                {
                    this.ExpressionType = PredefinedTypes.IntType;
                }
            }
        }
Exemplo n.º 7
0
        public override void CheckSemantics(Semantics.Scope scope, List <Semantics.SemanticError> errors)
        {
            //--------------------------------------------------
            // Poner Por Defecto Que Hay Errores.
            //--------------------------------------------------
            this.ExpressionType = PredefinedTypes.ErrorType;

            //--------------------------------------------------
            // Buscar El Primer Nodo Hacia La Raiz Que Acepte
            // Break.
            //--------------------------------------------------
            this.Owner = null;

            var pathToTheRoot = this.GetAncestors().Reverse();

            foreach (var u in pathToTheRoot)
            {
                if (u is IBreakableNode)
                {
                    this.Owner = u as IBreakableNode;
                    break;
                }
                if (u is FunctionDeclarationNode)
                {
                    break;
                }
                if (u is ExpressionsBlockNode)
                {
                    (u as ExpressionsBlockNode).ContainsBreakNodes = true;
                }
            }

            //--------------------------------------------------
            // Comprobar Si El Break Está Siendo Usado Fuera
            // De  Un  For,  While, O Bloque De Expresiones.
            //--------------------------------------------------
            if (this.Owner == null)
            {
                errors.Add(SemanticError.InvalidUseOfBreak(this));
            }
            else
            {
                this.ExpressionType = PredefinedTypes.VoidType;
            }
        }
        public VariableFlags Assignment(
            IAssignmentExpression assignmentExpression,
            VariableFlags definitelyUnassigned)
        {
            switch (assignmentExpression.LeftOperand)
            {
            case INameExpression identifier:
                var symbol = identifier.ReferencedSymbol;
                if (!symbol.IsMutableBinding && definitelyUnassigned[symbol] == false)
                {
                    diagnostics.Add(SemanticError.VariableMayAlreadyBeAssigned(file, identifier.Span, identifier.ReferencedSymbol.Name));
                }
                return(definitelyUnassigned.Set(symbol, false));

            case IFieldAccessExpression _:
                return(definitelyUnassigned);

            default:
                throw new NotImplementedException("Complex assignments not yet implemented");
            }
        }
Exemplo n.º 9
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.LeftVariable.CheckSemantics(scope, errors);
            this.Value.CheckSemantics(scope, errors);

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

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

            if (this.LeftVariable.ReadOnly)
            {
                errors.Add(SemanticError.InvalidUseOfAssignmentToAReadonlyVariable(this.LeftVariable));
                return;
            }

            if (!SemanticError.CompatibleTypes(this.LeftVariable.ExpressionType, this.Value.ExpressionType))
            {
                errors.Add(SemanticError.ExpectedType(this.LeftVariable.ExpressionType,
                                                      this.Value.ExpressionType, this));
            }
            else
            {
                this.ExpressionType = PredefinedTypes.VoidType;
            }
        }
Exemplo n.º 10
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // A 'IdNode' Se Le Hace 'CheckSemantics' Solamente
            // Cuando Es Usado Como 'AccessNode'.
            //--------------------------------------------------
            this.VariableInfo = scope.FindVariableInfo(this.Name);

            //--------------------------------------------------
            // Si No Existe Una Variable En El Scope Visible
            // Actual Que Corresponda Al Nombre Del 'ID' Actual,
            // Informamos Error.
            //--------------------------------------------------
            if (this.VariableInfo == null)
            {
                errors.Add(SemanticError.UndefinedVariableUsed(this.Name, this));
                this.ExpressionType = PredefinedTypes.ErrorType;
            }
            else
            {
                this.ExpressionType = this.VariableInfo.TypeNode;
                this.ReadOnly       = this.VariableInfo.ReadOnly;
            }
        }
Exemplo n.º 11
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Buscar En El Scope Actual El TypeInfo De TypeID.
            //--------------------------------------------------
            var TI = scope.FindTypeInfo(this.TypeID.Name);

            //--------------------------------------------------
            // Si El Tipo No Existe,  Entonces  Reportar El Error,
            // En Caso  Contrario,  Crear  Un  'VariableInfo' Para
            // El Campo Actual Con Nombre ID Y Tipo TI. Actualizar
            // IsOk En Cada Caso.
            //--------------------------------------------------
            if (TI == null)
            {
                errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID));
                this.IsOk = false;
            }
            else
            {
                this.VariableInfo = new VariableInfo(ID.Name, TI.TypeNode);
                this.IsOk         = true;
            }
        }
Exemplo n.º 12
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Poner El Valor De Retorno De La Expresión A 'Error'
            // Por Default.
            //--------------------------------------------------
            this.ExpressionType = PredefinedTypes.ErrorType;

            //--------------------------------------------------
            // Buscar Por El Tipo Del Record.
            //--------------------------------------------------
            var TI = scope.FindTypeInfo(this.TypeID.Name);

            //--------------------------------------------------
            // Si El Tipo No Está Definido, Reportar Error.
            //--------------------------------------------------
            if (TI == null)
            {
                errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID));
                return;
            }

            var RecordType = TI.TypeNode as RecordTypeNode;

            //--------------------------------------------------
            // Si El Tipo No Es Un Record.
            //--------------------------------------------------
            if (RecordType == null)
            {
                errors.Add(SemanticError.RecordTypeExpected(TI.TypeNode, this.TypeID));
                return;
            }

            //--------------------------------------------------
            // La Cantidad De Campos Debe Ser La Misma.
            //--------------------------------------------------
            if (this.Fields.Length != RecordType.Fields.Length)
            {
                errors.Add(SemanticError.WrongFieldNumberInRecord(RecordType.Name,
                                                                  RecordType.Fields.Length, this.Fields.Length, this));
                return;
            }

            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Campos Del Record.
            //--------------------------------------------------
            bool IsOk = true;

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

            if (!IsOk)
            {
                return;
            }

            //--------------------------------------------------
            // Comprobar El Orden De Los Campos Y Los Tipos.
            //--------------------------------------------------
            for (int i = 0; i < this.Fields.Length; i++)
            {
                if (this.Fields[i].ID.Name != RecordType.Fields[i].ID.Name)
                {
                    IsOk = false;
                    errors.Add(SemanticError.WrongFieldNameInRecord(
                                   this.Fields[i].ID.Name, RecordType.Fields[i].ID.Name, this.Fields[i]
                                   ));
                }
                if (!SemanticError.CompatibleTypes(RecordType.Fields[i].VariableInfo.TypeNode, this.Fields[i].ExpressionType))
                {
                    IsOk = false;
                    errors.Add(SemanticError.ExpectedType(
                                   RecordType.Fields[i].VariableInfo.TypeNode, this.Fields[i].ExpressionType, this.Fields[i]
                                   ));
                }
            }

            if (IsOk)
            {
                this.ExpressionType = RecordType;
            }
        }
Exemplo n.º 13
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;
            }
        }
Exemplo n.º 14
0
 public void ErrorSuppressComment(string format, params object[] args)
 {
     var err = new SemanticError(String.Format(format, args), item, readFrom.LineNumber, readFrom.LinePosition);
     engine.ReportError(err);
 }
Exemplo n.º 15
0
 public void ErrorSuppressComment(string message)
 {
     var err = new SemanticError(message, item, readFrom.LineNumber, readFrom.LinePosition);
     engine.ReportError(err);
 }
        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);
        }
Exemplo n.º 17
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.Size.CheckSemantics(scope, errors);
            this.Value.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.Size.ExpressionType == PredefinedTypes.ErrorType ||
                this.Value.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // Buscar Por El Tipo Del Array
            //--------------------------------------------------
            var TI = scope.FindTypeInfo(this.TypeID.Name);

            //--------------------------------------------------
            // Si El Tipo No Está Definido, Reportar Error.
            //--------------------------------------------------
            if (TI == null)
            {
                errors.Add(SemanticError.TypeDoesNotExist(this.TypeID.Name, this.TypeID));
                return;
            }

            var ArrayType = TI.TypeNode as ArrayTypeNode;

            //--------------------------------------------------
            // Si El Tipo No Es Un Array.
            //--------------------------------------------------
            if (ArrayType == null)
            {
                errors.Add(SemanticError.ArrayTypeExpected(TI.TypeNode, this.TypeID));
                return;
            }

            //--------------------------------------------------
            // 'Size' Debe Ser De Tipo <int>.
            //--------------------------------------------------
            if (this.Size.ExpressionType != PredefinedTypes.IntType)
            {
                errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType,
                                                      this.Size.ExpressionType, this.Size));
                return;
            }

            //--------------------------------------------------
            // 'Value' Debe Ser Del Mismo Tipo Que El Array.
            //--------------------------------------------------
            if (!SemanticError.CompatibleTypes(ArrayType.ArrayOf, this.Value.ExpressionType))
            {
                errors.Add(SemanticError.ExpectedType(ArrayType.ArrayOf,
                                                      this.Value.ExpressionType, this.Value));
                return;
            }

            this.ExpressionType = ArrayType;
        }
Exemplo n.º 18
0
 public DeclareAndInitializeGlobalVariable(SemanticError error)
 {
     Name  = Strings.DeclareAndInitializeGlobalVariable;
     Error = error;
 }
Exemplo n.º 19
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Por Default, El Nodo No Tiene Errores.
            //--------------------------------------------------
            this.IsOk = true;

            //--------------------------------------------------
            // Obtener Todos Los Nombres De Los Tipos En El
            // Bloque Actual.
            //--------------------------------------------------
            string[] names = this.Declarations.Select(x => x.ID.Name).ToArray <string>();

            //--------------------------------------------------
            // Comprobar Que Todos Los Nombres Se Declaren Solo
            // Una Vez.
            //--------------------------------------------------
            for (int i = 0; i < names.Length; i++)
            {
                bool hasPreviousDeclaration = (scope.FindLocalTypeInfo(names[i]) != null);
                for (int j = 0; j < i; j++)
                {
                    if (names[i] == names[j])
                    {
                        hasPreviousDeclaration = true;
                    }
                }
                if (hasPreviousDeclaration)
                {
                    errors.Add(SemanticError.PreviousTypeDeclaration(names[i], this.Declarations[i]));
                    this.IsOk = false;
                }
            }

            if (!this.IsOk)
            {
                return;
            }

            //--------------------------------------------------
            // Buscar Ciclos En Las Declaraciones AliasTypeNode
            // Y ArrayTypeNode.
            //--------------------------------------------------
            bool[] visited = new bool[this.Declarations.Length];

            //--------------------------------------------------
            // Actualizar 'Scope' Solamente Con Declaraciones De Records.
            //--------------------------------------------------
            for (int i = 0; i < this.Declarations.Length; i++)
            {
                if (this.Declarations[i].TypeNode is RecordTypeNode)
                {
                    visited[i] = true;
                    scope.Add(new TypeInfo(this.Declarations[i].ID.Name, this.Declarations[i].TypeNode));
                }
            }

            for (int i = 0; i < names.Length && this.IsOk; i++)
            {
                if (visited[i])
                {
                    continue;
                }

                List <int> path = new List <int>();

                int currentDeclaration = i;
                while (true)
                {
                    //--------------------------------------------------
                    // Si La Declaración Ha Sido Visitada Previamente,
                    // Entonces Estamos En Presencia  De  Un  Ciclo.
                    //--------------------------------------------------
                    if (visited[currentDeclaration])
                    {
                        errors.Add(SemanticError.CycleInTypeDeclaration(
                                       this.Declarations[currentDeclaration].ID.Name, this
                                       ));
                        this.IsOk = false;
                        break;
                    }

                    //--------------------------------------------------
                    // Marcar Como "Visitada" La Declaración Actual.
                    //--------------------------------------------------
                    path.Add(currentDeclaration);
                    visited[currentDeclaration] = true;

                    //--------------------------------------------------
                    // Buscar El Nombre Del Tipo Del Que Depende La
                    // Declaración Actual:
                    //
                    // type <type-id> = <type-id>
                    // type <type-id> = array of <type-id>
                    //--------------------------------------------------
                    var CDN = this.Declarations.ElementAt(currentDeclaration).TypeNode;

                    string type = CDN is AliasTypeNode ? (CDN as AliasTypeNode).TypeID.Name :
                                  (CDN as ArrayTypeNode).TypeID.Name;

                    //--------------------------------------------------
                    // Buscar Primero Si Depende De Un Tipo En Este Bloque
                    // De Declaraciones.
                    //--------------------------------------------------
                    int namesIndex = Array.FindIndex(this.Declarations, x => x.ID.Name == type);

                    //--------------------------------------------------
                    // Si El Tipo No Esta En El Bloque De Declaraciones,
                    // Buscar En El Scope Global. De Lo Contrario, Buscar
                    // En El Scope Local.
                    //--------------------------------------------------
                    TypeInfo TI = null;
                    if (namesIndex < 0 || namesIndex >= names.Length)
                    {
                        TI = scope.FindTypeInfo(type);
                    }
                    else
                    {
                        TI = scope.FindLocalTypeInfo(type);
                    }

                    //--------------------------------------------------
                    // Si El Tipo Está En El Scope, Actualizar Cada Una
                    // De Las Declaraciones.
                    //--------------------------------------------------
                    if (TI != null)
                    {
                        var TN = TI.TypeNode;

                        for (int u = path.Count - 1; u >= 0; u--)
                        {
                            var declarationNode = this.Declarations[path[u]];
                            if (declarationNode.TypeNode is AliasTypeNode)
                            {
                                (declarationNode.TypeNode as AliasTypeNode).AliasOf = TN;
                            }
                            else
                            {
                                (declarationNode.TypeNode as ArrayTypeNode).ArrayOf = TN;
                                TN = declarationNode.TypeNode;
                            }
                            scope.Add(new TypeInfo(declarationNode.ID.Name, TN));
                        }
                        break;
                    }

                    //--------------------------------------------------
                    // Si No Se Pudo Encontrar El Tipo , Entonces Comprobar
                    // Si Depende De Alguna Declaración En El Mismo Bloque.
                    // Si No Es El Caso, Reportar Error.
                    //--------------------------------------------------
                    currentDeclaration = namesIndex;

                    if (currentDeclaration < 0 || currentDeclaration >= names.Length)
                    {
                        errors.Add(SemanticError.TypeDoesNotExist(type, CDN));
                        this.IsOk = false;
                        break;
                    }
                }
            }

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

            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Cada TypeDeclarationNode.
            //--------------------------------------------------
            foreach (var declaration in this.Declarations)
            {
                declaration.CheckSemantics(scope, errors);
                this.IsOk &= declaration.IsOk;
            }
        }
Exemplo n.º 20
0
 public static void ReportError(SemanticError error)
 {
     Diagnostics.SemanticErrors.Add(error);
 }
        public override void CheckSemantics(Semantics.Scope scope, List <Semantics.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;
            }

            //--------------------------------------------------
            // Buscar Parámetros Repetidos En La Declaración De La Función.
            //--------------------------------------------------
            var ParameterName = this.Parameters.Select(x => x.ID.Name).ToArray <string>();

            for (int i = 0; i < ParameterName.Length; i++)
            {
                int j = 0;
                while (j < i && ParameterName[i] != ParameterName[j])
                {
                    j = j + 1;
                }
                if (j < i)
                {
                    errors.Add(SemanticError.PreviousParameterDeclaration(ParameterName[i], this.ID.Name, this.Parameters[i]));
                    this.IsOk = false;
                }
            }

            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Parámetros...
            //--------------------------------------------------
            foreach (var parameter in this.Parameters)
            {
                parameter.CheckSemantics(scope, errors);
                this.IsOk &= parameter.IsOk;
            }

            if (!this.IsOk)
            {
                return;
            }

            //--------------------------------------------------
            // Crea El 'FunctionInfo' Correspondiente A La Función
            // Actual. Notar Que El Tipo De Retorno Se Pone En <none>.
            //--------------------------------------------------
            this.FunctionInfo = new FunctionInfo(
                this.ID.Name,
                PredefinedTypes.VoidType,
                this.Parameters.Select(x => x.VariableInfo).ToArray()
                );

            //--------------------------------------------------
            // Si La Función Tiene El Tipo De Retorno Explícitamente
            // Entonces Es De La Siguiente Forma:
            //
            // function foo( parameters ) : type-id = expr
            //
            // ... Y Podemos Actualizar El 'FunctionInfo';
            //--------------------------------------------------
            if (this.ChildCount == 4)
            {
                var typeID = this.Children[3] 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, typeID));
                    this.IsOk = false;
                    return;
                }

                //--------------------------------------------------
                // Actualizar El Tipo De Retorno De La Función.
                //--------------------------------------------------
                this.FunctionInfo.ReturnType = TI.TypeNode;
            }

            //--------------------------------------------------
            // Actualizar El Scope Actual.
            //--------------------------------------------------
            scope.Add(this.FunctionInfo);
        }
Exemplo n.º 22
0
        public void Error(string format, params object[] args)
        {
            var err = new SemanticError(String.Format(format, args), item, readFrom.LineNumber, readFrom.LinePosition);
            engine.ReportError(err);

            // Inject an HTML comment describing the error:
            if (engine.InjectErrorComments)
                writeTo.AppendFormat("<!-- IVOCMS error in '{0}' ({1}:{2}): {3} -->", err.Item.TreeBlobPath.Path, err.LineNumber, err.LinePosition, err.Message);
        }
Exemplo n.º 23
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;
            }
        }
Exemplo n.º 24
0
        public override void CheckSemantics(Scope scope, List <SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.LoNode.CheckSemantics(scope, errors);
            this.HiNode.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.LoNode.ExpressionType == PredefinedTypes.ErrorType ||
                this.HiNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // Ambos Nodos, LoNode & HiNode, Deben Ser De Tipo <int>.
            //--------------------------------------------------
            if (this.LoNode.ExpressionType != PredefinedTypes.IntType ||
                this.HiNode.ExpressionType != PredefinedTypes.IntType)
            {
                if (this.LoNode.ExpressionType != PredefinedTypes.IntType)
                {
                    errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType, this.LoNode.ExpressionType, this.LoNode));
                }
                if (this.HiNode.ExpressionType != PredefinedTypes.IntType)
                {
                    errors.Add(SemanticError.ExpectedType(PredefinedTypes.IntType, this.HiNode.ExpressionType, this.HiNode));
                }
                return;
            }

            //--------------------------------------------------
            // Definir Un Nuevo Scope Con La Variable De Iteración
            // Incluída.
            //--------------------------------------------------
            this.ID.VariableInfo = new VariableInfo(this.ID.Name, PredefinedTypes.IntType, true);

            Scope InnerScope = scope.CreateChildScope();

            InnerScope.Add(this.ID.VariableInfo);

            //--------------------------------------------------
            // Hacer 'CheckSemantics' En El Cuerpo Del For.
            //--------------------------------------------------
            this.BodyNode.CheckSemantics(InnerScope, errors);

            //--------------------------------------------------
            // Si Hay Errores En El Cuerpo Del For, Parar De
            // Reportar Errores.
            //--------------------------------------------------
            if (this.BodyNode.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            //--------------------------------------------------
            // El Cuerpo Del For No Puede Devolver Valor.
            //--------------------------------------------------
            if (this.BodyNode.ExpressionType != PredefinedTypes.VoidType)
            {
                errors.Add(SemanticError.ExpectedType(PredefinedTypes.VoidType,
                                                      this.BodyNode.ExpressionType, this));
            }
            else
            {
                this.ExpressionType = PredefinedTypes.VoidType;
            }
        }