A generic conversion system that uses a single transformer rule and a callback to dynamically look up conversion factors stored in variables.
ID: 1355
using uCalcSoftware;
var uc = new uCalc();
static void ConvertUnits(uCalc.Callback cb) {
var value = cb.Arg(1);
var fromUnit = cb.ArgStr(2);
var toUnit = cb.ArgStr(3);
// Construct the variable names for direct and inverse factors
var factorName = fromUnit + "_to_" + toUnit;
var inverseFactorName = toUnit + "_to_" + fromUnit;
var uc_instance = cb.uCalc;
// Try to find the direct conversion factor
var factorItem = uc_instance.ItemOf(factorName);
if (factorItem.NotEmpty()) {
cb.Return(Math.Round(value * factorItem.Value(), 4));
return;
}
// If not found, try to find the inverse factor and use its reciprocal
var inverseFactorItem = uc_instance.ItemOf(inverseFactorName);
if (inverseFactorItem.NotEmpty()) {
cb.Return(value / inverseFactorItem.Value());
return;
}
// If no factor is found, raise an error
cb.Error.Raise("Conversion factor not found for " + fromUnit + " to " + toUnit);
}
// Define the conversion factors as variables
uc.DefineVariable("in_to_cm = 2.54");
uc.DefineVariable("km_to_miles = 0.621371");
// Define a custom function for temperature, since it's not a simple multiplication
uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0");
// Register our generic conversion callback
uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", ConvertUnits);
// Create generic rules in the expression transformer
var t = uc.ExpressionTransformer;
t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')");
// A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last)
t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})");
Console.WriteLine($"10 in to cm = {uc.Eval("10 in to cm")}");
Console.WriteLine($"100 km to miles = {uc.Eval("100 km to miles")}");
// Test the inverse conversion, which the callback handles automatically
Console.WriteLine($"254 cm to in = {uc.Eval("254 cm to in")}");
Console.WriteLine($"98.6 F to C = {uc.Eval("98.6 F to C")}");
10 in to cm = 25.4
100 km to miles = 62.1371
254 cm to in = 100
98.6 F to C = 37 using uCalcSoftware; var uc = new uCalc(); static void ConvertUnits(uCalc.Callback cb) { var value = cb.Arg(1); var fromUnit = cb.ArgStr(2); var toUnit = cb.ArgStr(3); // Construct the variable names for direct and inverse factors var factorName = fromUnit + "_to_" + toUnit; var inverseFactorName = toUnit + "_to_" + fromUnit; var uc_instance = cb.uCalc; // Try to find the direct conversion factor var factorItem = uc_instance.ItemOf(factorName); if (factorItem.NotEmpty()) { cb.Return(Math.Round(value * factorItem.Value(), 4)); return; } // If not found, try to find the inverse factor and use its reciprocal var inverseFactorItem = uc_instance.ItemOf(inverseFactorName); if (inverseFactorItem.NotEmpty()) { cb.Return(value / inverseFactorItem.Value()); return; } // If no factor is found, raise an error cb.Error.Raise("Conversion factor not found for " + fromUnit + " to " + toUnit); } // Define the conversion factors as variables uc.DefineVariable("in_to_cm = 2.54"); uc.DefineVariable("km_to_miles = 0.621371"); // Define a custom function for temperature, since it's not a simple multiplication uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0"); // Register our generic conversion callback uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", ConvertUnits); // Create generic rules in the expression transformer var t = uc.ExpressionTransformer; t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')"); // A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last) t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})"); Console.WriteLine($"10 in to cm = {uc.Eval("10 in to cm")}"); Console.WriteLine($"100 km to miles = {uc.Eval("100 km to miles")}"); // Test the inverse conversion, which the callback handles automatically Console.WriteLine($"254 cm to in = {uc.Eval("254 cm to in")}"); Console.WriteLine($"98.6 F to C = {uc.Eval("98.6 F to C")}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call ConvertUnits(uCalcBase::Callback cb) {
auto value = cb.Arg(1);
auto fromUnit = cb.ArgStr(2);
auto toUnit = cb.ArgStr(3);
// Construct the variable names for direct and inverse factors
auto factorName = fromUnit + "_to_" + toUnit;
auto inverseFactorName = toUnit + "_to_" + fromUnit;
auto uc_instance = cb.uCalc();
// Try to find the direct conversion factor
auto factorItem = uc_instance.ItemOf(factorName);
if (factorItem.NotEmpty()) {
cb.Return(value * factorItem.Value());
return;
}
// If not found, try to find the inverse factor and use its reciprocal
auto inverseFactorItem = uc_instance.ItemOf(inverseFactorName);
if (inverseFactorItem.NotEmpty()) {
cb.Return(value / inverseFactorItem.Value());
return;
}
// If no factor is found, raise an error
cb.Error().Raise("Conversion factor not found for " + fromUnit + " to " + toUnit);
}
int main() {
uCalc uc;
// Define the conversion factors as variables
uc.DefineVariable("in_to_cm = 2.54");
uc.DefineVariable("km_to_miles = 0.621371");
// Define a custom function for temperature, since it's not a simple multiplication
uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0");
// Register our generic conversion callback
uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", ConvertUnits);
// Create generic rules in the expression transformer
auto t = uc.ExpressionTransformer();
t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')");
// A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last)
t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})");
cout << "10 in to cm = " << uc.Eval("10 in to cm") << endl;
cout << "100 km to miles = " << uc.Eval("100 km to miles") << endl;
// Test the inverse conversion, which the callback handles automatically
cout << "254 cm to in = " << uc.Eval("254 cm to in") << endl;
cout << "98.6 F to C = " << uc.Eval("98.6 F to C") << endl;
}
10 in to cm = 25.4
100 km to miles = 62.1371
254 cm to in = 100
98.6 F to C = 37 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call ConvertUnits(uCalcBase::Callback cb) { auto value = cb.Arg(1); auto fromUnit = cb.ArgStr(2); auto toUnit = cb.ArgStr(3); // Construct the variable names for direct and inverse factors auto factorName = fromUnit + "_to_" + toUnit; auto inverseFactorName = toUnit + "_to_" + fromUnit; auto uc_instance = cb.uCalc(); // Try to find the direct conversion factor auto factorItem = uc_instance.ItemOf(factorName); if (factorItem.NotEmpty()) { cb.Return(value * factorItem.Value()); return; } // If not found, try to find the inverse factor and use its reciprocal auto inverseFactorItem = uc_instance.ItemOf(inverseFactorName); if (inverseFactorItem.NotEmpty()) { cb.Return(value / inverseFactorItem.Value()); return; } // If no factor is found, raise an error cb.Error().Raise("Conversion factor not found for " + fromUnit + " to " + toUnit); } int main() { uCalc uc; // Define the conversion factors as variables uc.DefineVariable("in_to_cm = 2.54"); uc.DefineVariable("km_to_miles = 0.621371"); // Define a custom function for temperature, since it's not a simple multiplication uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0"); // Register our generic conversion callback uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", ConvertUnits); // Create generic rules in the expression transformer auto t = uc.ExpressionTransformer(); t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')"); // A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last) t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})"); cout << "10 in to cm = " << uc.Eval("10 in to cm") << endl; cout << "100 km to miles = " << uc.Eval("100 km to miles") << endl; // Test the inverse conversion, which the callback handles automatically cout << "254 cm to in = " << uc.Eval("254 cm to in") << endl; cout << "98.6 F to C = " << uc.Eval("98.6 F to C") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub ConvertUnits(ByVal cb As uCalc.Callback)
Dim value = cb.Arg(1)
Dim fromUnit = cb.ArgStr(2)
Dim toUnit = cb.ArgStr(3)
'// Construct the variable names for direct and inverse factors
Dim factorName = fromUnit + "_to_" + toUnit
Dim inverseFactorName = toUnit + "_to_" + fromUnit
Dim uc_instance = cb.uCalc
'// Try to find the direct conversion factor
Dim factorItem = uc_instance.ItemOf(factorName)
If factorItem.NotEmpty() Then
cb.Return(Math.Round(value * factorItem.Value(), 4))
return
End If
'// If not found, try to find the inverse factor and use its reciprocal
Dim inverseFactorItem = uc_instance.ItemOf(inverseFactorName)
If inverseFactorItem.NotEmpty() Then
cb.Return(value / inverseFactorItem.Value())
return
End If
'// If no factor is found, raise an error
cb.Error.Raise("Conversion factor not found for " + fromUnit + " to " + toUnit)
End Sub
Public Sub Main()
Dim uc As New uCalc()
'// Define the conversion factors as variables
uc.DefineVariable("in_to_cm = 2.54")
uc.DefineVariable("km_to_miles = 0.621371")
'// Define a custom function for temperature, since it's not a simple multiplication
uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0")
'// Register our generic conversion callback
uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", AddressOf ConvertUnits)
'// Create generic rules in the expression transformer
Dim t = uc.ExpressionTransformer
t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')")
'// A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last)
t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})")
Console.WriteLine($"10 in to cm = {uc.Eval("10 in to cm")}")
Console.WriteLine($"100 km to miles = {uc.Eval("100 km to miles")}")
'// Test the inverse conversion, which the callback handles automatically
Console.WriteLine($"254 cm to in = {uc.Eval("254 cm to in")}")
Console.WriteLine($"98.6 F to C = {uc.Eval("98.6 F to C")}")
End Sub
End Module
10 in to cm = 25.4
100 km to miles = 62.1371
254 cm to in = 100
98.6 F to C = 37 Imports System Imports uCalcSoftware Public Module Program Public Sub ConvertUnits(ByVal cb As uCalc.Callback) Dim value = cb.Arg(1) Dim fromUnit = cb.ArgStr(2) Dim toUnit = cb.ArgStr(3) '// Construct the variable names for direct and inverse factors Dim factorName = fromUnit + "_to_" + toUnit Dim inverseFactorName = toUnit + "_to_" + fromUnit Dim uc_instance = cb.uCalc '// Try to find the direct conversion factor Dim factorItem = uc_instance.ItemOf(factorName) If factorItem.NotEmpty() Then cb.Return(Math.Round(value * factorItem.Value(), 4)) return End If '// If not found, try to find the inverse factor and use its reciprocal Dim inverseFactorItem = uc_instance.ItemOf(inverseFactorName) If inverseFactorItem.NotEmpty() Then cb.Return(value / inverseFactorItem.Value()) return End If '// If no factor is found, raise an error cb.Error.Raise("Conversion factor not found for " + fromUnit + " to " + toUnit) End Sub Public Sub Main() Dim uc As New uCalc() '// Define the conversion factors as variables uc.DefineVariable("in_to_cm = 2.54") uc.DefineVariable("km_to_miles = 0.621371") '// Define a custom function for temperature, since it's not a simple multiplication uc.DefineFunction("ConvertTempFToC(val) = (val - 32) * 5.0/9.0") '// Register our generic conversion callback uc.DefineFunction("Convert(val, fromUnit As String, toUnit As String)", AddressOf ConvertUnits) '// Create generic rules in the expression transformer Dim t = uc.ExpressionTransformer t.FromTo("{@Number:val} {@Alpha:from} to {@Alpha:to}", "Convert({val}, '{from}', '{to}')") '// A specific rule for Fahrenheit to Celsius since it's more complex (higher precedence because it's defined last) t.FromTo("{@Number:val} F to C", "ConvertTempFToC({val})") Console.WriteLine($"10 in to cm = {uc.Eval("10 in to cm")}") Console.WriteLine($"100 km to miles = {uc.Eval("100 km to miles")}") '// Test the inverse conversion, which the callback handles automatically Console.WriteLine($"254 cm to in = {uc.Eval("254 cm to in")}") Console.WriteLine($"98.6 F to C = {uc.Eval("98.6 F to C")}") End Sub End Module