Пример #1
0
 public void Bind(VariableSymbolNode symbol)
 {
     VariableIdentifierNode = new BoundIdentifierNode(VariableIdentifier, symbol, VariableIdentifierNode.LineNumber, VariableIdentifierNode.LineNumber)
     {
         ParentNode = this
     };
 }
Пример #2
0
        public VariableSymbolNode CreateVariable(TypeSymbolNode type)
        {
            VariableSymbolNode variable = new VariableSymbolNode(VariableIdentifier,
                                                                 type,
                                                                 isReadOnly: true,
                                                                 VariableIdentifierNode.LineNumber,
                                                                 VariableIdentifierNode.Index);

            VariableIdentifierNode = new BoundIdentifierNode(VariableIdentifier,
                                                             variable,
                                                             VariableIdentifierNode.LineNumber,
                                                             VariableIdentifierNode.Index)
            {
                ParentNode = this
            };
            return(variable);
        }
Пример #3
0
 public Variable(VariableSymbolNode variable, int level)
 {
     this.variable = variable;
     this.level    = level;
 }
Пример #4
0
        private bool BindInForStatement(ForStatementNode forStatement, VariableIdentifierMap variableIdentifierMap)
        {
            variableIdentifierMap.EnterBlock();

            TypeSymbolNode iterationVariableType;

            if (forStatement.DeclaresNew)
            {
                Debug.Assert(forStatement.InitialValueNode != null);

                TypeSymbolNode?assignedValueType = BindInExpression(forStatement.InitialValueNode, variableIdentifierMap);

                if (assignedValueType == null)
                {
                    return(false);
                }

                iterationVariableType = assignedValueType;

                VariableSymbolNode variable = forStatement.CreateVariable(iterationVariableType);

                variableIdentifierMap.AddSymbol(forStatement.VariableIdentifier, variable);
            }
            else
            {
                SymbolNode?symbol = GetExpressionSymbol(forStatement.VariableIdentifier, variableIdentifierMap);

                if (symbol == null)
                {
                    ErrorProvider.ReportError(ErrorCode.CantFindIdentifierInScope,
                                              Compilation,
                                              forStatement.VariableIdentifierNode);
                    return(false);
                }

                if (symbol is not VariableSymbolNode variable)
                {
                    ErrorProvider.ReportError(ErrorCode.ForNotVariable,
                                              Compilation,
                                              forStatement.VariableIdentifierNode,
                                              $"Identifier: {forStatement.VariableIdentifier}");
                    return(false);
                }

                Debug.Assert(variable.TypeNode != null);
                iterationVariableType = variable.TypeNode;

                if (forStatement.InitialValueNode != null)
                {
                    TypeSymbolNode?assignedValueType = BindInExpression(forStatement.InitialValueNode, variableIdentifierMap);

                    if (assignedValueType == null)
                    {
                        return(false);
                    }

                    if (!TypeIsCompatibleWith(assignedValueType,
                                              iterationVariableType,
                                              possiblyOffendingNode: forStatement.InitialValueNode,
                                              out ImplicitConversionSymbolNode? implicitConversion))
                    {
                        if (implicitConversion != null)
                        {
                            forStatement.InitialValueNode.SpecifyImplicitConversion(implicitConversion);
                        }

                        return(false);
                    }
                }
            }

            {
                TypeSymbolNode?intType      = typeManager[FrameworkType.Int];
                TypeSymbolNode?rationalType = typeManager[FrameworkType.Rational];
                TypeSymbolNode?complexType  = typeManager[FrameworkType.Complex];

                if (iterationVariableType != intType &&
                    iterationVariableType != rationalType &&
                    iterationVariableType != complexType)
                {
                    ErrorProvider.ReportError(ErrorCode.ForIterationVariableHasToBeNumberType,
                                              Compilation,
                                              forStatement.VariableIdentifierNode,
                                              $"Type of iteration variable: {iterationVariableType.Identifier}");
                    return(false);
                }
            }

            if (forStatement.ConditionNode != null)
            {
                TypeSymbolNode?conditionType = BindInExpression(forStatement.ConditionNode, variableIdentifierMap);

                if (conditionType == null)
                {
                    return(false);
                }

                TypeSymbolNode?boolType = typeManager[FrameworkType.Bool];

                if (!TypeIsCompatibleWith(conditionType,
                                          boolType,
                                          possiblyOffendingNode: forStatement.ConditionNode,
                                          out ImplicitConversionSymbolNode? conversion))
                {
                    return(false);
                }

                if (conversion != null)
                {
                    forStatement.ConditionNode.SpecifyImplicitConversion(conversion);
                }
            }

            if (forStatement.WithExpressionNode != null)
            {
                TypeSymbolNode?withType = BindInExpression(forStatement.WithExpressionNode, variableIdentifierMap);

                if (withType == null)
                {
                    return(false);
                }

                if (!TypeIsCompatibleWith(withType,
                                          iterationVariableType,
                                          possiblyOffendingNode: forStatement.WithExpressionNode,
                                          out ImplicitConversionSymbolNode? conversion))
                {
                    return(false);
                }

                if (conversion != null)
                {
                    forStatement.WithExpressionNode.SpecifyImplicitConversion(conversion);
                }
            }

            bool success = BindInStatementBlock(forStatement.StatementNodes, variableIdentifierMap);

            if (!success)
            {
                return(false);
            }

            variableIdentifierMap.LeaveBlock();

            return(true);
        }