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;
				
					#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;
   }
}
				
			
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
				
			
var exchange_rate = 0.5; var interestRate = 0.1;
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);
				
					#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;
   }
}
				
			

// 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
				
			

// Deprecated: Use FetchUserProfile instead of GetUserData
function FetchUserProfile(id) {
    print("Calling GetUserData is not recommended.");
    return http.get("/users/" + id);
}
var user = FetchUserProfile(123);