⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 forstatement.vb

📁 大名鼎鼎的mono是.NET平台的跨平台(支持linux
💻 VB
字号:
' ' Visual Basic.Net Compiler' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com' ' This library is free software; you can redistribute it and/or' modify it under the terms of the GNU Lesser General Public' License as published by the Free Software Foundation; either' version 2.1 of the License, or (at your option) any later version.' ' This library is distributed in the hope that it will be useful,' but WITHOUT ANY WARRANTY; without even the implied warranty of' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU' Lesser General Public License for more details.' ' You should have received a copy of the GNU Lesser General Public' License along with this library; if not, write to the Free Software' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA' ''' <summary>''' ForStatement  ::='''	   "For" LoopControlVariable  "="  Expression  "To"  Expression  [  "Step"  Expression  ]  StatementTerminator'''	      [ Block  ]'''	   "Next" [  NextExpressionList  ]  StatementTerminator''' LoopControlVariable  ::='''	   Identifier  [  ArrayNameModifier  ] "As" TypeName  |'''	   Expression''' NextExpressionList  ::='''	   Expression  |'''	   NextExpressionList "," Expression''' </summary>''' <remarks></remarks>Public Class ForStatement    Inherits BlockStatement    ''' <summary>    ''' The loop control variable    ''' </summary>    ''' <remarks></remarks>    Private m_LoopControlVariable As LoopControlVariable    Private m_LoopStartExpression As Expression    Private m_LoopEndExpression As Expression    Private m_LoopStepExpression As Expression    Private m_NextExpressionList As ExpressionList    Private m_NextIteration As Label    Private m_LoopType As Type    ReadOnly Property LoopStepExpression() As Expression        Get            Return m_LoopStepExpression        End Get    End Property    ReadOnly Property NextExpressionList() As ExpressionList        Get            Return m_NextExpressionList        End Get    End Property    ReadOnly Property LoopEndExpression() As Expression        Get            Return m_LoopEndExpression        End Get    End Property    ReadOnly Property LoopStartExpression() As Expression        Get            Return m_LoopStartExpression        End Get    End Property    ReadOnly Property LoopControlVariable() As LoopControlVariable        Get            Return m_LoopControlVariable        End Get    End Property    Public Overrides Function ResolveTypeReferences() As Boolean        Dim result As Boolean = True        If m_LoopControlVariable IsNot Nothing Then result = m_LoopControlVariable.ResolveTypeReferences AndAlso result        If m_LoopStartExpression IsNot Nothing Then result = m_LoopStartExpression.ResolveTypeReferences AndAlso result        If m_LoopEndExpression IsNot Nothing Then result = m_LoopEndExpression.ResolveTypeReferences AndAlso result        If m_LoopStepExpression IsNot Nothing Then result = m_LoopStepExpression.ResolveTypeReferences AndAlso result        If m_NextExpressionList IsNot Nothing Then result = m_NextExpressionList.ResolveTypeReferences AndAlso result        result = MyBase.ResolveTypeReferences AndAlso result        Return result    End Function    Sub New(ByVal Parent As ParsedObject)        MyBase.New(Parent)    End Sub    Shadows Sub Init(ByVal LoopControlVariable As LoopControlVariable, ByVal LoopStartExpression As Expression, ByVal LoopEndExpression As Expression, ByVal LoopStepExpression As Expression, ByVal NextExpressionList As ExpressionList, ByVal Block As CodeBlock)        MyBase.Init(Block)        m_LoopControlVariable = LoopControlVariable        m_LoopStartExpression = LoopStartExpression        m_LoopEndExpression = LoopEndExpression        m_LoopStepExpression = LoopStepExpression        m_NextExpressionList = NextExpressionList    End Sub    ReadOnly Property NextIteration() As Label        Get            Return m_NextIteration        End Get    End Property    ''' <summary>    ''' Emit code for     ''' Dim i As Integer    ''' For i = 0 ...    ''' </summary>    ''' <param name="Info"></param>    ''' <returns></returns>    ''' <remarks></remarks>    Private Function GenerateOtherVariableCode(ByVal Info As EmitInfo) As Boolean        Dim result As Boolean = True        Dim conditionLabel As Label        Dim startlabel As Label        Dim loopexp As Expression        Dim loopClass As VariableClassification        Dim loadInfo, storeInfo As EmitInfo        Dim maxvar As LocalBuilder        Dim stepvar As LocalBuilder = Nothing        startlabel = Info.ILGen.DefineLabel        conditionLabel = Info.ILGen.DefineLabel        EndLabel = Info.ILGen.DefineLabel        m_NextIteration = Info.ILGen.DefineLabel        loopexp = m_LoopControlVariable.Expression        loopClass = loopexp.Classification.AsVariableClassification        loadInfo = Info.Clone(True, False, m_LoopType)        storeInfo = Info.Clone(False, False, m_LoopType)        maxvar = Emitter.DeclareLocal(Info, m_LoopType, "maxvar$" & Me.ObjectID.ToString)        stepvar = Emitter.DeclareLocal(Info, m_LoopType, "stepvar$" & Me.ObjectID.ToString)        'Load the initial expression        'result = m_LoopStartExpression.GenerateCode(loadInfo) AndAlso result        result = loopClass.GenerateCode(Info.Clone(m_LoopStartExpression)) AndAlso result        'Emitter.EmitStoreVariable(Info, loopClass)        'Load the max expression        result = m_LoopEndExpression.GenerateCode(loadInfo) AndAlso result        Emitter.EmitStoreVariable(Info, maxvar)        result = m_LoopStepExpression.GenerateCode(loadInfo) AndAlso result        Emitter.EmitStoreVariable(Info, stepvar)        'Jump to the comparison        Emitter.EmitBranch(Info, conditionLabel)        Info.ILGen.MarkLabel(startlabel)        result = CodeBlock.GenerateCode(Info) AndAlso result        'This is the start of the next iteration        Info.ILGen.MarkLabel(m_NextIteration)        Dim addexp As New BinaryAddExpression(Me, loopexp, New LoadLocalExpression(Me, stepvar))        result = addexp.ResolveExpression(ResolveInfo.Default(Compiler)) AndAlso result        'result = addexp.GenerateCode(Info.Clone) AndAlso result        ''Load the current loop value        'result = loopClass.GenerateCodeAsValue(loadInfo) AndAlso result        ''Load the value to add        'Emitter.EmitLoadVariable(Info, stepvar)        ''Add them up        'Emitter.EmitAdd(Info, m_LoopType)        'Store the result into the loop var        result = loopClass.GenerateCode(Info.Clone(addexp)) AndAlso result        'Emitter.EmitStoreVariable(Info, loopClass)        Info.ILGen.MarkLabel(conditionLabel)        'Load the current value        result = loopexp.GenerateCode(loadInfo) AndAlso result        'Load the max value        Emitter.EmitLoadVariable(Info, maxvar)        'Compare the values        EmitComparison(Info, startlabel, stepvar)        Info.ILGen.MarkLabel(EndLabel)        Return result    End Function    Private Function IsNegativeStep() As Boolean        Dim constant As Object        constant = m_LoopStepExpression.ConstantValue        If TypeOf constant Is Decimal Then            Return CDec(constant) < 0        Else            Return CDbl(constant) < 0        End If    End Function    Private Function IsPositiveStep() As Boolean        Dim constant As Object        constant = m_LoopStepExpression.ConstantValue        If TypeOf constant Is Decimal Then            Return CDec(constant) > 0        Else            Return CDbl(constant) > 0        End If    End Function    Private Function IsKnownStep() As Boolean        Return m_LoopStepExpression.IsConstant    End Function    ''' <summary>    ''' Emit code for    ''' For i As Integer = 0 ...    ''' </summary>    ''' <param name="Info"></param>    ''' <returns></returns>    ''' <remarks></remarks>    Private Function GenerateDeclaredVariableCode(ByVal Info As EmitInfo) As Boolean        Dim result As Boolean = True        Dim conditionLabel As Label        Dim startlabel As Label        Dim maxvar As LocalBuilder        Dim loopvar As LocalBuilder        Dim stepvar As LocalBuilder = Nothing        Dim loadInfo As EmitInfo        conditionLabel = Info.ILGen.DefineLabel        startlabel = Info.ILGen.DefineLabel        EndLabel = Info.ILGen.DefineLabel        m_NextIteration = Info.ILGen.DefineLabel        loadInfo = Info.Clone(True, False, m_LoopType)        'Create the localbuilder        result = m_LoopControlVariable.GenerateCode(Info) AndAlso result        loopvar = m_LoopControlVariable.GetVariableDeclaration.LocalBuilder        maxvar = Emitter.DeclareLocal(Info, m_LoopType, "maxvar$" & Me.ObjectID.ToString)        stepvar = Emitter.DeclareLocal(Info, m_LoopType, "stepvar$" & Me.ObjectID.ToString)        'Load the initial expression        result = m_LoopStartExpression.GenerateCode(loadInfo) AndAlso result        Emitter.EmitStoreVariable(Info, loopvar)        'Load the max expression        result = m_LoopEndExpression.GenerateCode(loadInfo) AndAlso result        Emitter.EmitStoreVariable(Info, maxvar)        result = m_LoopStepExpression.GenerateCode(loadInfo) AndAlso result        Emitter.EmitStoreVariable(Info, stepvar)        'Jump to the comparison        Emitter.EmitBranch(Info, conditionLabel)        'Emit the contained code.        Info.ILGen.MarkLabel(startlabel)        result = CodeBlock.GenerateCode(Info) AndAlso result        'This is the start of the next iteration        Info.ILGen.MarkLabel(m_NextIteration)        'Load the current loop value        Emitter.EmitLoadVariable(Info, loopvar)        'Load the value to add        Emitter.EmitLoadVariable(Info, stepvar)        'Add them up        Emitter.EmitAdd(Info, m_LoopType)        'Store the result into the loop var        Emitter.EmitStoreVariable(Info, loopvar)        'Do the comparison        Info.ILGen.MarkLabel(conditionLabel)        'Load the current value        Emitter.EmitLoadVariable(Info, loopvar)        'Load the max value        Emitter.EmitLoadVariable(Info, maxvar)        'Compare the values        EmitComparison(Info, startlabel, stepvar)        Info.ILGen.MarkLabel(EndLabel)        Return result    End Function    Private Sub EmitComparison(ByVal Info As EmitInfo, ByVal startLabel As Label, ByVal stepvar As LocalBuilder)        If IsKnownStep() Then            If IsPositiveStep() Then                Emitter.EmitLE(Info, m_LoopType)                Emitter.EmitBranchIfTrue(Info, startlabel)            ElseIf IsNegativeStep() Then                Emitter.EmitGE(Info, m_LoopType)                Emitter.EmitBranchIfTrue(Info, startlabel)            Else                Helper.AddError("Infinite loop")            End If        Else            Dim negativeLabel As Label            Dim endCheck As Label            negativeLabel = Emitter.DefineLabel(info)            endCheck = Emitter.DefineLabel(Info)            Emitter.EmitLoadVariable(Info, stepvar)            Emitter.EmitLoadValue(Info.Clone(True, False, m_LoopType), TypeConverter.ConvertTo(0, m_LoopType))            Emitter.EmitGE(Info, m_LoopType) 'stepvar >= 0?            Info.ILGen.Emit(OpCodes.Brfalse_S, negativeLabel)            Info.Stack.Pop(Compiler.TypeCache.System_Boolean)            Emitter.EmitLE(Info, m_LoopType) 'Positive check            Emitter.EmitBranch(Info, endCheck)            Emitter.MarkLabel(Info, negativeLabel)            Emitter.EmitGE(Info, m_LoopType) 'Negative check            Emitter.MarkLabel(info, endCheck)            Emitter.EmitBranchIfTrue(Info, startlabel)        End If    End Sub    Friend Overrides Function GenerateCode(ByVal Info As EmitInfo) As Boolean        Dim result As Boolean = True        If m_LoopControlVariable.IsVariableDeclaration Then            result = GenerateDeclaredVariableCode(Info) AndAlso result        Else            result = GenerateOtherVariableCode(Info) AndAlso result        End If        Return result    End Function    Public Overrides Function ResolveStatement(ByVal Info As ResolveInfo) As Boolean        Dim result As Boolean = True        result = m_LoopControlVariable.ResolveCode(Info) AndAlso result        result = m_LoopStartExpression.ResolveExpression(Info) AndAlso result        result = m_LoopEndExpression.ResolveExpression(Info) AndAlso result        If m_LoopControlVariable.Expression IsNot Nothing Then            If m_LoopControlVariable.Expression.Classification.IsVariableClassification = False Then                Helper.AddError("In the case of an expression, the expression must be classified as a variable.")            End If        End If        m_LoopType = m_LoopControlVariable.VariableType        If m_LoopStepExpression IsNot Nothing Then            result = m_LoopStepExpression.ResolveExpression(Info) AndAlso result        Else            m_LoopStepExpression = New ConstantExpression(Me, 1, Compiler.TypeCache.System_Int32)        End If        'If m_NextExpressionList IsNot Nothing Then result = m_NextExpressionList.ResolveCode(info) AndAlso result        m_LoopStepExpression = Helper.CreateTypeConversion(Me, m_LoopStepExpression, m_LoopType, result)        m_LoopStartExpression = Helper.CreateTypeConversion(Me, m_LoopStartExpression, m_LoopType, result)        m_LoopEndExpression = Helper.CreateTypeConversion(Me, m_LoopEndExpression, m_LoopType, result)        If m_LoopControlVariable.IsVariableDeclaration Then            CodeBlock.Variables.Add(m_LoopControlVariable.GetVariableDeclaration)        End If        result = CodeBlock.ResolveCode(Info) AndAlso result        Compiler.Helper.AddCheck("Check that loop variable has not been used in another for statement.")        Compiler.Helper.AddCheck("The loop control variable of a For statement must be of a primitive numeric type (Byte, SByte, UShort, Short, UInteger, Integer, ULong, Long, Decimal, Single, Double), Object, or a type T that has the following operators: (...)")        Compiler.Helper.AddCheck("The bound and step expressions must be implicitly convertible to the type of the loop control. ")        Compiler.Helper.AddCheck("If a variable matches a For loop that is not the most nested loop at that point, a compile-time error results")        Compiler.Helper.AddCheck("It is not valid to branch into a For loop from outside the loop.")        Return result    End FunctionEnd Class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -