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 project to build an advanced, token-aware find-and-replace utility for code refactoring using the uCalc Transformer.
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.
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.
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.
The core of our tool is a Transformer with a simple FromTo rule.
csharp
var t = new uCalc.Transformer();
t.FromTo("GetUserData", "FetchUserProfile");
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.
SkipOverThis 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.
## 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 TogetherThe 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.ID: 1401
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
ID: 1402
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