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

📄 conditionalexpression.vb

📁 大名鼎鼎的mono是.NET平台的跨平台(支持linux
💻 VB
📖 第 1 页 / 共 2 页
字号:
' 
' 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
' 

Option Compare Text

Public Class ConditionalExpression
    Inherits BaseObject

    Private m_Compiler As ConditionalCompiler

    <Obsolete()> Friend Overrides ReadOnly Property tm() As tm
        Get
            Return MyBase.tm 'Throw New InternalException("Don't use this")
        End Get
    End Property

    ReadOnly Property CurrentConstants() As ConditionalConstants
        Get
            Return m_Compiler.CurrentConstants
        End Get
    End Property

    Public Sub New(ByVal Compiler As ConditionalCompiler)
        MyBase.New(Compiler)
        m_Compiler = Compiler
    End Sub

    ReadOnly Property Reader() As ITokenReader
        Get
            Return m_Compiler.Reader
        End Get
    End Property

    Function RuleIdentifier(ByRef Result As Object) As Boolean
        'A value of 0 evaluates as false, anything else as true
        If Reader.Peek.Equals(KS.Nothing) Then
            Result = Nothing
            Reader.Next()
        ElseIf Reader.Peek.IsLiteral Then
            Dim tp As TypeCode = Type.GetTypeCode(Reader.Peek.LiteralValue.GetType)
            Select Case tp
                Case TypeCode.String
                    Result = Reader.Peek.StringLiteral
                Case TypeCode.Object
                    Throw New InternalException("Shouldn't happen, Nothing is a keyword.")
                Case TypeCode.Boolean
                    Throw New InternalException("Shouldn't happen, True and False are keywords.")
                Case TypeCode.DateTime
                    Result = Reader.Peek.DateLiteral
                Case Else
                    Helper.Assert(Compiler.TypeResolution.IsNumericType(Reader.Peek.LiteralValue.GetType))
                    Result = CDbl(Reader.Peek.LiteralValue) 'AsFloatingPointLiteral.Literal
            End Select
            'Result = CurrentToken.Value.Literal
            Reader.Next()
        ElseIf Reader.Peek.IsKeyword Then
            Dim tpType As Type = Compiler.TypeResolution.KeywordToType(Reader.Peek.Keyword)
            If tpType Is Nothing Then
                If Reader.Peek.Equals(KS.True) Then
                    Result = True
                    Reader.Next()
                    Return True
                ElseIf Reader.Peek.Equals(KS.False) Then
                    Result = False
                    Reader.Next()
                    Return True
                Else 'TODO: Conversion functions (CInt...)
                    Compiler.Report.ShowMessage(Messages.VBNC30201)
                End If
                Reader.Next()
                Return False
            Else
                'A builtin type, i.e:
                '#Const a = Integer.MaxValue
                '#Const a = (user defined type).Constant is not allowed.
                Throw New InternalException("") 'TODO
            End If
        ElseIf Reader.Peek.IsIdentifier Then
            'Find the identifier in the list of defines.
            If CurrentConstants.ContainsKey(Reader.Peek.Identifier) Then
                Result = CurrentConstants.Item(Reader.Peek.Identifier).Value
                Reader.Next()
            Else
                Result = Nothing
                Reader.Next()
            End If
        End If

        Return True
    End Function

    Function RuleExponent(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing, RSide As Object = Nothing

        If RuleIdentifier(LSide) = False Then Return False

        While Reader.Peek.Equals(KS.Power)
            Reader.Next()
            RuleExpression(RSide)

            Dim op1, op2 As Double
            Dim bErr As Boolean
            If ToDouble(LSide, op1) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, LSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If
            If ToDouble(RSide, op2) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, RSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If

            If bErr Then
                LSide = CDbl(0)
            Else
                LSide = op1 ^ op2
            End If
        End While

        Result = LSide
        Return True
    End Function

    Function RuleUnaryNegation(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing

        If Reader.Peek.Equals(KS.Minus) Then
            Reader.Next()
            RuleUnaryNegation = RuleExponent(LSide)

            Dim op1 As Double
            If ToDouble(LSide, op1) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, LSide.GetType.ToString, KS.Double.ToString)
                LSide = 0
            Else
                LSide = -op1
            End If
        Else
            If RuleExponent(LSide) = False Then
                Return False
            End If
        End If
        Result = LSide
        Return True
    End Function

    Function RuleMultiplicationAndRealDivision(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing, RSide As Object = Nothing

        If RuleUnaryNegation(LSide) = False Then Return False

        While Reader.Peek.Equals(KS.Mult, KS.RealDivision)
            Dim DoMult As Boolean
            DoMult = Reader.Peek.Equals(KS.Mult)
            Reader.Next()

            RuleExpression(RSide)

            Dim op1, op2 As Double
            Dim bErr As Boolean
            If ToDouble(LSide, op1) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, LSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If
            If ToDouble(RSide, op2) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, RSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If

            If bErr Then
                LSide = CDbl(0)
            ElseIf DoMult Then
                LSide = op1 * op2
            Else
                If op2 = 0 Then
                    Compiler.Report.ShowMessage(Messages.VBNC30542)
                    LSide = CDbl(0)
                Else
                    LSide = op1 / op2
                End If
            End If
        End While

        Result = LSide
        Return True
    End Function

    Function RuleIntegerDivision(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing, RSide As Object = Nothing

        If RuleMultiplicationAndRealDivision(LSide) = False Then Return False

        While Reader.Peek.Equals(KS.IntDivision)
            Reader.Next()
            RuleExpression(RSide)

            Dim op1, op2 As Double
            Dim bErr As Boolean
            If ToDouble(LSide, op1) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, LSide.GetType.ToString, KS.Long.ToString)
                bErr = True
            End If
            If ToDouble(RSide, op2) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, RSide.GetType.ToString, KS.Long.ToString)
                bErr = True
            End If

            If bErr Then
                LSide = CDbl(0)
            ElseIf CLng(op2) = 0 Then
                Compiler.Report.ShowMessage(Messages.VBNC30542)
                LSide = CDbl(0)
            Else
                LSide = CDbl(CLng(op1) \ CLng(op2))
            End If
        End While

        Result = LSide
        Return True
    End Function

    Function RuleMod(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing, RSide As Object = Nothing

        If RuleIntegerDivision(LSide) = False Then Return False

        While Reader.Peek.Equals(KS.Mod)
            Reader.Next()
            RuleExpression(RSide)

            Dim op1, op2 As Double
            Dim bErr As Boolean
            If ToDouble(LSide, op1) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, LSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If
            If ToDouble(RSide, op2) = False Then
                Compiler.Report.ShowMessage(Messages.VBNC30748, RSide.GetType.ToString, KS.Double.ToString)
                bErr = True
            End If

            If bErr Then
                LSide = CLng(0)
            Else
                LSide = op1 Mod op2
            End If
        End While

        Result = LSide
        Return True
    End Function

    Function RuleAdditionSubtractionStringConcat(ByRef Result As Object) As Boolean
        Dim LSide As Object = Nothing, RSide As Object = Nothing

        If RuleMod(LSide) = False Then Return False

        While Reader.Peek.Equals(KS.Minus, KS.Add)
            Dim DoAdd As Boolean
            DoAdd = Reader.Peek.Equals(KS.Add)
            Reader.Next()
            RuleExpression(RSide)

            Dim bErr As Boolean
            If TypeOf LSide Is String AndAlso TypeOf RSide Is String Then
                'String concat
                LSide = CStr(LSide) & CStr(RSide)
            Else
                Dim op1, op2 As Double
                If TypeOf LSide Is String Then
                    op1 = Double.Parse(DirectCast(LSide, String))
                    If ToDouble(RSide, op2) = False Then
                        Compiler.Report.ShowMessage(Messages.VBNC30748, RSide.GetType.ToString, KS.Double.ToString)
                        bErr = True
                    End If
                ElseIf TypeOf RSide Is String Then
                    op2 = Double.Parse(DirectCast(RSide, String))

⌨️ 快捷键说明

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