Click here to Skip to main content
15,886,545 members
Articles / Programming Languages / C#

A Calculation Engine for .NET

Rate me:
Please Sign up or sign in to vote.
4.92/5 (183 votes)
1 Sep 2013Public Domain15 min read 650.6K   11.4K   421  
A calculation engine that is small, fast, and extensible.
Friend Class [Text]

    ' Methods
    Public Shared Sub Register(ByVal ce As CalcEngine)
        ce.RegisterFunction("CHAR", 1, New CalcEngineFunction(AddressOf Text._Char))
        ce.RegisterFunction("CODE", 1, New CalcEngineFunction(AddressOf Text.Code))
        ce.RegisterFunction("CONCATENATE", 1, &H7FFFFFFF, New CalcEngineFunction(AddressOf Text.Concat))
        ce.RegisterFunction("FIND", 2, 3, New CalcEngineFunction(AddressOf Text.Find))
        ce.RegisterFunction("LEFT", 1, 2, New CalcEngineFunction(AddressOf Text.Left))
        ce.RegisterFunction("LEN", 1, New CalcEngineFunction(AddressOf Text.Len))
        ce.RegisterFunction("LOWER", 1, New CalcEngineFunction(AddressOf Text.Lower))
        ce.RegisterFunction("MID", 3, New CalcEngineFunction(AddressOf Text.Mid))
        ce.RegisterFunction("PROPER", 1, New CalcEngineFunction(AddressOf Text.Proper))
        ce.RegisterFunction("REPLACE", 4, New CalcEngineFunction(AddressOf Text.Replace))
        ce.RegisterFunction("REPT", 2, New CalcEngineFunction(AddressOf Text.Rept))
        ce.RegisterFunction("RIGHT", 1, 2, New CalcEngineFunction(AddressOf Text.Right))
        ce.RegisterFunction("SEARCH", 2, New CalcEngineFunction(AddressOf Text.Search))
        ce.RegisterFunction("SUBSTITUTE", 3, 4, New CalcEngineFunction(AddressOf Text.Substitute))
        ce.RegisterFunction("T", 1, New CalcEngineFunction(AddressOf Text.T))
        ce.RegisterFunction("TEXT", 2, New CalcEngineFunction(AddressOf Text._Text))
        ce.RegisterFunction("TRIM", 1, New CalcEngineFunction(AddressOf Text.Trim))
        ce.RegisterFunction("UPPER", 1, New CalcEngineFunction(AddressOf Text.Upper))
        ce.RegisterFunction("VALUE", 1, New CalcEngineFunction(AddressOf Text.Value))
    End Sub

    Private Shared Function _Char(ByVal p As List(Of Expression)) As Object
        Dim c As Char = Microsoft.VisualBasic.ChrW(CInt(p.Item(0)))
        Return c.ToString
    End Function

    Private Shared Function _Text(ByVal p As List(Of Expression)) As Object
        Dim dbl As Double = CDbl(p.Item(0))
        Return dbl.ToString(p.Item(1), System.Globalization.CultureInfo.InvariantCulture)
    End Function

    Private Shared Function Code(ByVal p As List(Of Expression)) As Object
        Dim s As String = CStr(p.Item(0))
        Return Microsoft.VisualBasic.Val(s.Chars(0))
    End Function

    Private Shared Function Concat(ByVal p As List(Of Expression)) As Object
        Dim sb As New System.Text.StringBuilder
        Dim x As Expression
        For Each x In p
            sb.Append(CStr(x))
        Next
        Return sb.ToString
    End Function

    Private Shared Function Find(ByVal p As List(Of Expression)) As Object
        Return Text.IndexOf(p, StringComparison.Ordinal)
    End Function

    Private Shared Function IndexOf(ByVal p As List(Of Expression), ByVal cmp As StringComparison) As Integer
        Dim srch As String = p.Item(0)
        Dim text As String = p.Item(1)
        Dim start As Integer = 0
        If (p.Count > 2) Then
            start = (CInt(p.Item(2)) - 1)
        End If
        Dim index As Integer = [text].IndexOf(srch, start, cmp)
        Return IIf((index > -1), (index + 1), index)
    End Function

    Private Shared Function Left(ByVal p As List(Of Expression)) As Object
        Dim n As Integer = 1
        If (p.Count > 1) Then
            n = CInt(p.Item(1))
        End If
        Return CStr(p.Item(0)).Substring(0, n)
    End Function

    Private Shared Function Len(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0)).Length
    End Function

    Private Shared Function Lower(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0)).ToLower
    End Function

    Private Shared Function Mid(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0)).Substring((CInt(p.Item(1)) - 1), CInt(p.Item(2)))
    End Function

    Private Shared Function Proper(ByVal p As List(Of Expression)) As Object
        Dim s As String = p.Item(0)
        Return (s.Substring(0, 1).ToUpper & s.Substring(1).ToLower)
    End Function

    Private Shared Function Replace(ByVal p As List(Of Expression)) As Object
        Dim s As String = p.Item(0)
        Dim start As Integer = (CInt(p.Item(1)) - 1)
        Dim len As Integer = CInt(p.Item(2))
        Dim rep As String = p.Item(3)
        Dim sb As New System.Text.StringBuilder
        sb.Append(s.Substring(0, start))
        sb.Append(rep)
        sb.Append(s.Substring((start + len)))
        Return sb.ToString
    End Function

    Private Shared Function Rept(ByVal p As List(Of Expression)) As Object
        Dim sb As New System.Text.StringBuilder
        Dim s As String = p.Item(0)
        Dim i As Integer
        For i = 0 To CInt(p.Item(1)) - 1
            sb.Append(s)
        Next i
        Return sb.ToString
    End Function

    Private Shared Function Right(ByVal p As List(Of Expression)) As Object
        Dim n As Integer = 1
        If (p.Count > 1) Then
            n = CInt(p.Item(1))
        End If
        Dim s As String = p.Item(0)
        Return s.Substring((s.Length - n))
    End Function

    Private Shared Function Search(ByVal p As List(Of Expression)) As Object
        Return Text.IndexOf(p, StringComparison.OrdinalIgnoreCase)
    End Function

    Private Shared Function Substitute(ByVal p As List(Of Expression)) As Object
        Dim text As String = p.Item(0)
        Dim oldText As String = p.Item(1)
        Dim newText As String = p.Item(2)
        If (p.Count = 3) Then
            Return [text].Replace(oldText, newText)
        End If
        Dim index As Integer = CInt(p.Item(3))
        If (index < 1) Then
            Throw New Exception("Invalid index in Substitute.")
        End If
        Dim pos As Integer = [text].IndexOf(oldText)
        Do While ((pos > -1) AndAlso (index > 1))
            pos = [text].IndexOf(oldText, CInt((pos + 1)))
            index -= 1
        Loop
        Return IIf((pos > -1), ([text].Substring(0, pos) & newText & [text].Substring((pos + oldText.Length))), [text])
    End Function

    Private Shared Function T(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0))
    End Function

    Private Shared Function Trim(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0)).Trim
    End Function

    Private Shared Function Upper(ByVal p As List(Of Expression)) As Object
        Return CStr(p.Item(0)).ToUpper
    End Function

    Private Shared Function Value(ByVal p As List(Of Expression)) As Object
        Return Double.Parse(p.Item(0), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture)
    End Function

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Software Developer
Brazil Brazil
Software Architect/Developer with several years experience creating and delivering software.

Full-stack Web development (including React, Firebase, TypeScript, HTML, CSS), Entity Framework, C#, MS SQL Server.

Passionate about new technologies and always keen to learn new things as well as improve on existing skills.

Comments and Discussions