Beispiel #1
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);
        }
Beispiel #2
0
        private bool BindInVariableDeclaration(VariableDeclarationStatementNode variableDeclaration,
                                               VariableIdentifierMap variableIdentifierMap)
        {
            if (variableIdentifierMap.TryGet(variableDeclaration.VariableIdentifier, out VariableSymbolNode? _))
            {
                ErrorProvider.ReportError(ErrorCode.CantRedeclareVariable,
                                          Compilation,
                                          variableDeclaration.VariableIdentifierNode);
                return(false);
            }

            VariableSymbolNode variable;

            if (variableDeclaration.AssignedExpressionNode != null)
            {
                TypeSymbolNode?assignedType = BindInExpression(variableDeclaration.AssignedExpressionNode,
                                                               variableIdentifierMap);

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

                if (variableDeclaration.TypeSpecNode == null)
                {
                    variable = variableDeclaration.CreateVariable(typeSymbol: assignedType);
                }
                else
                {
                    if (!typeManager.TryGetTypeSymbol(variableDeclaration.TypeSpecNode, out TypeSymbolNode? variableType))
                    {
                        return(false);
                    }
                    else if (!TypeIsCompatibleWith(assignedType,
                                                   variableType,
                                                   variableDeclaration.AssignedExpressionNode,
                                                   out ImplicitConversionSymbolNode? conversion))
                    {
                        return(false);
                    }
                    else
                    {
                        if (conversion != null)
                        {
                            variableDeclaration.AssignedExpressionNode.SpecifyImplicitConversion(conversion);
                        }

                        variable = variableDeclaration.CreateVariable(variableType);
                    }
                }
            }
            else
            {
                if (typeManager.TryGetTypeSymbol(variableDeclaration.TypeSpecNode, out TypeSymbolNode? variableType))
                {
                    variable = variableDeclaration.CreateVariable(variableType);
                }
                else
                {
                    return(false);
                }
            }

            variableIdentifierMap.AddSymbol(variableDeclaration.VariableIdentifier, variable);

            return(true);
        }