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")}");