.NET Math Parser & Expression Evaluator (uCalc)
Embed a .NET Math Parser Across the CLR
uCalc is a high-performance expression parsing and token-aware text transformation engine built to run seamlessly on the .NET ecosystem. Going beyond simple math evaluation, uCalc enables enterprise applications to process dynamic formulas defined at runtime, build custom Domain-Specific Languages (DSLs), and safely restructure text.
Because the uCalc package operates as a standard .NET assembly, it provides native integration across CLI-compliant environments, including C#, VB.NET, F#, and PowerShell. uCalc is plug-and-play both on legacy .NET Standard 2.0 and modern .NET alike, with no dependencies. Just drop it in your app, and it's ready to go. It runs on Windows(32-bit, 64-bit, arm64 Copilot+PC), macOS (Intel x64, arm64 M-series), and Linux (x64, arm64).
Simplified syntax for evaluating an expression
ID: 1467
using uCalcSoftware;
var myExpr = new uCalc.Expression("5+4");
Console.WriteLine(myExpr);
myExpr = "10+20";
Console.WriteLine(myExpr);
9
30 using uCalcSoftware; var myExpr = new uCalc.Expression("5+4"); Console.WriteLine(myExpr); myExpr = "10+20"; Console.WriteLine(myExpr);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc::Expression myExpr("5+4");
cout << myExpr << endl;
myExpr = "10+20";
cout << myExpr << endl;
}
9
30 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc::Expression myExpr("5+4"); cout << myExpr << endl; myExpr = "10+20"; cout << myExpr << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim myExpr As New uCalc.Expression("5+4")
Console.WriteLine(myExpr)
myExpr = "10+20"
Console.WriteLine(myExpr)
End Sub
End Module
9
30 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim myExpr As New uCalc.Expression("5+4") Console.WriteLine(myExpr) myExpr = "10+20" Console.WriteLine(myExpr) End Sub End Module
Language-Specific Implementation
Whether you are architecting a modern C# cloud service, maintaining a legacy VB.NET enterprise application, or building PowerShell automation scripts, uCalc integrates naturally into your host environment.
C# Math Parser & Expression Evaluator: Explore idiomatic C# integration, lazy evaluation, robust sandboxing, and more.
VB.NET Expression Evaluator: See how uCalc brings dynamic, high-performance formula parsing to Visual Basic applications.
A minimal example defining a function inline to calculate the area of a rectangle.
ID: 296
using uCalcSoftware;
var uc = new uCalc();
uc.DefineVariable("x = 5");
uc.DefineFunction("Area(length, width) = length * width");
Console.WriteLine(uc.Eval("Area(4, x) + 7"));
27 using uCalcSoftware; var uc = new uCalc(); uc.DefineVariable("x = 5"); uc.DefineFunction("Area(length, width) = length * width"); Console.WriteLine(uc.Eval("Area(4, x) + 7"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineVariable("x = 5");
uc.DefineFunction("Area(length, width) = length * width");
cout << uc.Eval("Area(4, x) + 7") << endl;
}
27 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineVariable("x = 5"); uc.DefineFunction("Area(length, width) = length * width"); cout << uc.Eval("Area(4, x) + 7") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("x = 5")
uc.DefineFunction("Area(length, width) = length * width")
Console.WriteLine(uc.Eval("Area(4, x) + 7"))
End Sub
End Module
27 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("x = 5") uc.DefineFunction("Area(length, width) = length * width") Console.WriteLine(uc.Eval("Area(4, x) + 7")) End Sub End Module
Why Architects should Choose uCalc for .NET
Standard .NET workarounds like DataTable.Compute are slow, lack extensibility, and re-parse strings on every call. On the other end of the spectrum, compiling dynamic Roslyn scripts exposes applications to severe code-injection vulnerabilities. uCalc occupies the sweet spot: it delivers high performance through a Parse-Once, Evaluate-Many architecture while keeping execution strictly sandboxed.
Using the parse-evaluate pattern for high-performance calculations in a loop with a changing variable.
ID: 574
using uCalcSoftware;
var uc = new uCalc();
// Define a variable 'x' that will be updated in the loop.
var variableX = uc.DefineVariable("x");
// Parse the expression just once before the loop begins.
var parsedExpr = uc.Parse("x^2 * 10");
Console.WriteLine("Evaluating 'x^2 * 10' for x = 1 to 5:");
for (double x = 1; x <= 5; x++) {
variableX.Value(x);
// Evaluate is very fast as the parsing work is already done.
Console.WriteLine($"x = {x}, Result = {parsedExpr.Evaluate()}");
}
Evaluating 'x^2 * 10' for x = 1 to 5:
x = 1, Result = 10
x = 2, Result = 40
x = 3, Result = 90
x = 4, Result = 160
x = 5, Result = 250 using uCalcSoftware; var uc = new uCalc(); // Define a variable 'x' that will be updated in the loop. var variableX = uc.DefineVariable("x"); // Parse the expression just once before the loop begins. var parsedExpr = uc.Parse("x^2 * 10"); Console.WriteLine("Evaluating 'x^2 * 10' for x = 1 to 5:"); for (double x = 1; x <= 5; x++) { variableX.Value(x); // Evaluate is very fast as the parsing work is already done. Console.WriteLine($"x = {x}, Result = {parsedExpr.Evaluate()}"); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// Define a variable 'x' that will be updated in the loop.
auto variableX = uc.DefineVariable("x");
// Parse the expression just once before the loop begins.
auto parsedExpr = uc.Parse("x^2 * 10");
cout << "Evaluating 'x^2 * 10' for x = 1 to 5:" << endl;
for (double x = 1; x <= 5; x++) {
variableX.Value(x);
// Evaluate is very fast as the parsing work is already done.
cout << "x = " << x << ", Result = " << parsedExpr.Evaluate() << endl;
}
}
Evaluating 'x^2 * 10' for x = 1 to 5:
x = 1, Result = 10
x = 2, Result = 40
x = 3, Result = 90
x = 4, Result = 160
x = 5, Result = 250 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // Define a variable 'x' that will be updated in the loop. auto variableX = uc.DefineVariable("x"); // Parse the expression just once before the loop begins. auto parsedExpr = uc.Parse("x^2 * 10"); cout << "Evaluating 'x^2 * 10' for x = 1 to 5:" << endl; for (double x = 1; x <= 5; x++) { variableX.Value(x); // Evaluate is very fast as the parsing work is already done. cout << "x = " << x << ", Result = " << parsedExpr.Evaluate() << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// Define a variable 'x' that will be updated in the loop.
Dim variableX = uc.DefineVariable("x")
'// Parse the expression just once before the loop begins.
Dim parsedExpr = uc.Parse("x^2 * 10")
Console.WriteLine("Evaluating 'x^2 * 10' for x = 1 to 5:")
For x As Double = 1 To 5
variableX.Value(x)
'// Evaluate is very fast as the parsing work is already done.
Console.WriteLine($"x = {x}, Result = {parsedExpr.Evaluate()}")
Next
End Sub
End Module
Evaluating 'x^2 * 10' for x = 1 to 5:
x = 1, Result = 10
x = 2, Result = 40
x = 3, Result = 90
x = 4, Result = 160
x = 5, Result = 250 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// Define a variable 'x' that will be updated in the loop. Dim variableX = uc.DefineVariable("x") '// Parse the expression just once before the loop begins. Dim parsedExpr = uc.Parse("x^2 * 10") Console.WriteLine("Evaluating 'x^2 * 10' for x = 1 to 5:") For x As Double = 1 To 5 variableX.Value(x) '// Evaluate is very fast as the parsing work is already done. Console.WriteLine($"x = {x}, Result = {parsedExpr.Evaluate()}") Next End Sub End Module
1. Configurable Sandbox Security
Evaluating user-defined formulas—such as those from financial models, dynamic forms, or configuration files—demands strict security. Unlike dynamic code compilation tools that execute arbitrary C# IL, uCalc operates within an isolated instance. The host .NET application retains absolute control over which functions, operators, and variables are accessible, preventing untrusted scripts from escaping into system-level CLR operations.
2. State-Based, Exception-Free Error Handling
Traditional .NET evaluation engines rely on throwing heavy CLR exceptions (like DivideByZeroException or syntax errors) when evaluating invalid user input. In highly interactive applications, catching exceptions at every turn causes severe performance degradation and stack unwinding. uCalc uses a lightweight, state-based error model, returning formatted diagnostic strings natively without throwing exceptions. uCalc also supports advanced error handling.
3. Token-Aware Text Transformation
Standard .NET System.Text.RegularExpressions is powerful but struggles with nested structures and code manipulation because it treats everything as a flat stream of characters. The uCalc SDK integrates a structural Transformer that operates on lexical tokens. It intrinsically understands strings, nested brackets, and user-configurable structures, making it highly robust for parsing logs, transpiling code, or restructuring text. Mathematical logic can even be executed directly inside string replacements using the {@Eval} directive.
4. Advanced Custom Functions and Operators
uCalc lets you define infix, prefix, and postfix operators and configure associativity and precedence levels. Users can define their own functions and operators at runtime, or you can link them to callback functions in the host application. Functions can be variadic (accepting an indefinite number of arguments), overloaded, and have optional parameters. Function definitions support overwriting, shadowing, bootstrapping, and recursion. Functions support lazy evaluation, with arguments passed ByExpr, and arguments passed ByHandle to allow introspection.
5. Runtime Dynamic Grammar
In statically compiled .NET languages, syntax is locked at compile time. uCalc brings dynamic grammar to the CLR. Developers can define custom syntax constructs using the Transformer.
6. Extensive Documentation with tons of interactive examples online
uCalc has extensive documentation online. It includes tutorials, guides, hands-on projects, and references, plus a very large number of examples you can quickly try interactively right on the website without downloading anything. If you're not sure where to start, you can go directly to the Ask uCalc AI chatbot and tell it what you're trying to do, and it will show you how to do it with uCalc and point you to the right documentation pages where you can find further information.
A practical example that calculates line-item totals for a list of products by capturing quantity and price.
ID: 1218
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// Rule to find quantity and price, then calculate total.
// Note the explicit Double() to convert the captured numerical
// values as text into double-precision numbers for {@Eval}.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}");
var invoice = """
Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50
""";
Console.WriteLine(t.Transform(invoice));
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15 using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // Rule to find quantity and price, then calculate total. // Note the explicit Double() to convert the captured numerical // values as text into double-precision numbers for {@Eval}. t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}", "{@Self}, Total: {@Eval: Double(qty) * Double(price)}"); var invoice = """ Item: Book, Qty: 3, Price: 15.00 Item: Pen, Qty: 10, Price: 1.50 """; Console.WriteLine(t.Transform(invoice));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// Rule to find quantity and price, then calculate total.
// Note the explicit Double() to convert the captured numerical
// values as text into double-precision numbers for {@Eval}.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}");
auto invoice = R"(Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50)";
cout << t.Transform(invoice) << endl;
}
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // Rule to find quantity and price, then calculate total. // Note the explicit Double() to convert the captured numerical // values as text into double-precision numbers for {@Eval}. t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}", "{@Self}, Total: {@Eval: Double(qty) * Double(price)}"); auto invoice = R"(Item: Book, Qty: 3, Price: 15.00 Item: Pen, Qty: 10, Price: 1.50)"; cout << t.Transform(invoice) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// Rule to find quantity and price, then calculate total.
'// Note the explicit Double() to convert the captured numerical
'// values as text into double-precision numbers for {@Eval}.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}")
Dim invoice = "Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50"
Console.WriteLine(t.Transform(invoice))
End Sub
End Module
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// Rule to find quantity and price, then calculate total. '// Note the explicit Double() to convert the captured numerical '// values as text into double-precision numbers for {@Eval}. t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}", "{@Self}, Total: {@Eval: Double(qty) * Double(price)}") Dim invoice = "Item: Book, Qty: 3, Price: 15.00 Item: Pen, Qty: 10, Price: 1.50" Console.WriteLine(t.Transform(invoice)) End Sub End Module
Passing arg ByExpr (delayed lazy eval) and ByHandle
ID: 14
using uCalcSoftware;
var uc = new uCalc();
static void MySum(uCalc.Callback cb) {
var Total = 0.0;
var Expr = cb.ArgExpr(1);
var Start = cb.Arg(2);
var Finish = cb.Arg(3);
var Variable = cb.ArgItem(4);
for (double x = Start; x <= Finish; x++) {
Variable.Value(x);
Total += Expr.Evaluate();
}
cb.Return(Total);
}
uc.DefineVariable("x");
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum);
Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"));
385 using uCalcSoftware; var uc = new uCalc(); static void MySum(uCalc.Callback cb) { var Total = 0.0; var Expr = cb.ArgExpr(1); var Start = cb.Arg(2); var Finish = cb.Arg(3); var Variable = cb.ArgItem(4); for (double x = Start; x <= Finish; x++) { Variable.Value(x); Total += Expr.Evaluate(); } cb.Return(Total); } uc.DefineVariable("x"); uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum); Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call MySum(uCalcBase::Callback cb) {
auto Total = 0.0;
auto Expr = cb.ArgExpr(1);
auto Start = cb.Arg(2);
auto Finish = cb.Arg(3);
auto Variable = cb.ArgItem(4);
for (double x = Start; x <= Finish; x++) {
Variable.Value(x);
Total += Expr.Evaluate();
}
cb.Return(Total);
}
int main() {
uCalc uc;
uc.DefineVariable("x");
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum);
cout << uc.Eval("Sum(x ^ 2, 1, 10, x)") << endl;
}
385 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call MySum(uCalcBase::Callback cb) { auto Total = 0.0; auto Expr = cb.ArgExpr(1); auto Start = cb.Arg(2); auto Finish = cb.Arg(3); auto Variable = cb.ArgItem(4); for (double x = Start; x <= Finish; x++) { Variable.Value(x); Total += Expr.Evaluate(); } cb.Return(Total); } int main() { uCalc uc; uc.DefineVariable("x"); uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum); cout << uc.Eval("Sum(x ^ 2, 1, 10, x)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub MySum(ByVal cb As uCalc.Callback)
Dim Total = 0.0
Dim Expr = cb.ArgExpr(1)
Dim Start = cb.Arg(2)
Dim Finish = cb.Arg(3)
Dim Variable = cb.ArgItem(4)
For x As Double = Start To Finish
Variable.Value(x)
Total += Expr.Evaluate()
Next
cb.Return(Total)
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("x")
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", AddressOf MySum)
Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"))
End Sub
End Module
385 Imports System Imports uCalcSoftware Public Module Program Public Sub MySum(ByVal cb As uCalc.Callback) Dim Total = 0.0 Dim Expr = cb.ArgExpr(1) Dim Start = cb.Arg(2) Dim Finish = cb.Arg(3) Dim Variable = cb.ArgItem(4) For x As Double = Start To Finish Variable.Value(x) Total += Expr.Evaluate() Next cb.Return(Total) End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("x") uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", AddressOf MySum) Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)")) End Sub End Module