Exemplo n.º 1
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al IndexExpression
            IndexExpression.CheckSemantic(symbolTable, errors);

            ///check semantics al InitExpression
            InitExpression.CheckSemantic(symbolTable, errors);

            ///si IndexExpression o InitExpression evalúa de error entonces esta también
            if (IndexExpression.NodeInfo.Equals(SemanticInfo.SemanticError) ||
                InitExpression.NodeInfo.Equals(SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            SemanticInfo arrayInfo;

            ///el ArrayId tiene que estar definido
            if (!symbolTable.GetDefinedTypeDeep(ArrayId, out arrayInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = GetChild(0).Line,
                    Column       = GetChild(0).CharPositionInLine,
                    ErrorMessage = string.Format("Type '{0}' could not be found in current context", ArrayId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }
            else
            {
                ///ArrayId tiene que ser compatible con array
                if (!arrayInfo.Type.BuiltInType.IsCompatibleWith(BuiltInType.Array))
                {
                    errors.Add(new CompileError
                    {
                        Line         = GetChild(0).Line,
                        Column       = GetChild(0).CharPositionInLine,
                        ErrorMessage = string.Format("Cannot apply indexing with [] to an expression of type '{0}'", arrayInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si IndexExpression no evaluó de error
            if (!Object.Equals(IndexExpression.NodeInfo, SemanticInfo.SemanticError))
            {
                ///IndexExpressiontiene que ser compatible con 'int'
                if (!IndexExpression.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Int))
                {
                    errors.Add(new CompileError
                    {
                        Line         = IndexExpression.Line,
                        Column       = IndexExpression.CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to 'int'", IndexExpression.NodeInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si InitExpression no evaluó de error
            if (!Object.Equals(InitExpression.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el tipo de InitExpression debe ser compatible con el de los elementos del array
                if (!Object.Equals(arrayInfo, SemanticInfo.SemanticError) &&
                    !arrayInfo.Type.ElementsType.Type.IsCompatibleWith(InitExpression.NodeInfo.Type))
                {
                    errors.Add(new CompileError
                    {
                        Line         = GetChild(2).Line,
                        Column       = GetChild(2).CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to '{1}'", InitExpression.NodeInfo.Type.Name, arrayInfo.ElementsType.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///seteamos los campos necesarios
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo.BuiltInType = BuiltInType.Array;

                NodeInfo.ElementsType = arrayInfo.Type.ElementsType;
                NodeInfo.Fields       = arrayInfo.Type.Fields;

                //change the last
                NodeInfo.Type   = arrayInfo.Type.Type;
                NodeInfo.ILType = arrayInfo.Type.ILType;
            }
        }