uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Project: An Advanced Find-and-Replace Utility
Product:
Class:
A step-by-step project to build an advanced, token-aware find-and-replace utility for code refactoring using the uCalc Transformer.
Remarks
💡 Project: An Advanced Find-and-Replace Utility
This project will guide you through building a powerful, command-line-style find-and-replace utility. Unlike basic text replacement, this tool will be structurally aware, making it safe for refactoring source code. It's a perfect real-world example of why the token-aware uCalc.Transformer is superior to Regular Expressions for manipulating structured text.
The Goal
We'll create a tool that can intelligently rename a function or variable in a code snippet, correctly ignoring occurrences of the name inside comments and string literals.
The Problem with Naive Find-and-Replace
A standard text editor's find-and-replace is character-based and 'blind' to context. If you try to rename the function GetUserData to FetchUserProfile, a naive tool would corrupt the code by changing the name inside comments and strings where it shouldn't.
Input Code:
// Deprecated: Use FetchUserProfile instead of GetUserDatafunction GetUserData(id) { print("Calling GetUserData is not recommended."); return http.get("/users/" + id);}var user = GetUserData(123);Incorrect Naive Result:
// Deprecated: Use FetchUserProfile instead of FetchUserProfilefunction FetchUserProfile(id) { print("Calling FetchUserProfile is not recommended."); return http.get("/users/" + id);}var user = FetchUserProfile(123);This project will show you how to do it correctly with uCalc.
Step 1: The Basic Replacement Rule
The core of our tool is a Transformer with a simple FromTo rule.
var t = new uCalc.Transformer();t.FromTo("GetUserData", "FetchUserProfile");Step 2: Handling "Whole Word" Matching (The Token Advantage)
How do we prevent renaming GetUserData from breaking a variable named GetUserData_Fast? With Regex, you'd need word boundaries (\b). With uCalc, this is automatic. The tokenizer identifies GetUserData and GetUserData_Fast as two distinct alphanumeric tokens. The rule for GetUserData will not match the other one.
Step 3: Ignoring Comments with SkipOver
This is where uCalc's power becomes clear. To prevent the tool from changing text inside comments, we don't need complex lookarounds. We simply tell the transformer to treat comments as "dead zones" using SkipOver.
// These rules run before any FromTo rules, protecting the content.t.SkipOver("// {text}");t.SkipOver("/* {text} */");Step 4: Ignoring Strings (Built-in Safety)
How do we protect the text inside print("...")? We don't have to do anything! By default, all rules are QuoteSensitive, meaning the tokenizer treats a quoted string as a single, atomic unit. The FromTo rule will not even look inside it.
Putting It All Together
The practical example below combines these concepts into a complete, working refactoring tool. It correctly transforms the code, demonstrating the safety and power of a token-aware approach.
Examples
A succinct example showing a basic, token-aware variable rename.
using uCalcSoftware;
var uc = new uCalc();
using (var t = new uCalc.Transformer()) {
// This rule will only match the standalone token 'rate', not 'exchange_rate'.
t.FromTo("rate", "interestRate");
var code = "var exchange_rate = 0.5; var rate = 0.1;";
Console.WriteLine(t.Transform(code));
}
var exchange_rate = 0.5; var interestRate = 0.1; using uCalcSoftware; var uc = new uCalc(); using (var t = new uCalc.Transformer()) { // This rule will only match the standalone token 'rate', not 'exchange_rate'. t.FromTo("rate", "interestRate"); var code = "var exchange_rate = 0.5; var rate = 0.1;"; Console.WriteLine(t.Transform(code)); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
{
uCalc::Transformer t;
t.Owned(); // Causes t to be released when it goes out of scope
// This rule will only match the standalone token 'rate', not 'exchange_rate'.
t.FromTo("rate", "interestRate");
auto code = "var exchange_rate = 0.5; var rate = 0.1;";
cout << t.Transform(code) << endl;
}
}
var exchange_rate = 0.5; var interestRate = 0.1; #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; { uCalc::Transformer t; t.Owned(); // Causes t to be released when it goes out of scope // This rule will only match the standalone token 'rate', not 'exchange_rate'. t.FromTo("rate", "interestRate"); auto code = "var exchange_rate = 0.5; var rate = 0.1;"; cout << t.Transform(code) << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Using t As New uCalc.Transformer()
'// This rule will only match the standalone token 'rate', not 'exchange_rate'.
t.FromTo("rate", "interestRate")
Dim code = "var exchange_rate = 0.5; var rate = 0.1;"
Console.WriteLine(t.Transform(code))
End Using
End Sub
End Module
var exchange_rate = 0.5; var interestRate = 0.1; Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Using t As New uCalc.Transformer() '// This rule will only match the standalone token 'rate', not 'exchange_rate'. t.FromTo("rate", "interestRate") Dim code = "var exchange_rate = 0.5; var rate = 0.1;" Console.WriteLine(t.Transform(code)) End Using End Sub End Module
A practical implementation of the code refactoring utility, safely renaming a function while ignoring occurrences in comments and strings.
using uCalcSoftware;
var uc = new uCalc();
// Simulate user inputs for the tool
var findText = "GetUserData";
var replaceText = "FetchUserProfile";
var sourceCode = """
// Deprecated: Use FetchUserProfile instead of GetUserData
function GetUserData(id) {
print("Calling GetUserData is not recommended.");
return http.get("/users/" + id);
}
var user = GetUserData(123);
""";
using (var refactorTool = new uCalc.Transformer()) {
// 1. Define rules to ignore comments. These have the highest precedence.
refactorTool.SkipOver("// {text}");
refactorTool.SkipOver("/* {text} */");
// 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings.
var rule = refactorTool.FromTo(findText, replaceText);
// 3. Run the transformation and print the result.
Console.WriteLine(refactorTool.Transform(sourceCode));
}
// Deprecated: Use FetchUserProfile instead of GetUserData
function FetchUserProfile(id) {
print("Calling GetUserData is not recommended.");
return http.get("/users/" + id);
}
var user = FetchUserProfile(123);
using uCalcSoftware; var uc = new uCalc(); // Simulate user inputs for the tool var findText = "GetUserData"; var replaceText = "FetchUserProfile"; var sourceCode = """ // Deprecated: Use FetchUserProfile instead of GetUserData function GetUserData(id) { print("Calling GetUserData is not recommended."); return http.get("/users/" + id); } var user = GetUserData(123); """; using (var refactorTool = new uCalc.Transformer()) { // 1. Define rules to ignore comments. These have the highest precedence. refactorTool.SkipOver("// {text}"); refactorTool.SkipOver("/* {text} */"); // 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings. var rule = refactorTool.FromTo(findText, replaceText); // 3. Run the transformation and print the result. Console.WriteLine(refactorTool.Transform(sourceCode)); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// Simulate user inputs for the tool
auto findText = "GetUserData";
auto replaceText = "FetchUserProfile";
auto sourceCode = R"(
// Deprecated: Use FetchUserProfile instead of GetUserData
function GetUserData(id) {
print("Calling GetUserData is not recommended.");
return http.get("/users/" + id);
}
var user = GetUserData(123);
)";
{
uCalc::Transformer refactorTool;
refactorTool.Owned(); // Causes refactorTool to be released when it goes out of scope
// 1. Define rules to ignore comments. These have the highest precedence.
refactorTool.SkipOver("// {text}");
refactorTool.SkipOver("/* {text} */");
// 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings.
auto rule = refactorTool.FromTo(findText, replaceText);
// 3. Run the transformation and print the result.
cout << refactorTool.Transform(sourceCode) << endl;
}
}
// Deprecated: Use FetchUserProfile instead of GetUserData
function FetchUserProfile(id) {
print("Calling GetUserData is not recommended.");
return http.get("/users/" + id);
}
var user = FetchUserProfile(123);
#include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // Simulate user inputs for the tool auto findText = "GetUserData"; auto replaceText = "FetchUserProfile"; auto sourceCode = R"( // Deprecated: Use FetchUserProfile instead of GetUserData function GetUserData(id) { print("Calling GetUserData is not recommended."); return http.get("/users/" + id); } var user = GetUserData(123); )"; { uCalc::Transformer refactorTool; refactorTool.Owned(); // Causes refactorTool to be released when it goes out of scope // 1. Define rules to ignore comments. These have the highest precedence. refactorTool.SkipOver("// {text}"); refactorTool.SkipOver("/* {text} */"); // 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings. auto rule = refactorTool.FromTo(findText, replaceText); // 3. Run the transformation and print the result. cout << refactorTool.Transform(sourceCode) << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// Simulate user inputs for the tool
Dim findText = "GetUserData"
Dim replaceText = "FetchUserProfile"
Dim sourceCode = "
// Deprecated: Use FetchUserProfile instead of GetUserData
function GetUserData(id) {
print(""Calling GetUserData is not recommended."");
return http.get(""/users/"" + id);
}
var user = GetUserData(123);
"
Using refactorTool As New uCalc.Transformer()
'// 1. Define rules to ignore comments. These have the highest precedence.
refactorTool.SkipOver("// {text}")
refactorTool.SkipOver("/* {text} */")
'// 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings.
Dim rule = refactorTool.FromTo(findText, replaceText)
'// 3. Run the transformation and print the result.
Console.WriteLine(refactorTool.Transform(sourceCode))
End Using
End Sub
End Module
// Deprecated: Use FetchUserProfile instead of GetUserData
function FetchUserProfile(id) {
print("Calling GetUserData is not recommended.");
return http.get("/users/" + id);
}
var user = FetchUserProfile(123);
Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// Simulate user inputs for the tool Dim findText = "GetUserData" Dim replaceText = "FetchUserProfile" Dim sourceCode = " // Deprecated: Use FetchUserProfile instead of GetUserData function GetUserData(id) { print(""Calling GetUserData is not recommended.""); return http.get(""/users/"" + id); } var user = GetUserData(123); " Using refactorTool As New uCalc.Transformer() '// 1. Define rules to ignore comments. These have the highest precedence. refactorTool.SkipOver("// {text}") refactorTool.SkipOver("/* {text} */") '// 2. Define the replacement rule. QuoteSensitive is true by default, protecting strings. Dim rule = refactorTool.FromTo(findText, replaceText) '// 3. Run the transformation and print the result. Console.WriteLine(refactorTool.Transform(sourceCode)) End Using End Sub End Module