Imports System
Imports System.Collections.Generic
Imports Microsoft.VisualBasic
Imports System.Collections
Imports System.Text.RegularExpressions
' The 'text' parameter will contain the text from the:
' - Current Clipboard when run by HotKey
' - History Item when run from the History Menu
' The returned String will be:
' - Placed directly on the Clipboard
' - Ignored by ClipboardFusion if it is 'Nothing'
Public Class ClipboardFusionHelper
Public Shared Function ProcessText(text As String) As String
Dim pattern As String = "\[[^\[\]]*\]"
Dim replacement As String = ""
Dim rgx As Regex = New Regex(pattern)
Dim result As String = rgx.Replace(text, replacement)
Return calculateValue(result)
End Function
Public Shared Function calculateValue(text As String) As String
Dim pattern As String = "[0-9\.+-/*()()= ]+"
Dim rgx As Regex = New Regex(pattern)
Dim match As Boolean = rgx.IsMatch(text)
Dim mt As MatchCollection = rgx.Matches(text)
If(Not match) Then
Return "The expression contains illegal characters!"
End If
Dim count As Integer = 0
For Each m In mt
count= count+1
Next m
If(count>1) Then
Return "The expression contains illegal characters!"
End If
Dim opt_stk As Stack = New Stack()
Dim num_stk As Stack = New Stack()
Dim sb_temp As String = ""
Dim items = text.ToCharArray
For i = 0 To text.Length-1
Dim c = items(i)
If (c <> " ") Then
If ((c >= "0" And c <= "9") Or c = "." Or (c="-" And sb_temp.Length =0)) Then
sb_temp = sb_temp + c
Else
If (sb_temp.Length >0) Then
Dim temp_value As Double
temp_value = sb_temp
num_stk.push(temp_value)
sb_temp = ""
End If
Dim curOpt As String = c
If (opt_stk.Count = 0) Then
opt_stk.Push(curOpt)
Else
If (curOpt.Equals("(")) Then
opt_stk.Push(curOpt)
ElseIf (curOpt.Equals(")")) Then
directCalc(opt_stk, num_stk, True)
ElseIf (curOpt.Equals("="))
directCalc(opt_stk, num_stk, False)
Return Math.Round(num_stk.Pop,3)
Else
compareAndCalc(opt_stk, num_stk, curOpt)
End If
End If
End If
End If
Next
If (sb_temp.Length>0) Then
Dim temp_value As Double
temp_value = sb_temp
num_stk.push(temp_value)
End If
directCalc(opt_stk, num_stk, False)
Return Math.Round(num_stk.Pop,3)
End Function
Public Shared Function directCalc(optStack As Stack, numStack As Stack, isBracket As Boolean)
Dim opt As String = optStack.Pop
Dim num2 As Double = numStack.Pop
Dim num1 As Double = numStack.Pop
Dim result As Double = floatingPointCalc(opt, num1, num2)
numStack.Push(result)
If (isBracket) Then
If (optStack.Peek.Equals("(")) Then
optStack.Pop
Else
directCalc(optStack, numStack, isBracket)
End If
Else
If (optStack.Count>0) Then
directCalc(optStack, numStack, isBracket)
End If
End If
End Function
Public Shared Function compareAndCalc(optStack As Stack, numStack As Stack, curOpt As String) As Double
Dim peekOpt = optStack.Peek
Dim priority = getPriority(peekOpt, curOpt)
If (priority = -1 Or priority = 0) Then
Dim opt As String = optStack.Pop
Dim num2 As Double = numStack.Pop
Dim num1 As Double = numStack.Pop
Dim result As Double = floatingPointCalc(opt, num1, num2)
numStack.Push(result)
If (optStack.Count = 0) Then
optStack.Push(curOpt)
Else
compareAndCalc(optStack, numStack, curOpt)
End If
Else
optStack.Push(curOpt)
End If
End Function
Public Shared Function getPriority(opt1 As String, opt2 As String) As Integer
Dim map As SortedList = New SortedList()
map.Add("(", 0)
map.Add("+", 2)
map.Add("-", 2)
map.Add("*", 3)
map.Add("/", 3)
map.Add(")", 7)
map.Add("=", 20)
Dim index1 = map.IndexOfKey(opt1)
Dim value1 = map.GetByIndex(index1)
Dim index2 = map.IndexOfKey(opt2)
Dim value2 = map.GetByIndex(index2)
Return value2 - value1
End Function
Public Shared Function floatingPointCalc(opt As String, val1 As Double, val2 As Double) As Double
Dim result As Double
If (opt.Equals("+")) Then
result = val1 + val2
End If
If (opt.Equals("-")) Then
result = val1 - val2
End If
If (opt.Equals("*")) Then
result = val1 * val2
End If
If (opt.Equals("/")) Then
result = val1 / val2
End If
Return result
End Function
End Class