public void Bind(VariableSymbolNode symbol) { VariableIdentifierNode = new BoundIdentifierNode(VariableIdentifier, symbol, VariableIdentifierNode.LineNumber, VariableIdentifierNode.LineNumber) { ParentNode = this }; }
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); }
public Variable(VariableSymbolNode variable, int level) { this.variable = variable; this.level = level; }
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); }