#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; }