예제 #1
0
        public override void CheckSemantics(Semantics.Scope scope, List <Semantics.SemanticError> errors)
        {
            //--------------------------------------------------
            // Hacer 'CheckSemantics' A Los Hijos.
            //--------------------------------------------------
            this.LeftVariable.CheckSemantics(scope, errors);
            this.Index.CheckSemantics(scope, errors);

            //--------------------------------------------------
            // ...
            //--------------------------------------------------
            this.ReadOnly = this.LeftVariable.ReadOnly;

            //--------------------------------------------------
            // 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.Index.ExpressionType == PredefinedTypes.ErrorType)
            {
                return;
            }

            var AT = this.LeftVariable.ExpressionType as ArrayTypeNode;

            //--------------------------------------------------
            // Si La Variable No Es Un Array, Reportar Error.
            //--------------------------------------------------
            if (AT == null)
            {
                errors.Add(SemanticError.InvalidIndexingOperation(this.LeftVariable.ExpressionType, this));
                return;
            }

            //--------------------------------------------------
            // 'Index' Debe Ser De Tipo <int>
            //--------------------------------------------------
            if (this.Index.ExpressionType != PredefinedTypes.IntType)
            {
                errors.Add(SemanticError.InvalidArrayAccess(this.Index));
            }
            else
            {
                this.ExpressionType = AT.ArrayOf;
            }
        }
예제 #2
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 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);
        }
예제 #4
0
 public override void CheckSemantics(Semantics.Scope scope, System.Collections.Generic.List <Semantics.SemanticError> errors)
 {
     this.ExpressionType = PredefinedTypes.NilType;
 }