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); }
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); }