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.
RewindOnChange = [bool]
Property
Product:
Class:
Controls whether the transformer re-scans text from the beginning of a match after a replacement, enabling recursive or cascading transformations.
Remarks
🔄 Recursive Transformations with RewindOnChange
The RewindOnChange property controls the Transformer's behavior after it successfully applies a rule. It allows you to create powerful recursive or cascading transformations that would otherwise require complex, multi-pass logic.
false(Default): After a replacement, the Transformer continues scanning from the position after the newly inserted text. It will not re-evaluate the text that was just modified.true: After a replacement, the Transformer "rewinds" its cursor to the start of the original match location and re-scans the text. This allows other rules—or even the same rule—to find new matches within the just-transformed text.
🎯 Core Use Case: Recursive and Cascading Rules
This property is the key to creating rules that expand recursively. A common use case is implementing variadic functions in a pre-processing step. Consider a pattern to expand Add(1, 2, 3) into (1 + (2 + 3)).
// Without Rewind, only the first match is found.var t = new uCalc.Transformer();t.FromTo("Add({x}, {y})", "({x} + Add({y}))");Console.WriteLine(t.Transform("Add(1,2,3)"));// Output: (1 + Add(2,3)) - The inner Add(2,3) is not expanded.// With Rewind, the expansion continues until no matches are left.t.Reset();t.FromTo("Add({x}, {y})", "({x} + Add({y}))").RewindOnChange = true;Console.WriteLine(t.Transform("Add(1,2,3)"));// Output: (1 + (2 + 3))This works because after the first transform, the string becomes (1 + Add(2,3)). The rewind causes the parser to re-scan this, find Add(2,3), and apply the rule again.
⚠️ Infinite Loop Warning
Use @RewindOnChange with caution. If your rules can transform text in a cyclical manner, you will create an infinite loop.
Example of an Infinite Loop:
var t = new uCalc.Transformer();t.FromTo("A", "B").SetRewindOnChange(true);t.FromTo("B", "A").SetRewindOnChange(true);// This will cause an infinite loop: A -> B -> A -> B ...// t.Transform("A"); To prevent this, ensure your transformation rules are always reducing the input towards a final, non-matching state, or use a Maximum match count to terminate the process.
💡 Why uCalc? (Comparative Analysis)
In a traditional regex-based workflow, achieving a recursive transformation requires manual, imperative code:
// Manual approach without uCalcstring text = "Add(1,2,3)";while (text.Contains("Add(")) { text = Regex.Replace(text, "Add\\((.*?),(.*)\\)", "($1 + Add($2))");}This approach is slow, brittle, and mixes transformation logic with control flow. uCalc's @RewindOnChange(true) is declarative. You simply state your intent on the rule, and the engine handles the complex looping and re-scanning logic internally in a highly optimized manner.
Per-Rule vs. Global Setting
You can set this property on an individual Rule for granular control, or you can set it on the Transformer.DefaultRuleSet to have it apply to all subsequently defined rules in that transformer.
Examples
A succinct example demonstrating the cascading effect of enabling `RewindOnChange`.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// Rule 1: Replace 'A' with 'B'. Rewind is off by default.
t.FromTo("A", "B");
// Rule 2: Replace 'B' with 'C'.
t.FromTo("B", "C");
Console.WriteLine("--- Rewind Disabled ---");
// The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered.
Console.WriteLine(t.Transform("Start A End"));
t.Reset();
// Now, enable rewind on the first rule.
t.FromTo("A", "B").RewindOnChange = true;
t.FromTo("B", "C");
Console.WriteLine("");
Console.WriteLine("--- Rewind Enabled ---");
// The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'.
Console.WriteLine(t.Transform("Start A End"));
--- Rewind Disabled ---
Start B End
--- Rewind Enabled ---
Start C End using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // Rule 1: Replace 'A' with 'B'. Rewind is off by default. t.FromTo("A", "B"); // Rule 2: Replace 'B' with 'C'. t.FromTo("B", "C"); Console.WriteLine("--- Rewind Disabled ---"); // The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered. Console.WriteLine(t.Transform("Start A End")); t.Reset(); // Now, enable rewind on the first rule. t.FromTo("A", "B").RewindOnChange = true; t.FromTo("B", "C"); Console.WriteLine(""); Console.WriteLine("--- Rewind Enabled ---"); // The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'. Console.WriteLine(t.Transform("Start A End"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// Rule 1: Replace 'A' with 'B'. Rewind is off by default.
t.FromTo("A", "B");
// Rule 2: Replace 'B' with 'C'.
t.FromTo("B", "C");
cout << "--- Rewind Disabled ---" << endl;
// The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered.
cout << t.Transform("Start A End") << endl;
t.Reset();
// Now, enable rewind on the first rule.
t.FromTo("A", "B").RewindOnChange(true);
t.FromTo("B", "C");
cout << "" << endl;
cout << "--- Rewind Enabled ---" << endl;
// The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'.
cout << t.Transform("Start A End") << endl;
}
--- Rewind Disabled ---
Start B End
--- Rewind Enabled ---
Start C End #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // Rule 1: Replace 'A' with 'B'. Rewind is off by default. t.FromTo("A", "B"); // Rule 2: Replace 'B' with 'C'. t.FromTo("B", "C"); cout << "--- Rewind Disabled ---" << endl; // The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered. cout << t.Transform("Start A End") << endl; t.Reset(); // Now, enable rewind on the first rule. t.FromTo("A", "B").RewindOnChange(true); t.FromTo("B", "C"); cout << "" << endl; cout << "--- Rewind Enabled ---" << endl; // The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'. cout << t.Transform("Start A End") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// Rule 1: Replace 'A' with 'B'. Rewind is off by default.
t.FromTo("A", "B")
'// Rule 2: Replace 'B' with 'C'.
t.FromTo("B", "C")
Console.WriteLine("--- Rewind Disabled ---")
'// The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered.
Console.WriteLine(t.Transform("Start A End"))
t.Reset()
'// Now, enable rewind on the first rule.
t.FromTo("A", "B").RewindOnChange = true
t.FromTo("B", "C")
Console.WriteLine("")
Console.WriteLine("--- Rewind Enabled ---")
'// The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'.
Console.WriteLine(t.Transform("Start A End"))
End Sub
End Module
--- Rewind Disabled ---
Start B End
--- Rewind Enabled ---
Start C End Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// Rule 1: Replace 'A' with 'B'. Rewind is off by default. t.FromTo("A", "B") '// Rule 2: Replace 'B' with 'C'. t.FromTo("B", "C") Console.WriteLine("--- Rewind Disabled ---") '// The 'A' becomes 'B', but the scan continues *after* the 'B', so rule 2 is not triggered. Console.WriteLine(t.Transform("Start A End")) t.Reset() '// Now, enable rewind on the first rule. t.FromTo("A", "B").RewindOnChange = true t.FromTo("B", "C") Console.WriteLine("") Console.WriteLine("--- Rewind Enabled ---") '// The 'A' becomes 'B', rewind occurs, the 'B' is re-scanned and becomes 'C'. Console.WriteLine(t.Transform("Start A End")) End Sub End Module
Demonstrates using `RewindOnChange` to create a recursive `AddUp` function within the expression transformer.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate()
var p1 = t.FromTo("AddUp({x})", "{x}"); // Base case
var p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); // Recursive step
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}");
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}");
Console.WriteLine("");
Console.WriteLine($"Input: AddUp(1,2,3,4)");
Console.WriteLine($"Transform: {t.Transform("AddUp(1,2,3,4)")}");
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 using uCalcSoftware; var uc = new uCalc(); var t = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate() var p1 = t.FromTo("AddUp({x})", "{x}"); // Base case var p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); // Recursive step Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}"); Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}"); Console.WriteLine(""); Console.WriteLine($"Input: AddUp(1,2,3,4)"); Console.WriteLine($"Transform: {t.Transform("AddUp(1,2,3,4)")}"); Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
#define tf(IsTrue) ((IsTrue) ? "True" : "False")
int main() {
uCalc uc;
auto t = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate()
auto p1 = t.FromTo("AddUp({x})", "{x}"); // Base case
auto p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); // Recursive step
cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl;
cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl;
cout << "" << endl;
cout << "Input: " << "AddUp(1,2,3,4)" << endl;
cout << "Transform: " << t.Transform("AddUp(1,2,3,4)") << endl;
cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl;
}
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; #define tf(IsTrue) ((IsTrue) ? "True" : "False") int main() { uCalc uc; auto t = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate() auto p1 = t.FromTo("AddUp({x})", "{x}"); // Base case auto p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); // Recursive step cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl; cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl; cout << "" << endl; cout << "Input: " << "AddUp(1,2,3,4)" << endl; cout << "Transform: " << t.Transform("AddUp(1,2,3,4)") << endl; cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate()
Dim p1 = t.FromTo("AddUp({x})", "{x}") '// Base case
Dim p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true) '// Recursive step
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}")
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}")
Console.WriteLine("")
Console.WriteLine($"Input: AddUp(1,2,3,4)")
Console.WriteLine($"Transform: {t.Transform("AddUp(1,2,3,4)")}")
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}")
End Sub
End Module
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate() Dim p1 = t.FromTo("AddUp({x})", "{x}") '// Base case Dim p2 = t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true) '// Recursive step Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}") Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}") Console.WriteLine("") Console.WriteLine($"Input: AddUp(1,2,3,4)") Console.WriteLine($"Transform: {t.Transform("AddUp(1,2,3,4)")}") Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}") End Sub End Module
Applies `RewindOnChange` to a default rule set to enable complex, multi-rule transformations for a custom `Average` function.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.ExpressionTransformer;
// Enable rewind for all subsequent rules in this transformer.
t.DefaultRuleSet.SetRewindOnChange(true);
// Define the recursive rules.
t.FromTo("AddUp({x})", "{x}");
t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");
t.FromTo("ArgCount({x})", "1");
t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");
// The main rule that combines the others.
t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");
var expression = "Average(1, 2, 3, 4)";
Console.WriteLine($"Input: {expression}");
Console.WriteLine($"Transform: {t.Transform(expression)}");
Console.WriteLine($"Eval: {uc.Eval(expression)}");
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 using uCalcSoftware; var uc = new uCalc(); var t = uc.ExpressionTransformer; // Enable rewind for all subsequent rules in this transformer. t.DefaultRuleSet.SetRewindOnChange(true); // Define the recursive rules. t.FromTo("AddUp({x})", "{x}"); t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))"); t.FromTo("ArgCount({x})", "1"); t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))"); // The main rule that combines the others. t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})"); var expression = "Average(1, 2, 3, 4)"; Console.WriteLine($"Input: {expression}"); Console.WriteLine($"Transform: {t.Transform(expression)}"); Console.WriteLine($"Eval: {uc.Eval(expression)}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.ExpressionTransformer();
// Enable rewind for all subsequent rules in this transformer.
t.DefaultRuleSet().SetRewindOnChange(true);
// Define the recursive rules.
t.FromTo("AddUp({x})", "{x}");
t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");
t.FromTo("ArgCount({x})", "1");
t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");
// The main rule that combines the others.
t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");
auto expression = "Average(1, 2, 3, 4)";
cout << "Input: " << expression << endl;
cout << "Transform: " << t.Transform(expression) << endl;
cout << "Eval: " << uc.Eval(expression) << endl;
}
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.ExpressionTransformer(); // Enable rewind for all subsequent rules in this transformer. t.DefaultRuleSet().SetRewindOnChange(true); // Define the recursive rules. t.FromTo("AddUp({x})", "{x}"); t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))"); t.FromTo("ArgCount({x})", "1"); t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))"); // The main rule that combines the others. t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})"); auto expression = "Average(1, 2, 3, 4)"; cout << "Input: " << expression << endl; cout << "Transform: " << t.Transform(expression) << endl; cout << "Eval: " << uc.Eval(expression) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.ExpressionTransformer
'// Enable rewind for all subsequent rules in this transformer.
t.DefaultRuleSet.SetRewindOnChange(true)
'// Define the recursive rules.
t.FromTo("AddUp({x})", "{x}")
t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))")
t.FromTo("ArgCount({x})", "1")
t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))")
'// The main rule that combines the others.
t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})")
Dim expression = "Average(1, 2, 3, 4)"
Console.WriteLine($"Input: {expression}")
Console.WriteLine($"Transform: {t.Transform(expression)}")
Console.WriteLine($"Eval: {uc.Eval(expression)}")
End Sub
End Module
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.ExpressionTransformer '// Enable rewind for all subsequent rules in this transformer. t.DefaultRuleSet.SetRewindOnChange(true) '// Define the recursive rules. t.FromTo("AddUp({x})", "{x}") t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))") t.FromTo("ArgCount({x})", "1") t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))") '// The main rule that combines the others. t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})") Dim expression = "Average(1, 2, 3, 4)" Console.WriteLine($"Input: {expression}") Console.WriteLine($"Transform: {t.Transform(expression)}") Console.WriteLine($"Eval: {uc.Eval(expression)}") End Sub End Module
Using ExpressionTransformer to transform expressions before they are parsed
using uCalcSoftware;
var uc = new uCalc();
var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate()
var p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default
var p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true);
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}");
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}");
Console.WriteLine("");
Console.WriteLine($"Input: AddUp(1,2,3,4)");
Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}");
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 using uCalcSoftware; var uc = new uCalc(); var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate() var p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default var p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}"); Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}"); Console.WriteLine(""); Console.WriteLine($"Input: AddUp(1,2,3,4)"); Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}"); Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
#define tf(IsTrue) ((IsTrue) ? "True" : "False")
int main() {
uCalc uc;
auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate()
auto p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default
auto p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true);
cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl;
cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl;
cout << "" << endl;
cout << "Input: " << "AddUp(1,2,3,4)" << endl;
cout << "Transform: " << ExprT.Transform("AddUp(1,2,3,4)") << endl;
cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl;
}
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; #define tf(IsTrue) ((IsTrue) ? "True" : "False") int main() { uCalc uc; auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate() auto p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default auto p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl; cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl; cout << "" << endl; cout << "Input: " << "AddUp(1,2,3,4)" << endl; cout << "Transform: " << ExprT.Transform("AddUp(1,2,3,4)") << endl; cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate()
Dim p1 = ExprT.FromTo("AddUp({x})", "{x}") '// RewindOnChange False by default
Dim p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true)
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}")
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}")
Console.WriteLine("")
Console.WriteLine($"Input: AddUp(1,2,3,4)")
Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}")
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}")
End Sub
End Module
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate() Dim p1 = ExprT.FromTo("AddUp({x})", "{x}") '// RewindOnChange False by default Dim p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true) Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}") Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}") Console.WriteLine("") Console.WriteLine($"Input: AddUp(1,2,3,4)") Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}") Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}") End Sub End Module
RewindOnChange
using uCalcSoftware;
var uc = new uCalc();
var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate()
ExprT.DefaultRuleSet.RewindOnChange = true;
ExprT.FromTo("AddUp({x})", "{x}");
ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");
ExprT.FromTo("ArgCount({x})", "1");
ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");
ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");
var Expression = "Average(1, 2, 3, 4)";
Console.WriteLine($"Input: {Expression}");
Console.WriteLine($"Transform: {ExprT.Transform(Expression)}");
Console.WriteLine($"Eval: {uc.Eval(Expression)}");
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 using uCalcSoftware; var uc = new uCalc(); var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate() ExprT.DefaultRuleSet.RewindOnChange = true; ExprT.FromTo("AddUp({x})", "{x}"); ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))"); ExprT.FromTo("ArgCount({x})", "1"); ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))"); ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})"); var Expression = "Average(1, 2, 3, 4)"; Console.WriteLine($"Input: {Expression}"); Console.WriteLine($"Transform: {ExprT.Transform(Expression)}"); Console.WriteLine($"Eval: {uc.Eval(Expression)}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate()
ExprT.DefaultRuleSet().RewindOnChange(true);
ExprT.FromTo("AddUp({x})", "{x}");
ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");
ExprT.FromTo("ArgCount({x})", "1");
ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");
ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");
auto Expression = "Average(1, 2, 3, 4)";
cout << "Input: " << Expression << endl;
cout << "Transform: " << ExprT.Transform(Expression) << endl;
cout << "Eval: " << uc.Eval(Expression) << endl;
}
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate() ExprT.DefaultRuleSet().RewindOnChange(true); ExprT.FromTo("AddUp({x})", "{x}"); ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))"); ExprT.FromTo("ArgCount({x})", "1"); ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))"); ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})"); auto Expression = "Average(1, 2, 3, 4)"; cout << "Input: " << Expression << endl; cout << "Transform: " << ExprT.Transform(Expression) << endl; cout << "Eval: " << uc.Eval(Expression) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate()
ExprT.DefaultRuleSet.RewindOnChange = true
ExprT.FromTo("AddUp({x})", "{x}")
ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))")
ExprT.FromTo("ArgCount({x})", "1")
ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))")
ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})")
Dim Expression = "Average(1, 2, 3, 4)"
Console.WriteLine($"Input: {Expression}")
Console.WriteLine($"Transform: {ExprT.Transform(Expression)}")
Console.WriteLine($"Eval: {uc.Eval(Expression)}")
End Sub
End Module
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate() ExprT.DefaultRuleSet.RewindOnChange = true ExprT.FromTo("AddUp({x})", "{x}") ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))") ExprT.FromTo("ArgCount({x})", "1") ExprT.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))") ExprT.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})") Dim Expression = "Average(1, 2, 3, 4)" Console.WriteLine($"Input: {Expression}") Console.WriteLine($"Transform: {ExprT.Transform(Expression)}") Console.WriteLine($"Eval: {uc.Eval(Expression)}") End Sub End Module