uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026
Warning
uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.
A step-by-step guide to building a rule engine that can parse and evaluate complex boolean logic using uCalc's built-in operators and custom DSLs.
This project demonstrates how to use uCalc to build a powerful engine for parsing and evaluating complex boolean logic expressions. This is a common requirement for applications like business rule engines, access control systems, search query parsers, and data validation frameworks.
We want to evaluate logical statements provided as strings at runtime, using a context of variables. Our engine should correctly handle:
==, >, <, >=, <=, <>AND, OR, NOT() to control the order of operations.A typical expression might look like this:"(status == 'Active' AND login_attempts < 3) OR is_admin == true"
Building a boolean logic parser from scratch is a significant undertaking. You would need to implement a lexer, a parser that understands operator precedence (e.g., AND before OR), and an evaluation engine.
uCalc provides all of this functionality out of the box:
The simplest way to evaluate a boolean expression is to define your variables and then pass the expression string directly to EvalStr(). uCalc's default grammar will handle the rest.
The "Succinct" example below demonstrates this direct approach.
For a more user-friendly or domain-specific syntax, you can use the ExpressionTransformer to transpile custom keywords into standard uCalc expressions before they are evaluated.
Let's say we want to support a more natural language syntax:
IS instead of ==IS NOT instead of <>CONTAINS for string searchingWe can define simple FromTo rules to map this custom syntax to uCalc's built-in operators and functions. This creates a powerful abstraction layer, making the rules easier for non-programmers to write and understand.
The "Practical" example demonstrates this technique.
In either approach, the boolean expression is evaluated against a set of variables. These variables represent the "facts" or the current state of the system. You define them using DefineVariable() before evaluating the expression.
csharp
// Define the data context for our rule engine
uc.DefineVariable("status = 'Active'");
uc.DefineVariable("login_attempts = 2");
uc.DefineVariable("is_admin = false");
When the expression is evaluated, uCalc will look up these variable names and use their current values in the calculation.
Let's see the complete implementations.
ID: 1391
using uCalcSoftware;
var uc = new uCalc();
uc.DefineVariable("status = 'Active'");
uc.DefineVariable("login_attempts = 2");
uc.DefineVariable("is_admin = false");
var rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true";
Console.WriteLine($"Evaluating rule: {rule}");
Console.Write("Result: ");
Console.WriteLine(uc.EvalStr(rule));
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true using uCalcSoftware; var uc = new uCalc(); uc.DefineVariable("status = 'Active'"); uc.DefineVariable("login_attempts = 2"); uc.DefineVariable("is_admin = false"); var rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"; Console.WriteLine($"Evaluating rule: {rule}"); Console.Write("Result: "); Console.WriteLine(uc.EvalStr(rule));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineVariable("status = 'Active'");
uc.DefineVariable("login_attempts = 2");
uc.DefineVariable("is_admin = false");
auto rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true";
cout << "Evaluating rule: " << rule << endl;
cout << "Result: ";
cout << uc.EvalStr(rule) << endl;
}
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineVariable("status = 'Active'"); uc.DefineVariable("login_attempts = 2"); uc.DefineVariable("is_admin = false"); auto rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"; cout << "Evaluating rule: " << rule << endl; cout << "Result: "; cout << uc.EvalStr(rule) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("status = 'Active'")
uc.DefineVariable("login_attempts = 2")
uc.DefineVariable("is_admin = false")
Dim rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"
Console.WriteLine($"Evaluating rule: {rule}")
Console.Write("Result: ")
Console.WriteLine(uc.EvalStr(rule))
End Sub
End Module
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("status = 'Active'") uc.DefineVariable("login_attempts = 2") uc.DefineVariable("is_admin = false") Dim rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true" Console.WriteLine($"Evaluating rule: {rule}") Console.Write("Result: ") Console.WriteLine(uc.EvalStr(rule)) End Sub End Module