Codice EvaluateString da migliorare
a cura di Anonimo (requisiti: conoscenza bassa di Visual Basic)

Public Class EvaluateString

    Implements IDisposable

    Public GetValueLogResolveExp 
    As String

    Public Function RekonExp(ByVal StringCompare As String) As Object
      On Error GoTo ERR

      Dim ProvvisoryNumbFinalize 
      As Long
      Dim Increment As Integer
      Dim Increment1 As Integer
      Dim Increment2 As Integer
      Dim CountText As Integer
      Dim StartIndexText As Integer
      Dim EndIndexText As Integer
      Dim TotalNumExp As Integer
      Dim TypeParentesi(1) As String
      Dim SubText As String
      Dim SubTextExponent As String
      Dim Interruptor As Boolean
      Dim InterruptorDecision As Boolean
      Dim InterruptorEsponent As Boolean
      Dim ResultExp As String

      If StringCompare = "" Then
        MsgBox("Immettere un'espressione! Impossibile eseguire la funzione!", _
               MsgBoxStyle.Exclamation, "Avviso!")
        Exit Function
      End If

      If  StringCompare.Contains(".") Then
        StringCompare = StringCompare.Replace(".", ",")
      End If

      TotalNumExp = 0
      GetValueLogResolveExp = vbCrLf & "Risoluzione espressione:  " & _
      StringCompare & vbCrLf & _
        "________________________________________________________________" & vbCrLf & vbCrLf

  STEP_CONTROLLER_STATUS_EXP:

      ProvvisoryNumbFinalize = 0
      Increment = 0
      Increment1 = 0
      CountText = 0
      StartIndexText = 0
      EndIndexText = 0
      Interruptor = False
      InterruptorDecision = False
      InterruptorEsponent = False
      TypeParentesi(0) = ""
      TypeParentesi(1) = ""
      SubText = ""
      SubTextExponent = ""

      If StringCompare.Contains("(") Then
        TypeParentesi(0) = "("
        TypeParentesi(1) = ")"
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                                "Risolvo le parentesi tonde!" & "  "
        GoTo STEP_SELECT_SUBSTRING
      End If
      If StringCompare.Contains("[") Then
        TypeParentesi(0) = "["
        TypeParentesi(1) = "]"
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                                "Risolvo le parentesi quadre!" & "  "
        GoTo STEP_SELECT_SUBSTRING
      End If
      If StringCompare.Contains("{") Then
        TypeParentesi(0) = "{"
        TypeParentesi(1) = "}"
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                                "Risolvo le parentesi graffe!" & "  "
        GoTo STEP_SELECT_SUBSTRING
      End If

      SubText = StringCompare
      InterruptorDecision = True
      GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                              "Nessuna parentesi trovata!" & "  "
      GoTo STEP_GET_SUBSTRING

  STEP_SELECT_SUBSTRING:

      Interruptor = False
      CountText = StringCompare.Length

      For Increment = 0 To CountText
        Select Case Increment
          Case Is = 0
            If StringCompare.Chars(Increment) = TypeParentesi(0) Then
              Interruptor = True
              StartIndexText = Increment
            End If
            If Interruptor = True Then
              SubText = SubText & StringCompare.Chars(Increment)
            End If
          Case Is > 0
            If StringCompare.Chars(Increment - 1) = TypeParentesi(0) Then
              Interruptor = True
              StartIndexText = Increment
            End If
            If Interruptor = True Then
              SubText = SubText & StringCompare.Chars(Increment - 1)
            End If
            If StringCompare.Chars(Increment - 1) = TypeParentesi(1) Then
              Interruptor = False
              EndIndexText = Increment
              If Increment = CountText Then
              Else
                If StringCompare.Chars(Increment) = "^" Then
                  InterruptorEsponent = True
                  Increment = Increment + 2
                  For Increment2 = Increment To CountText
                    If StringCompare.Chars(Increment2 - 1) Like "#" Then
                      SubTextExponent = SubTextExponent & StringCompare.Chars(Increment2 - 1)
                    Else
                      Exit For
                    End If
                  Next
                End If
              End If
              Exit For
            End If
        End Select
      Next

      SubText = SubText.Remove(0, 1)
      SubText = SubText.Remove(SubText.Length - 1, 1)

      If SubText.Contains("(") Or SubText.Contains("[") Or SubText.Contains("{") Then
        SubText = SubText.Substring(1, SubText.Length - 1)
      End If

  STEP_GET_SUBSTRING:

      ResultExp = SubText
      GetValueLogResolveExp = GetValueLogResolveExp & "Espressione da risolvere = " & _
                              ResultExp & vbCrLf

  STEP00:

      If ResultExp.Contains("+-") Then
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
          "!!!!!   Esistono 2 segni contigui + - ! Sostituisco con segno - !" & vbCrLf & _
          "!!!!!   Spiegazione: + * -  =  -   !!!!!" & vbCrLf
        ResultExp = ResultExp.Replace("+-", "-")
        GoTo STEP00
      End If
      If ResultExp.Contains("--") Then
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
          "!!!!!   Esistono 2 segni contigui - -  ! Sostituisco con segno + !" & vbCrLf & _
          "!!!!!  Spiegazione:  -  *  -  =  +   !!!!!" & vbCrLf
        ResultExp = ResultExp.Replace("--", "+")
        GoTo STEP00
      End If

      CountText = ResultExp.Length

  STEP01:

      Increment1 = 0
      Dim TextValue(CountText) As String
      Dim SignValue(CountText) As String
      Dim ValueLong(CountText) As Decimal

      If ResultExp.Contains("-") Or ResultExp.Contains("+") Or ResultExp.Contains("*") _
        Or ResultExp.Contains("/") Or ResultExp.Contains("^") Then
        For Increment = 0 To CountText - 1
          Select Case Increment
            Case Is = 0
              If ResultExp.Chars(Increment) Like "#" Or ResultExp.Chars(Increment) = "," _
                Or ResultExp.Chars(Increment) = "-" Or ResultExp.Chars(Increment) = "v" Then
                TextValue(Increment1) = TextValue(Increment1) & ResultExp.Chars(Increment)
              Else
                SignValue(Increment1) = ResultExp.Chars(Increment)
                Increment1 = Increment1 + 1
              End If
            Case Is > 0
              If ResultExp.Chars(Increment) Like "#" Or ResultExp.Chars(Increment) = "," _
                Or ResultExp.Chars(Increment) = "v" Then
                TextValue(Increment1) = TextValue(Increment1) & ResultExp.Chars(Increment)
              Else
                If ResultExp.Chars(Increment) = "-" Then
                  If ResultExp.Chars(Increment - 1) = "+" _
                    Or ResultExp.Chars(Increment - 1) = "*" _
                    Or ResultExp.Chars(Increment - 1) = "/" _
                    Or ResultExp.Chars(Increment - 1) = "^" Then
                    TextValue(Increment1) = TextValue(Increment1) & ResultExp.Chars(Increment)
                  Else
                    SignValue(Increment1) = "+"
                    Increment1 = Increment1 + 1
                    TextValue(Increment1) = TextValue(Increment1) & ResultExp.Chars(Increment)
                  End If
                Else
                  SignValue(Increment1) = ResultExp.Chars(Increment)
                  Increment1 = Increment1 + 1
                End If
              End If
          End Select
        Next

        For Increment = 0 To Increment1
          If TextValue(Increment).Contains("v") Then
            GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
              "_____ Eseguo prima le radici quadrate! Numero sotto radice : " & _
              TextValue(Increment) & "  =>  " & TextValue(Increment) & " = "
            TextValue(Increment) = TextValue(Increment).Remove(0, 1)
            ValueLong(Increment) = CDec(TextValue(Increment))
            ValueLong(Increment) = System.Math.Sqrt(ValueLong(Increment))
            TextValue(Increment) = CStr(ValueLong(Increment))
            GetValueLogResolveExp = GetValueLogResolveExp & TextValue(Increment)
          End If
        Next
        For Increment = 0 To Increment1
          ValueLong(Increment) = CDec(TextValue(Increment))
        Next
      Else

  STEP_RADICE:

        If ResultExp.Contains("v") Then

          Dim ProvvisoryNumb As Decimal
          Dim ProvvisoryText As String

          If ResultExp.Contains("=") Then
            If ResultExp Like "v*" Then
              ProvvisoryText = ResultExp.Substring(0, ResultExp.IndexOf("="))
              ResultExp = ResultExp.Substring(ResultExp.IndexOf("="), _
              ResultExp.Length - ResultExp.IndexOf("="))
              ProvvisoryText = ProvvisoryText.Remove(0, 1)
              ProvvisoryNumb = CDec(ProvvisoryText)
              GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                "_____ Eseguo prima le radici quadrate! Numero sotto radice : v" & _
                ProvvisoryNumb & "  =>  " & "v" & ProvvisoryNumb & " =
                " & System.Math.Sqrt(ProvvisoryNumb)
              ProvvisoryNumb = System.Math.Sqrt(ProvvisoryNumb)
              ProvvisoryText = CStr(ProvvisoryNumb)
              ResultExp = ProvvisoryText & ResultExp
              ProvvisoryNumb = 0
              ProvvisoryText = ""
              GoTo STEP_RADICE
            Else
              ProvvisoryText = ResultExp.Substring(ResultExp.IndexOf("=") + 1, _
                ResultExp.Length - ResultExp.IndexOf("=") - 1)
              ResultExp = ResultExp.Substring(0, ResultExp.IndexOf("=") + 1)
              ProvvisoryText = ProvvisoryText.Remove(0, 1)
              ProvvisoryNumb = CDec(ProvvisoryText)
              GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                "_____ Eseguo prima le radici quadrate! Numero sotto radice : v" & _
                ProvvisoryNumb & "  =>  " & "v" & ProvvisoryNumb & " = " & _
                System.Math.Sqrt(ProvvisoryNumb)
              ProvvisoryNumb = System.Math.Sqrt(ProvvisoryNumb)
              ProvvisoryText = CStr(ProvvisoryNumb)
              ResultExp = ResultExp & ProvvisoryText
              ProvvisoryNumb = 0
              ProvvisoryText = ""
            End If
          Else
            ResultExp = ResultExp.Remove(0, 1)
            ProvvisoryNumb = CDec(System.Math.Sqrt(ResultExp))
            GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
              "_____ Eseguo prima le radici quadrate! Numero sotto radice : " & _
              ResultExp & "  =>  " & ResultExp & " = " & ProvvisoryNumb
            ResultExp = CStr(ProvvisoryNumb)
          End If
        End If
        GoTo STEP04
      End If

  STEP02:

      For Increment = 0 To
       Increment1 - 1
        If SignValue(Increment) = "^" Then
          If ValueLong(Increment) < 0 Then
            Select Case ValueLong(Increment + 1).ToString.Substring(ValueLong(Increment _
                        + 1).ToString.Length - 1, 1)
              Case Is = 1, 3, 5, 7, 9
                GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                  "_____ Eseguo prima le potenze : " & _
                  ValueLong(Increment) & "^" & ValueLong(Increment + 1) & _
                  " = " & ValueLong(Increment) ^ ValueLong(Increment + 1) & vbCrLf
                ValueLong(Increment) = ValueLong(Increment) ^ ValueLong(Increment + 1)
              Case Is = 2, 4, 6, 8, 0
                GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                  "_____ Eseguo prima le potenze : " & _
                  ValueLong(Increment) & "^" & ValueLong(Increment + 1) & _
                  " = " & ValueLong(Increment) ^ ValueLong(Increment + 1) & vbCrLf
                ValueLong(Increment) = ValueLong(Increment) ^ ValueLong(Increment + 1) * -1
            End Select
          Else
            GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
              "_____ Eseguo prima le potenze : " & _
              ValueLong(Increment) & "^" & ValueLong(Increment + 1) & _
              " = " & ValueLong(Increment) ^ ValueLong(Increment + 1) & vbCrLf
            ValueLong(Increment) = ValueLong(Increment) ^ ValueLong(Increment + 1)
          End If
          ValueLong(Increment) = System.Math.Round(ValueLong(Increment), 5)
          TextValue(Increment) = CStr(ValueLong(Increment))
          TextValue(Increment + 1) = ""
          SignValue(Increment) = ""
          GoTo STEP03
        End If
      Next
      For Increment = 0 To Increment1 - 1
        If SignValue(Increment) = "/" Then
          GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
            "_____ Eseguo prima le divisioni : " & _
            ValueLong(Increment) & "/" & ValueLong(Increment + 1) & _
            " = " & ValueLong(Increment) / ValueLong(Increment + 1) & vbCrLf
          ValueLong(Increment) = ValueLong(Increment) / ValueLong(Increment + 1)
          ValueLong(Increment) = System.Math.Round(ValueLong(Increment), 5)
          TextValue(Increment) = CStr(ValueLong(Increment))
          TextValue(Increment + 1) = ""
          SignValue(Increment) = ""
          GoTo STEP03
        End If
      Next
      For Increment = 0 To Increment1 - 1
        If SignValue(Increment) = "*" Then
          GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
            "_____ Eseguo prima le moltiplicazioni : " & _
            ValueLong(Increment) & "*" & ValueLong(Increment + 1) & _
            " = " & ValueLong(Increment) * ValueLong(Increment + 1) & vbCrLf
          ValueLong(Increment) = ValueLong(Increment) * ValueLong(Increment + 1)
          ValueLong(Increment) = System.Math.Round(ValueLong(Increment), 5)
          TextValue(Increment) = CStr(ValueLong(Increment))
          TextValue(Increment + 1) = ""
          SignValue(Increment) = ""
          GoTo STEP03
        End If
      Next
      For Increment = 0 To Increment1 - 1
        If SignValue(Increment) = "+" Then
          If ValueLong(Increment + 1) < 0 Then
            ValueLong(Increment + 1) = ValueLong(Increment + 1) * -1
            GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
              "_____ Eseguo prima le sottrazioni : " & _
              ValueLong(Increment) & "-" & ValueLong(Increment + 1) & _
              " = " & ValueLong(Increment) - ValueLong(Increment + 1) & vbCrLf
            ValueLong(Increment) = ValueLong(Increment) - ValueLong(Increment + 1)
            ValueLong(Increment) = System.Math.Round(ValueLong(Increment), 5)
            TextValue(Increment) = CStr(ValueLong(Increment))
            TextValue(Increment + 1) = ""
            SignValue(Increment) = ""
            GoTo STEP03
          Else
            GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
              "_____ Eseguo le addizioni : " & ValueLong(Increment) & _
              "+" & ValueLong(Increment + 1) & _
              " = " & ValueLong(Increment) + ValueLong(Increment + 1) & vbCrLf
            ValueLong(Increment) = ValueLong(Increment) + ValueLong(Increment + 1)
            ValueLong(Increment) = System.Math.Round(ValueLong(Increment), 5)
            TextValue(Increment) = CStr(ValueLong(Increment))
            TextValue(Increment + 1) = ""
            SignValue(Increment) = ""
            GoTo STEP03
          End If
        End If
      Next

  STEP03:

      ResultExp = ""

      For Increment = 0 To Increment1
        ResultExp = ResultExp & TextValue(Increment) & SignValue(Increment)
      Next
      For Increment = 0 To Increment1
        ValueLong(Increment) = 0
        TextValue(Increment) = ""
      Next
      For Increment = 0 To Increment1
        SignValue(Increment) = ""
      Next
      If Increment1 > 0 Then
        GetValueLogResolveExp = GetValueLogResolveExp & _ 
          "_____Risultato parziale = " & " " & ResultExp & vbCrLf
        GoTo STEP00
      Else
        GoTo STEP04
      End If

  STEP04:

      If InterruptorEsponent = True Then
        SubTextExponent = SubTextExponent.Substring(SubTextExponent.Length - 1, 1)
        Select Case SubTextExponent
          Case Is = 2, 4, 6, 8, 0
            If ResultExp.Contains("-") Then
              ResultExp = ResultExp.Substring(1, ResultExp.Length - 1)
              GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                "?????   Il valore parziale è stato modificato da : " & _
                "-" & ResultExp & " a " & ResultExp & vbCrLf & _
                "?????   Essendo un valore racchiuso tra parentesi e negativo " & _
                "ed avendo una potenza pari, il risultato è sempre positivo. " & _
                "Se la potenza è dispari il risultato è negativo!" & vbCrLf & _
                "?????   Esempio: { -1^2 = -1 * -1 = +1 (- * - = +) }, " & _
                "{ -1 ^ 3 = -1 * -1 * -1 = " & _
                "-1 (- * - * - = -) infatti - * - = + e + * - = - }, e così via!" & vbCrLf
            End If
        End Select
      End If
      If InterruptorDecision =
  True Then
        GoTo STEP05
      Else
        StringCompare = StringCompare.Remove(StartIndexText - 1, EndIndexText - StartIndexText + 1)
        StringCompare = StringCompare.Insert(StartIndexText - 1, ResultExp)
        GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & _
                                "Passaggio successivo = " & " " & StringCompare & vbCrLf
        TotalNumExp = TotalNumExp + 1
        GoTo STEP_CONTROLLER_STATUS_EXP
      End If

  STEP05:

      Increment = 0
      Increment1 = 0
      CountText = 0
      StartIndexText = 0
      EndIndexText = 0
      Interruptor = False
      InterruptorDecision = False
      InterruptorEsponent = False
      TypeParentesi(0) = ""
      TypeParentesi(1) = ""
      SubText = ""
      SubTextExponent = ""

      If ResultExp.Contains("=") Then
        CountText = ResultExp.Length
        For Increment = 0 
        To CountText - 1
          If ResultExp.Chars(Increment) = "=" Then
            StartIndexText = Increment
            Exit For
          End If
        Next
        If ResultExp.Substring(0, StartIndexText) <> ResultExp.Substring(StartIndexText + 1, _
           CountText - StartIndexText - 1)  Then
          MsgBox("Espressione non corretta! " & _
            "Il termine di uguaglianza non ha dato esito positivo!  " & _
            ResultExp.Substring(0, StartIndexText) & "  è diverso da  " & _
            ResultExp.Substring(StartIndexText + 1, CountText - StartIndexText - 1), _
            MsgBoxStyle.Exclamation, "Errore!")
          GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & vbCrLf & _
            "ERRORE!" & vbCrLf & vbCrLf & _
            "Espressione non corretta! " & _
            "Il termine di uguaglianza non ha dato esito positivo!" & _
            ResultExp.Substring(0, StartIndexText) & "  è diverso da  " & _
            ResultExp.Substring(StartIndexText + 1, CountText - StartIndexText - 1)
          Exit Function
        End If
      End If

      If ResultExp.Contains(",") Then
        SubText = ResultExp.Substring(ResultExp.IndexOf(",") + 1, _
                  ResultExp.Length - ResultExp.IndexOf(",") - 1)
        ProvvisoryNumbFinalize = CLng(SubText)
        If ProvvisoryNumbFinalize > 0 Then
        Else
          ResultExp = ResultExp.Substring(0, ResultExp.IndexOf(","))
        End If
        RekonExp = ResultExp
        ProvvisoryNumbFinalize = 0
        SubText = ""
      Else
        RekonExp = ResultExp
      End If
      GetValueLogResolveExp = GetValueLogResolveExp & vbCrLf & vbCrLf & _
        "Risultato finale= " & ResultExp & vbCrLf & vbCrLf
      Exit Function

  ERR:

      MsgBox("Divisione per zero o numero troppo grande! Impossibile continuare l'operazione!", _
        MsgBoxStyle.Critical, "Errore!")
      GetValueLogResolveExp = "ERRORE!" & vbCrLf & vbCrLf & _
        "Divisione per zero o numero troppo grande! Impossibile continuare l'operazione!"
      ProvvisoryNumbFinalize = 0
      Increment = 0
      Increment1 = 0
      CountText = 0
      StartIndexText = 0
      EndIndexText = 0
      Interruptor = False
      InterruptorDecision = False
      InterruptorEsponent = False
      TypeParentesi(0) = ""
      TypeParentesi(1) = ""
      SubText = ""
      SubTextExponent = ""

    End Function

  #Region " IDisposable Support "
    Private disposedValue As Boolean = False        ' Per rilevare chiamate ridondanti

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
      If Not Me.disposedValue Then
        If disposing Then
          ' TODO: liberare le risorse non gestite chiamate in modo esplicito
        End If

        ' TODO: liberare le risorse non gestite condivise
      End If
      Me.disposedValue = True
    End Sub

    ' Questo codice è aggiunto da Visual Basic per
    ' implementare in modo corretto il modello Disposable.
    Public Sub Dispose() Implements IDisposable.Dispose
      ' Non modificare questo codice. Inserire il codice di pulitura in 
      ' Dispose(ByVal disposing As Boolean).
      Dispose(True)
      GC.SuppressFinalize(Me)
    End Sub
  #End Region

  End Class