uCalc API Version: 2.1.3-preview.2 Released: 6/17/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.
DefineFunction
Method
Product:
Class:
Registers a user-defined function for use in expressions, supporting inline definitions, external callbacks, and advanced features like overloading and recursion.
Syntax
Parameters
Return
Item
An [Item] object representing the newly defined function, which can be used for later modification or release.
Remarks
The DefineFunction method is a cornerstone of uCalc, allowing you to create custom functions for use in expressions. You can define functions in two primary ways:
- Inline Definition: Provide the entire function signature and logic as a single string.
- Callback Binding: Provide a function signature and link it to a native C#, C++, or VB function in your host application.
This flexibility makes it ideal for everything from simple user-defined helpers to complex integrations with existing code.
📖 Function Syntax
A function definition string follows this pattern:
FunctionName(param1, param2, ...) As ReturnType = expression
- Parameters: A comma-separated list of parameter names. You can optionally assign a data type to a parameter by following it with
As [typename]. Parentheses()are required even for functions with no parameters. - Return Type: Optional. If omitted, uCalc attempts to infer it. If it can't, it uses the instance's DefaultDataType.
- Expression: The logic to be executed when the function is called.
⚙️ Core Features
| Feature | Description |
|---|---|
| Overloading | Define multiple functions with the same name but different parameter types or counts. uCalc selects the correct one at runtime based on the arguments provided. |
| Optional Parameters | Specify default values for parameters, e.g., MyFunc(x, y = 5). |
| Variadic Functions | Create functions that accept a variable number of arguments using the ... syntax, e.g., Average(x ...) |
| Recursion | Functions can call themselves, enabling classic recursive algorithms like factorial or Fibonacci. |
| Shadowing vs. Overwriting | By default, a new definition shadows an old one; existing expressions still use the old version. Setting overwrite: true replaces the old definition everywhere, enabling powerful spreadsheet-like reactive updates. |
| Bootstrapping | Setting bootstrap: true lets you redefine a function by calling the original version within its new definition, which is perfect for extending or wrapping built-in functions without causing a recursive loop. |
🔗 Argument Passing Modifiers
uCalc extends standard argument passing with powerful custom modifiers that provide deep introspection and control.
| Modifier | Description |
|---|---|
ByVal | (Default) Passes the evaluated result of the argument. |
ByRef | Passes a reference to a variable, allowing the function to modify its value. |
ByHandle | Passes the argument's underlying Item object. This allows the callback to inspect metadata like the argument's name, data type, or original expression text. |
ByExpr | Passes the argument as an unevaluated Expression object. This enables powerful lazy-evaluation and short-circuiting logic, as seen in the built-in IIf function. |
💡 Comparative Analysis
vs. Compiled Languages (C#/C++): The primary advantage is dynamism. Functions can be defined at runtime from user input, configuration files, or database entries without requiring recompilation. This is fundamental for applications like report generators, scripting environments, and scientific modelers.
vs. Other Scripting Engines (Lua, Python): While full scripting engines are more powerful, they are also much heavier. uCalc is a lightweight, specialized component. Its key differentiators are:
ByExprandByHandle: These provide metaprogramming capabilities that are often complex or impossible to achieve in other embedded script engines.OverwriteFlag: This built-in feature for creating reactive dependencies is a unique and powerful concept that simplifies building spreadsheet-like applications, a task that would require significant manual dependency tracking in other systems.
📋 Retrieving Defined Functions
You can get a list of all currently defined functions using uc.ListOfItems(ItemIs.Function).
Examples
A minimal example defining a function inline to calculate the area of a rectangle.
using uCalcSoftware;
var uc = new uCalc();
uc.DefineFunction("Area(length, width) = length * width");
Console.WriteLine(uc.Eval("Area(4, 5)"));
20 using uCalcSoftware; var uc = new uCalc(); uc.DefineFunction("Area(length, width) = length * width"); Console.WriteLine(uc.Eval("Area(4, 5)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineFunction("Area(length, width) = length * width");
cout << uc.Eval("Area(4, 5)") << endl;
}
20 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineFunction("Area(length, width) = length * width"); cout << uc.Eval("Area(4, 5)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("Area(length, width) = length * width")
Console.WriteLine(uc.Eval("Area(4, 5)"))
End Sub
End Module
20 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("Area(length, width) = length * width") Console.WriteLine(uc.Eval("Area(4, 5)")) End Sub End Module
Demonstrates defining a function that is implemented by a native callback in the host application.
using uCalcSoftware;
var uc = new uCalc();
static void MyAreaCallback(uCalc.Callback cb) {
var length = cb.Arg(1);
var width = cb.Arg(2);
cb.Return(length * width);
}
// The signature is defined, but the logic is provided by 'MyAreaCallback'.
uc.DefineFunction("Area(x, y)", MyAreaCallback);
Console.WriteLine(uc.Eval("Area(3, 4)"));
12 using uCalcSoftware; var uc = new uCalc(); static void MyAreaCallback(uCalc.Callback cb) { var length = cb.Arg(1); var width = cb.Arg(2); cb.Return(length * width); } // The signature is defined, but the logic is provided by 'MyAreaCallback'. uc.DefineFunction("Area(x, y)", MyAreaCallback); Console.WriteLine(uc.Eval("Area(3, 4)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call MyAreaCallback(uCalcBase::Callback cb) {
auto length = cb.Arg(1);
auto width = cb.Arg(2);
cb.Return(length * width);
}
int main() {
uCalc uc;
// The signature is defined, but the logic is provided by 'MyAreaCallback'.
uc.DefineFunction("Area(x, y)", MyAreaCallback);
cout << uc.Eval("Area(3, 4)") << endl;
}
12 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call MyAreaCallback(uCalcBase::Callback cb) { auto length = cb.Arg(1); auto width = cb.Arg(2); cb.Return(length * width); } int main() { uCalc uc; // The signature is defined, but the logic is provided by 'MyAreaCallback'. uc.DefineFunction("Area(x, y)", MyAreaCallback); cout << uc.Eval("Area(3, 4)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub MyAreaCallback(ByVal cb As uCalc.Callback)
Dim length = cb.Arg(1)
Dim width = cb.Arg(2)
cb.Return(length * width)
End Sub
Public Sub Main()
Dim uc As New uCalc()
'// The signature is defined, but the logic is provided by 'MyAreaCallback'.
uc.DefineFunction("Area(x, y)", AddressOf MyAreaCallback)
Console.WriteLine(uc.Eval("Area(3, 4)"))
End Sub
End Module
12 Imports System Imports uCalcSoftware Public Module Program Public Sub MyAreaCallback(ByVal cb As uCalc.Callback) Dim length = cb.Arg(1) Dim width = cb.Arg(2) cb.Return(length * width) End Sub Public Sub Main() Dim uc As New uCalc() '// The signature is defined, but the logic is provided by 'MyAreaCallback'. uc.DefineFunction("Area(x, y)", AddressOf MyAreaCallback) Console.WriteLine(uc.Eval("Area(3, 4)")) End Sub End Module
Shows how to create overloaded functions that uCalc distinguishes based on parameter count and type.
using uCalcSoftware;
var uc = new uCalc();
// Overload for two numbers
uc.DefineFunction("Combine(x, y) = x + y");
// Overload for two strings
uc.DefineFunction("Combine(x As String, y As String) As String = x + y");
// Overload for three numbers
uc.DefineFunction("Combine(x, y, z) = x + y + z");
Console.WriteLine($"Two numbers: {uc.EvalStr("Combine(5, 10)")}");
Console.WriteLine($"Two strings: {uc.EvalStr("Combine('Hello, ', 'World!')")}");
Console.WriteLine($"Three numbers: {uc.EvalStr("Combine(5, 10, 20)")}");
Two numbers: 15
Two strings: Hello, World!
Three numbers: 35 using uCalcSoftware; var uc = new uCalc(); // Overload for two numbers uc.DefineFunction("Combine(x, y) = x + y"); // Overload for two strings uc.DefineFunction("Combine(x As String, y As String) As String = x + y"); // Overload for three numbers uc.DefineFunction("Combine(x, y, z) = x + y + z"); Console.WriteLine($"Two numbers: {uc.EvalStr("Combine(5, 10)")}"); Console.WriteLine($"Two strings: {uc.EvalStr("Combine('Hello, ', 'World!')")}"); Console.WriteLine($"Three numbers: {uc.EvalStr("Combine(5, 10, 20)")}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// Overload for two numbers
uc.DefineFunction("Combine(x, y) = x + y");
// Overload for two strings
uc.DefineFunction("Combine(x As String, y As String) As String = x + y");
// Overload for three numbers
uc.DefineFunction("Combine(x, y, z) = x + y + z");
cout << "Two numbers: " << uc.EvalStr("Combine(5, 10)") << endl;
cout << "Two strings: " << uc.EvalStr("Combine('Hello, ', 'World!')") << endl;
cout << "Three numbers: " << uc.EvalStr("Combine(5, 10, 20)") << endl;
}
Two numbers: 15
Two strings: Hello, World!
Three numbers: 35 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // Overload for two numbers uc.DefineFunction("Combine(x, y) = x + y"); // Overload for two strings uc.DefineFunction("Combine(x As String, y As String) As String = x + y"); // Overload for three numbers uc.DefineFunction("Combine(x, y, z) = x + y + z"); cout << "Two numbers: " << uc.EvalStr("Combine(5, 10)") << endl; cout << "Two strings: " << uc.EvalStr("Combine('Hello, ', 'World!')") << endl; cout << "Three numbers: " << uc.EvalStr("Combine(5, 10, 20)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// Overload for two numbers
uc.DefineFunction("Combine(x, y) = x + y")
'// Overload for two strings
uc.DefineFunction("Combine(x As String, y As String) As String = x + y")
'// Overload for three numbers
uc.DefineFunction("Combine(x, y, z) = x + y + z")
Console.WriteLine($"Two numbers: {uc.EvalStr("Combine(5, 10)")}")
Console.WriteLine($"Two strings: {uc.EvalStr("Combine('Hello, ', 'World!')")}")
Console.WriteLine($"Three numbers: {uc.EvalStr("Combine(5, 10, 20)")}")
End Sub
End Module
Two numbers: 15
Two strings: Hello, World!
Three numbers: 35 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// Overload for two numbers uc.DefineFunction("Combine(x, y) = x + y") '// Overload for two strings uc.DefineFunction("Combine(x As String, y As String) As String = x + y") '// Overload for three numbers uc.DefineFunction("Combine(x, y, z) = x + y + z") Console.WriteLine($"Two numbers: {uc.EvalStr("Combine(5, 10)")}") Console.WriteLine($"Two strings: {uc.EvalStr("Combine('Hello, ', 'World!')")}") Console.WriteLine($"Three numbers: {uc.EvalStr("Combine(5, 10, 20)")}") End Sub End Module
Defines a recursive Factorial function using the IIf function for conditional logic.
using uCalcSoftware;
var uc = new uCalc();
uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)");
Console.WriteLine(uc.Eval("Factorial(5)"));
120 using uCalcSoftware; var uc = new uCalc(); uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)"); Console.WriteLine(uc.Eval("Factorial(5)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)");
cout << uc.Eval("Factorial(5)") << endl;
}
120 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)"); cout << uc.Eval("Factorial(5)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)")
Console.WriteLine(uc.Eval("Factorial(5)"))
End Sub
End Module
120 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("Factorial(n) = IIf(n > 1, n * Factorial(n - 1), 1)") Console.WriteLine(uc.Eval("Factorial(5)")) End Sub End Module
Miscellaneous end-user functions defined with DefineFunction()
using uCalcSoftware;
var uc = new uCalc();
Console.WriteLine("---- Simple function def ----");
uc.DefineFunction("f(x) = x ^ 2 + 5");
Console.WriteLine(uc.Eval("f(10)"));
Console.WriteLine("---- Function overloading ----");
// Overloading based on parameter type or number of parameters
uc.DefineFunction("MyOverload(x As Double) = x + x");
uc.DefineFunction("MyOverload(x As String) As String = x + x");
uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y");
uc.DefineFunction("MyOverload(x, y) = x + y");
Console.WriteLine(uc.EvalStr("MyOverload(5)"));
Console.WriteLine(uc.EvalStr("MyOverload('Ha')"));
Console.WriteLine(uc.EvalStr("MyOverload('Hello ', 'world!')"));
Console.WriteLine(uc.EvalStr("MyOverload(5, 10)"));
Console.WriteLine("---- Definition hiding/un-hiding ----");
// Shadowing (hiding) definitions
uc.DefineFunction("h(x) = x * 10");
Console.WriteLine(uc.Eval("h(3)"));
var hFunc = uc.DefineFunction("h(x) = x * 100"); // hides previous def
Console.WriteLine(uc.Eval("h(3)"));
hFunc.Release(); // Releasing this restores previous def
Console.WriteLine(uc.Eval("h(3)"));
Console.WriteLine("---- Optional parameters ----");
uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)");
Console.WriteLine(uc.Eval("Opt(10)"));
Console.WriteLine(uc.Eval("Opt(10, 20)"));
Console.WriteLine(uc.Eval("Opt(10, 20, 'Just a test 123')"));
Console.WriteLine("---- Recursion ----");
uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)");
uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))");
Console.WriteLine(uc.Eval("Factorial(5)"));
Console.WriteLine(uc.Eval("Fib(10)"));
// Bootstrap - builds new def on top of existing one
Console.WriteLine("------ Bootstrapping -------");
Console.WriteLine(uc.EvalStr("Hex(123)")); // uses "built-in" version of Hex()
var MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", bootstrap: true);
Console.WriteLine(uc.EvalStr("Hex(123)"));
MyHex.Release();
Console.WriteLine(uc.EvalStr("Hex(123)"));
// Overwrite - useful for spreadsheet-like functionality
Console.WriteLine("------ Overwrite -------");
uc.DefineFunction("SpreadsheetCell_A1() = 5", overwrite: true);
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", overwrite: true);
uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", overwrite: true);
Console.WriteLine(uc.Eval("SpreadsheetCell_A1()"));
Console.WriteLine(uc.Eval("SpreadsheetCell_B2()"));
Console.WriteLine(uc.Eval("SpreadsheetCell_C3()"));
// SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3()
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", overwrite: true);
uc.DefineFunction("SpreadsheetCell_A1() = 25", overwrite: true);
Console.WriteLine("-------");
// Note: Empty parenthesis are optional for functions with no parameters
Console.WriteLine(uc.Eval("SpreadsheetCell_A1"));
Console.WriteLine(uc.Eval("SpreadsheetCell_B2"));
Console.WriteLine(uc.Eval("SpreadsheetCell_C3"));
// See Define() topic for more
---- Simple function def ----
105
---- Function overloading ----
10
HaHa
Hello world!
15
---- Definition hiding/un-hiding ----
30
300
30
---- Optional parameters ----
20
35
45
---- Recursion ----
120
55
------ Bootstrapping -------
7b
0x7B
7b
------ Overwrite -------
5
50
55
-------
25
2500
2525 using uCalcSoftware; var uc = new uCalc(); Console.WriteLine("---- Simple function def ----"); uc.DefineFunction("f(x) = x ^ 2 + 5"); Console.WriteLine(uc.Eval("f(10)")); Console.WriteLine("---- Function overloading ----"); // Overloading based on parameter type or number of parameters uc.DefineFunction("MyOverload(x As Double) = x + x"); uc.DefineFunction("MyOverload(x As String) As String = x + x"); uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y"); uc.DefineFunction("MyOverload(x, y) = x + y"); Console.WriteLine(uc.EvalStr("MyOverload(5)")); Console.WriteLine(uc.EvalStr("MyOverload('Ha')")); Console.WriteLine(uc.EvalStr("MyOverload('Hello ', 'world!')")); Console.WriteLine(uc.EvalStr("MyOverload(5, 10)")); Console.WriteLine("---- Definition hiding/un-hiding ----"); // Shadowing (hiding) definitions uc.DefineFunction("h(x) = x * 10"); Console.WriteLine(uc.Eval("h(3)")); var hFunc = uc.DefineFunction("h(x) = x * 100"); // hides previous def Console.WriteLine(uc.Eval("h(3)")); hFunc.Release(); // Releasing this restores previous def Console.WriteLine(uc.Eval("h(3)")); Console.WriteLine("---- Optional parameters ----"); uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)"); Console.WriteLine(uc.Eval("Opt(10)")); Console.WriteLine(uc.Eval("Opt(10, 20)")); Console.WriteLine(uc.Eval("Opt(10, 20, 'Just a test 123')")); Console.WriteLine("---- Recursion ----"); uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)"); uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))"); Console.WriteLine(uc.Eval("Factorial(5)")); Console.WriteLine(uc.Eval("Fib(10)")); // Bootstrap - builds new def on top of existing one Console.WriteLine("------ Bootstrapping -------"); Console.WriteLine(uc.EvalStr("Hex(123)")); // uses "built-in" version of Hex() var MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", bootstrap: true); Console.WriteLine(uc.EvalStr("Hex(123)")); MyHex.Release(); Console.WriteLine(uc.EvalStr("Hex(123)")); // Overwrite - useful for spreadsheet-like functionality Console.WriteLine("------ Overwrite -------"); uc.DefineFunction("SpreadsheetCell_A1() = 5", overwrite: true); uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", overwrite: true); uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", overwrite: true); Console.WriteLine(uc.Eval("SpreadsheetCell_A1()")); Console.WriteLine(uc.Eval("SpreadsheetCell_B2()")); Console.WriteLine(uc.Eval("SpreadsheetCell_C3()")); // SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3() uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", overwrite: true); uc.DefineFunction("SpreadsheetCell_A1() = 25", overwrite: true); Console.WriteLine("-------"); // Note: Empty parenthesis are optional for functions with no parameters Console.WriteLine(uc.Eval("SpreadsheetCell_A1")); Console.WriteLine(uc.Eval("SpreadsheetCell_B2")); Console.WriteLine(uc.Eval("SpreadsheetCell_C3")); // See Define() topic for more
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
cout << "---- Simple function def ----" << endl;
uc.DefineFunction("f(x) = x ^ 2 + 5");
cout << uc.Eval("f(10)") << endl;
cout << "---- Function overloading ----" << endl;
// Overloading based on parameter type or number of parameters
uc.DefineFunction("MyOverload(x As Double) = x + x");
uc.DefineFunction("MyOverload(x As String) As String = x + x");
uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y");
uc.DefineFunction("MyOverload(x, y) = x + y");
cout << uc.EvalStr("MyOverload(5)") << endl;
cout << uc.EvalStr("MyOverload('Ha')") << endl;
cout << uc.EvalStr("MyOverload('Hello ', 'world!')") << endl;
cout << uc.EvalStr("MyOverload(5, 10)") << endl;
cout << "---- Definition hiding/un-hiding ----" << endl;
// Shadowing (hiding) definitions
uc.DefineFunction("h(x) = x * 10");
cout << uc.Eval("h(3)") << endl;
auto hFunc = uc.DefineFunction("h(x) = x * 100"); // hides previous def
cout << uc.Eval("h(3)") << endl;
hFunc.Release(); // Releasing this restores previous def
cout << uc.Eval("h(3)") << endl;
cout << "---- Optional parameters ----" << endl;
uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)");
cout << uc.Eval("Opt(10)") << endl;
cout << uc.Eval("Opt(10, 20)") << endl;
cout << uc.Eval("Opt(10, 20, 'Just a test 123')") << endl;
cout << "---- Recursion ----" << endl;
uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)");
uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))");
cout << uc.Eval("Factorial(5)") << endl;
cout << uc.Eval("Fib(10)") << endl;
// Bootstrap - builds new def on top of existing one
cout << "------ Bootstrapping -------" << endl;
cout << uc.EvalStr("Hex(123)") << endl; // uses "built-in" version of Hex()
auto MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", 0, uCalc::DataType::Empty, true);
cout << uc.EvalStr("Hex(123)") << endl;
MyHex.Release();
cout << uc.EvalStr("Hex(123)") << endl;
// Overwrite - useful for spreadsheet-like functionality
cout << "------ Overwrite -------" << endl;
uc.DefineFunction("SpreadsheetCell_A1() = 5", 0, uCalc::DataType::Empty, false, true);
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", 0, uCalc::DataType::Empty, false, true);
uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", 0, uCalc::DataType::Empty, false, true);
cout << uc.Eval("SpreadsheetCell_A1()") << endl;
cout << uc.Eval("SpreadsheetCell_B2()") << endl;
cout << uc.Eval("SpreadsheetCell_C3()") << endl;
// SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3()
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", 0, uCalc::DataType::Empty, false, true);
uc.DefineFunction("SpreadsheetCell_A1() = 25", 0, uCalc::DataType::Empty, false, true);
cout << "-------" << endl;
// Note: Empty parenthesis are optional for functions with no parameters
cout << uc.Eval("SpreadsheetCell_A1") << endl;
cout << uc.Eval("SpreadsheetCell_B2") << endl;
cout << uc.Eval("SpreadsheetCell_C3") << endl;
// See Define() topic for more
}
---- Simple function def ----
105
---- Function overloading ----
10
HaHa
Hello world!
15
---- Definition hiding/un-hiding ----
30
300
30
---- Optional parameters ----
20
35
45
---- Recursion ----
120
55
------ Bootstrapping -------
7b
0x7B
7b
------ Overwrite -------
5
50
55
-------
25
2500
2525 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; cout << "---- Simple function def ----" << endl; uc.DefineFunction("f(x) = x ^ 2 + 5"); cout << uc.Eval("f(10)") << endl; cout << "---- Function overloading ----" << endl; // Overloading based on parameter type or number of parameters uc.DefineFunction("MyOverload(x As Double) = x + x"); uc.DefineFunction("MyOverload(x As String) As String = x + x"); uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y"); uc.DefineFunction("MyOverload(x, y) = x + y"); cout << uc.EvalStr("MyOverload(5)") << endl; cout << uc.EvalStr("MyOverload('Ha')") << endl; cout << uc.EvalStr("MyOverload('Hello ', 'world!')") << endl; cout << uc.EvalStr("MyOverload(5, 10)") << endl; cout << "---- Definition hiding/un-hiding ----" << endl; // Shadowing (hiding) definitions uc.DefineFunction("h(x) = x * 10"); cout << uc.Eval("h(3)") << endl; auto hFunc = uc.DefineFunction("h(x) = x * 100"); // hides previous def cout << uc.Eval("h(3)") << endl; hFunc.Release(); // Releasing this restores previous def cout << uc.Eval("h(3)") << endl; cout << "---- Optional parameters ----" << endl; uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)"); cout << uc.Eval("Opt(10)") << endl; cout << uc.Eval("Opt(10, 20)") << endl; cout << uc.Eval("Opt(10, 20, 'Just a test 123')") << endl; cout << "---- Recursion ----" << endl; uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)"); uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))"); cout << uc.Eval("Factorial(5)") << endl; cout << uc.Eval("Fib(10)") << endl; // Bootstrap - builds new def on top of existing one cout << "------ Bootstrapping -------" << endl; cout << uc.EvalStr("Hex(123)") << endl; // uses "built-in" version of Hex() auto MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", 0, uCalc::DataType::Empty, true); cout << uc.EvalStr("Hex(123)") << endl; MyHex.Release(); cout << uc.EvalStr("Hex(123)") << endl; // Overwrite - useful for spreadsheet-like functionality cout << "------ Overwrite -------" << endl; uc.DefineFunction("SpreadsheetCell_A1() = 5", 0, uCalc::DataType::Empty, false, true); uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", 0, uCalc::DataType::Empty, false, true); uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", 0, uCalc::DataType::Empty, false, true); cout << uc.Eval("SpreadsheetCell_A1()") << endl; cout << uc.Eval("SpreadsheetCell_B2()") << endl; cout << uc.Eval("SpreadsheetCell_C3()") << endl; // SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3() uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", 0, uCalc::DataType::Empty, false, true); uc.DefineFunction("SpreadsheetCell_A1() = 25", 0, uCalc::DataType::Empty, false, true); cout << "-------" << endl; // Note: Empty parenthesis are optional for functions with no parameters cout << uc.Eval("SpreadsheetCell_A1") << endl; cout << uc.Eval("SpreadsheetCell_B2") << endl; cout << uc.Eval("SpreadsheetCell_C3") << endl; // See Define() topic for more }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Console.WriteLine("---- Simple function def ----")
uc.DefineFunction("f(x) = x ^ 2 + 5")
Console.WriteLine(uc.Eval("f(10)"))
Console.WriteLine("---- Function overloading ----")
'// Overloading based on parameter type or number of parameters
uc.DefineFunction("MyOverload(x As Double) = x + x")
uc.DefineFunction("MyOverload(x As String) As String = x + x")
uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y")
uc.DefineFunction("MyOverload(x, y) = x + y")
Console.WriteLine(uc.EvalStr("MyOverload(5)"))
Console.WriteLine(uc.EvalStr("MyOverload('Ha')"))
Console.WriteLine(uc.EvalStr("MyOverload('Hello ', 'world!')"))
Console.WriteLine(uc.EvalStr("MyOverload(5, 10)"))
Console.WriteLine("---- Definition hiding/un-hiding ----")
'// Shadowing (hiding) definitions
uc.DefineFunction("h(x) = x * 10")
Console.WriteLine(uc.Eval("h(3)"))
Dim hFunc = uc.DefineFunction("h(x) = x * 100") '// hides previous def
Console.WriteLine(uc.Eval("h(3)"))
hFunc.Release() '// Releasing this restores previous def
Console.WriteLine(uc.Eval("h(3)"))
Console.WriteLine("---- Optional parameters ----")
uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)")
Console.WriteLine(uc.Eval("Opt(10)"))
Console.WriteLine(uc.Eval("Opt(10, 20)"))
Console.WriteLine(uc.Eval("Opt(10, 20, 'Just a test 123')"))
Console.WriteLine("---- Recursion ----")
uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)")
uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))")
Console.WriteLine(uc.Eval("Factorial(5)"))
Console.WriteLine(uc.Eval("Fib(10)"))
'// Bootstrap - builds new def on top of existing one
Console.WriteLine("------ Bootstrapping -------")
Console.WriteLine(uc.EvalStr("Hex(123)")) '// uses "built-in" version of Hex()
Dim MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", bootstrap:=True)
Console.WriteLine(uc.EvalStr("Hex(123)"))
MyHex.Release()
Console.WriteLine(uc.EvalStr("Hex(123)"))
'// Overwrite - useful for spreadsheet-like functionality
Console.WriteLine("------ Overwrite -------")
uc.DefineFunction("SpreadsheetCell_A1() = 5", overwrite:=true)
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", Overwrite:=true)
uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", overwrite:=true)
Console.WriteLine(uc.Eval("SpreadsheetCell_A1()"))
Console.WriteLine(uc.Eval("SpreadsheetCell_B2()"))
Console.WriteLine(uc.Eval("SpreadsheetCell_C3()"))
'// SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3()
uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", overwrite:=true)
uc.DefineFunction("SpreadsheetCell_A1() = 25", overwrite:=true)
Console.WriteLine("-------")
'// Note: Empty parenthesis are optional for functions with no parameters
Console.WriteLine(uc.Eval("SpreadsheetCell_A1"))
Console.WriteLine(uc.Eval("SpreadsheetCell_B2"))
Console.WriteLine(uc.Eval("SpreadsheetCell_C3"))
'// See Define() topic for more
End Sub
End Module
---- Simple function def ----
105
---- Function overloading ----
10
HaHa
Hello world!
15
---- Definition hiding/un-hiding ----
30
300
30
---- Optional parameters ----
20
35
45
---- Recursion ----
120
55
------ Bootstrapping -------
7b
0x7B
7b
------ Overwrite -------
5
50
55
-------
25
2500
2525 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Console.WriteLine("---- Simple function def ----") uc.DefineFunction("f(x) = x ^ 2 + 5") Console.WriteLine(uc.Eval("f(10)")) Console.WriteLine("---- Function overloading ----") '// Overloading based on parameter type or number of parameters uc.DefineFunction("MyOverload(x As Double) = x + x") uc.DefineFunction("MyOverload(x As String) As String = x + x") uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y") uc.DefineFunction("MyOverload(x, y) = x + y") Console.WriteLine(uc.EvalStr("MyOverload(5)")) Console.WriteLine(uc.EvalStr("MyOverload('Ha')")) Console.WriteLine(uc.EvalStr("MyOverload('Hello ', 'world!')")) Console.WriteLine(uc.EvalStr("MyOverload(5, 10)")) Console.WriteLine("---- Definition hiding/un-hiding ----") '// Shadowing (hiding) definitions uc.DefineFunction("h(x) = x * 10") Console.WriteLine(uc.Eval("h(3)")) Dim hFunc = uc.DefineFunction("h(x) = x * 100") '// hides previous def Console.WriteLine(uc.Eval("h(3)")) hFunc.Release() '// Releasing this restores previous def Console.WriteLine(uc.Eval("h(3)")) Console.WriteLine("---- Optional parameters ----") uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)") Console.WriteLine(uc.Eval("Opt(10)")) Console.WriteLine(uc.Eval("Opt(10, 20)")) Console.WriteLine(uc.Eval("Opt(10, 20, 'Just a test 123')")) Console.WriteLine("---- Recursion ----") uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)") uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))") Console.WriteLine(uc.Eval("Factorial(5)")) Console.WriteLine(uc.Eval("Fib(10)")) '// Bootstrap - builds new def on top of existing one Console.WriteLine("------ Bootstrapping -------") Console.WriteLine(uc.EvalStr("Hex(123)")) '// uses "built-in" version of Hex() Dim MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", bootstrap:=True) Console.WriteLine(uc.EvalStr("Hex(123)")) MyHex.Release() Console.WriteLine(uc.EvalStr("Hex(123)")) '// Overwrite - useful for spreadsheet-like functionality Console.WriteLine("------ Overwrite -------") uc.DefineFunction("SpreadsheetCell_A1() = 5", overwrite:=true) uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", Overwrite:=true) uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", overwrite:=true) Console.WriteLine(uc.Eval("SpreadsheetCell_A1()")) Console.WriteLine(uc.Eval("SpreadsheetCell_B2()")) Console.WriteLine(uc.Eval("SpreadsheetCell_C3()")) '// SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3() uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", overwrite:=true) uc.DefineFunction("SpreadsheetCell_A1() = 25", overwrite:=true) Console.WriteLine("-------") '// Note: Empty parenthesis are optional for functions with no parameters Console.WriteLine(uc.Eval("SpreadsheetCell_A1")) Console.WriteLine(uc.Eval("SpreadsheetCell_B2")) Console.WriteLine(uc.Eval("SpreadsheetCell_C3")) '// See Define() topic for more End Sub End Module
Defining a callback function with a variable number of arguments
using uCalcSoftware;
var uc = new uCalc();
static void MyAverage(uCalc.Callback cb) {
double Total = 0;
for (int x = 1; x <= cb.ArgCount(); x++) {
Total = Total + cb.Arg(x);
}
cb.Return(Total / cb.ArgCount());
}
uc.DefineFunction("Average(x ...)", MyAverage);
Console.WriteLine(uc.Eval("Average(10, 3, 7, 4)"));
6 using uCalcSoftware; var uc = new uCalc(); static void MyAverage(uCalc.Callback cb) { double Total = 0; for (int x = 1; x <= cb.ArgCount(); x++) { Total = Total + cb.Arg(x); } cb.Return(Total / cb.ArgCount()); } uc.DefineFunction("Average(x ...)", MyAverage); Console.WriteLine(uc.Eval("Average(10, 3, 7, 4)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call MyAverage(uCalcBase::Callback cb) {
double Total = 0;
for (int x = 1; x <= cb.ArgCount(); x++) {
Total = Total + cb.Arg(x);
}
cb.Return(Total / cb.ArgCount());
}
int main() {
uCalc uc;
uc.DefineFunction("Average(x ...)", MyAverage);
cout << uc.Eval("Average(10, 3, 7, 4)") << endl;
}
6 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call MyAverage(uCalcBase::Callback cb) { double Total = 0; for (int x = 1; x <= cb.ArgCount(); x++) { Total = Total + cb.Arg(x); } cb.Return(Total / cb.ArgCount()); } int main() { uCalc uc; uc.DefineFunction("Average(x ...)", MyAverage); cout << uc.Eval("Average(10, 3, 7, 4)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub MyAverage(ByVal cb As uCalc.Callback)
Dim Total As Double = 0
For x As Integer = 1 To cb.ArgCount()
Total = Total + cb.Arg(x)
Next
cb.Return(Total / cb.ArgCount())
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("Average(x ...)", AddressOf MyAverage)
Console.WriteLine(uc.Eval("Average(10, 3, 7, 4)"))
End Sub
End Module
6 Imports System Imports uCalcSoftware Public Module Program Public Sub MyAverage(ByVal cb As uCalc.Callback) Dim Total As Double = 0 For x As Integer = 1 To cb.ArgCount() Total = Total + cb.Arg(x) Next cb.Return(Total / cb.ArgCount()) End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("Average(x ...)", AddressOf MyAverage) Console.WriteLine(uc.Eval("Average(10, 3, 7, 4)")) End Sub End Module
Passing arg ByHandle to retrieve meta data such as arg data type; and AnyType
using uCalcSoftware;
var uc = new uCalc();
static void DisplayArgs(uCalc.Callback cb) {
for (int x = 1; x <= cb.ArgCount(); x++) {
Console.WriteLine(cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType.Name);
}
}
uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", DisplayArgs);
uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))");
5 Type: double
3+2i Type: complex
Hello Type: string
true Type: bool
false Type: bool
9 Type: int16 using uCalcSoftware; var uc = new uCalc(); static void DisplayArgs(uCalc.Callback cb) { for (int x = 1; x <= cb.ArgCount(); x++) { Console.WriteLine(cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType.Name); } } uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", DisplayArgs); uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call DisplayArgs(uCalcBase::Callback cb) {
for (int x = 1; x <= cb.ArgCount(); x++) {
cout << cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType().Name() << endl;
}
}
int main() {
uCalc uc;
uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", DisplayArgs);
uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))");
}
5 Type: double
3+2i Type: complex
Hello Type: string
true Type: bool
false Type: bool
9 Type: int16 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call DisplayArgs(uCalcBase::Callback cb) { for (int x = 1; x <= cb.ArgCount(); x++) { cout << cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType().Name() << endl; } } int main() { uCalc uc; uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", DisplayArgs); uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))"); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub DisplayArgs(ByVal cb As uCalc.Callback)
For x As Integer = 1 To cb.ArgCount()
Console.WriteLine(cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType.Name)
Next
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", AddressOf DisplayArgs)
uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))")
End Sub
End Module
5 Type: double
3+2i Type: complex
Hello Type: string
true Type: bool
false Type: bool
9 Type: int16 Imports System Imports uCalcSoftware Public Module Program Public Sub DisplayArgs(ByVal cb As uCalc.Callback) For x As Integer = 1 To cb.ArgCount() Console.WriteLine(cb.ArgItem(x).ValueStr() + " Type: " + cb.ArgItem(x).DataType.Name) Next End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("DisplayArgs(ByHandle Arg As AnyType ...)", AddressOf DisplayArgs) uc.Eval("DisplayArgs(5, 3+2*#i, 'Hello', True, False, Int16(5+4.1))") End Sub End Module
Passing arg ByExpr
using uCalcSoftware;
var uc = new uCalc();
static void MySum(uCalc.Callback cb) {
var Total = 0.0;
var Expr = cb.ArgExpr(1);
var Start = cb.Arg(2);
var Finish = cb.Arg(3);
var Variable = cb.ArgItem(4);
for (double x = Start; x <= Finish; x++) {
Variable.Value(x);
Total += Expr.Evaluate();
}
cb.Return(Total);
}
uc.DefineVariable("x");
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum);
Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"));
385 using uCalcSoftware; var uc = new uCalc(); static void MySum(uCalc.Callback cb) { var Total = 0.0; var Expr = cb.ArgExpr(1); var Start = cb.Arg(2); var Finish = cb.Arg(3); var Variable = cb.ArgItem(4); for (double x = Start; x <= Finish; x++) { Variable.Value(x); Total += Expr.Evaluate(); } cb.Return(Total); } uc.DefineVariable("x"); uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum); Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call MySum(uCalcBase::Callback cb) {
auto Total = 0.0;
auto Expr = cb.ArgExpr(1);
auto Start = cb.Arg(2);
auto Finish = cb.Arg(3);
auto Variable = cb.ArgItem(4);
for (double x = Start; x <= Finish; x++) {
Variable.Value(x);
Total += Expr.Evaluate();
}
cb.Return(Total);
}
int main() {
uCalc uc;
uc.DefineVariable("x");
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum);
cout << uc.Eval("Sum(x ^ 2, 1, 10, x)") << endl;
}
385 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call MySum(uCalcBase::Callback cb) { auto Total = 0.0; auto Expr = cb.ArgExpr(1); auto Start = cb.Arg(2); auto Finish = cb.Arg(3); auto Variable = cb.ArgItem(4); for (double x = Start; x <= Finish; x++) { Variable.Value(x); Total += Expr.Evaluate(); } cb.Return(Total); } int main() { uCalc uc; uc.DefineVariable("x"); uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", MySum); cout << uc.Eval("Sum(x ^ 2, 1, 10, x)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub MySum(ByVal cb As uCalc.Callback)
Dim Total = 0.0
Dim Expr = cb.ArgExpr(1)
Dim Start = cb.Arg(2)
Dim Finish = cb.Arg(3)
Dim Variable = cb.ArgItem(4)
For x As Double = Start To Finish
Variable.Value(x)
Total += Expr.Evaluate()
Next
cb.Return(Total)
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("x")
uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", AddressOf MySum)
Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)"))
End Sub
End Module
385 Imports System Imports uCalcSoftware Public Module Program Public Sub MySum(ByVal cb As uCalc.Callback) Dim Total = 0.0 Dim Expr = cb.ArgExpr(1) Dim Start = cb.Arg(2) Dim Finish = cb.Arg(3) Dim Variable = cb.ArgItem(4) For x As Double = Start To Finish Variable.Value(x) Total += Expr.Evaluate() Next cb.Return(Total) End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("x") uc.DefineFunction("Sum(ByExpr Expr, Start, Finish, ByHandle Var)", AddressOf MySum) Console.WriteLine(uc.Eval("Sum(x ^ 2, 1, 10, x)")) End Sub End Module
Returning a string (from a callback)
using uCalcSoftware;
var uc = new uCalc();
static void TwiceStr(uCalc.Callback cb) {
cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1));
}
uc.DefineFunction("Twice(Txt As String) As String", TwiceStr);
Console.WriteLine(uc.EvalStr("Twice('Bye')"));
ByeBye using uCalcSoftware; var uc = new uCalc(); static void TwiceStr(uCalc.Callback cb) { cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1)); } uc.DefineFunction("Twice(Txt As String) As String", TwiceStr); Console.WriteLine(uc.EvalStr("Twice('Bye')"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call TwiceStr(uCalcBase::Callback cb) {
cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1));
}
int main() {
uCalc uc;
uc.DefineFunction("Twice(Txt As String) As String", TwiceStr);
cout << uc.EvalStr("Twice('Bye')") << endl;
}
ByeBye #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call TwiceStr(uCalcBase::Callback cb) { cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1)); } int main() { uCalc uc; uc.DefineFunction("Twice(Txt As String) As String", TwiceStr); cout << uc.EvalStr("Twice('Bye')") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub TwiceStr(ByVal cb As uCalc.Callback)
cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1))
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("Twice(Txt As String) As String", AddressOf TwiceStr)
Console.WriteLine(uc.EvalStr("Twice('Bye')"))
End Sub
End Module
ByeBye Imports System Imports uCalcSoftware Public Module Program Public Sub TwiceStr(ByVal cb As uCalc.Callback) cb.ReturnStr(cb.ArgStr(1) + cb.ArgStr(1)) End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("Twice(Txt As String) As String", AddressOf TwiceStr) Console.WriteLine(uc.EvalStr("Twice('Bye')")) End Sub End Module
How to handle and retrieve various data types (including pointers) within a callback.
using uCalcSoftware;
var uc = new uCalc();
static void MyFunction(uCalc.Callback cb) {
var uc = cb.uCalc;
Console.WriteLine("------ MyFunc ------");
// Retrieve standard 32-bit and 64-bit integer arguments directly
Console.WriteLine(cb.ArgInt32(1));
Console.WriteLine(cb.ArgInt64(2));
// Retrieve the value of a pointer argument by referencing its exact data type.
Console.WriteLine(uc.ItemOf("Int8").DataType.ToString(cb.ArgAddr(3)));
// The Item object correctly identifies the type before conversion
Console.WriteLine(uc.ItemOf("Int").DataType.ToString(cb.ArgPtr(4)));
}
static void MyFunction2(uCalc.Callback cb) {
var uc = cb.uCalc;
Console.WriteLine("------ MyFunc2 ------");
Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_8).ToString(cb.ArgPtr(1)));
}
static void MyFunction3(uCalc.Callback cb) {
var uc = cb.uCalc;
Console.WriteLine("------ MyFunc3 ------");
Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_16).ToString(cb.ArgPtr(1)));
}
uc.DefineVariable("x As Int = 123"); // Int32
uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)");
uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", MyFunction);
uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)");
uc.DefineVariable("x2 As Int8 = -123");
uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)");
uc.DefineFunction("MyFunc2(d As Int8 Ptr)", MyFunction2);
uc.Eval("MyFunc2(xPtr2)");
uc.DefineVariable("x3 As Int16 = 1234");
uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)");
uc.DefineFunction("MyFunc3(d As Int16 Ptr)", MyFunction3);
uc.Eval("MyFunc3(xPtr3)");
------ MyFunc ------
1230
2
-1
123
------ MyFunc2 ------
-123
------ MyFunc3 ------
1234 using uCalcSoftware; var uc = new uCalc(); static void MyFunction(uCalc.Callback cb) { var uc = cb.uCalc; Console.WriteLine("------ MyFunc ------"); // Retrieve standard 32-bit and 64-bit integer arguments directly Console.WriteLine(cb.ArgInt32(1)); Console.WriteLine(cb.ArgInt64(2)); // Retrieve the value of a pointer argument by referencing its exact data type. Console.WriteLine(uc.ItemOf("Int8").DataType.ToString(cb.ArgAddr(3))); // The Item object correctly identifies the type before conversion Console.WriteLine(uc.ItemOf("Int").DataType.ToString(cb.ArgPtr(4))); } static void MyFunction2(uCalc.Callback cb) { var uc = cb.uCalc; Console.WriteLine("------ MyFunc2 ------"); Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_8).ToString(cb.ArgPtr(1))); } static void MyFunction3(uCalc.Callback cb) { var uc = cb.uCalc; Console.WriteLine("------ MyFunc3 ------"); Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_16).ToString(cb.ArgPtr(1))); } uc.DefineVariable("x As Int = 123"); // Int32 uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)"); uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", MyFunction); uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)"); uc.DefineVariable("x2 As Int8 = -123"); uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)"); uc.DefineFunction("MyFunc2(d As Int8 Ptr)", MyFunction2); uc.Eval("MyFunc2(xPtr2)"); uc.DefineVariable("x3 As Int16 = 1234"); uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)"); uc.DefineFunction("MyFunc3(d As Int16 Ptr)", MyFunction3); uc.Eval("MyFunc3(xPtr3)");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call MyFunction(uCalcBase::Callback cb) {
auto uc = cb.uCalc();
cout << "------ MyFunc ------" << endl;
// Retrieve standard 32-bit and 64-bit integer arguments directly
cout << cb.ArgInt32(1) << endl;
cout << cb.ArgInt64(2) << endl;
// Retrieve the value of a pointer argument by referencing its exact data type.
cout << uc.ItemOf("Int8").DataType().ToString(cb.ArgAddr(3)) << endl;
// The Item object correctly identifies the type before conversion
cout << uc.ItemOf("Int").DataType().ToString(cb.ArgPtr(4)) << endl;
}
void ucalc_call MyFunction2(uCalcBase::Callback cb) {
auto uc = cb.uCalc();
cout << "------ MyFunc2 ------" << endl;
cout << uc.DataTypeOf(BuiltInType::Integer_8).ToString(cb.ArgPtr(1)) << endl;
}
void ucalc_call MyFunction3(uCalcBase::Callback cb) {
auto uc = cb.uCalc();
cout << "------ MyFunc3 ------" << endl;
cout << uc.DataTypeOf(BuiltInType::Integer_16).ToString(cb.ArgPtr(1)) << endl;
}
int main() {
uCalc uc;
uc.DefineVariable("x As Int = 123"); // Int32
uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)");
uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", MyFunction);
uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)");
uc.DefineVariable("x2 As Int8 = -123");
uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)");
uc.DefineFunction("MyFunc2(d As Int8 Ptr)", MyFunction2);
uc.Eval("MyFunc2(xPtr2)");
uc.DefineVariable("x3 As Int16 = 1234");
uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)");
uc.DefineFunction("MyFunc3(d As Int16 Ptr)", MyFunction3);
uc.Eval("MyFunc3(xPtr3)");
}
------ MyFunc ------
1230
2
-1
123
------ MyFunc2 ------
-123
------ MyFunc3 ------
1234 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call MyFunction(uCalcBase::Callback cb) { auto uc = cb.uCalc(); cout << "------ MyFunc ------" << endl; // Retrieve standard 32-bit and 64-bit integer arguments directly cout << cb.ArgInt32(1) << endl; cout << cb.ArgInt64(2) << endl; // Retrieve the value of a pointer argument by referencing its exact data type. cout << uc.ItemOf("Int8").DataType().ToString(cb.ArgAddr(3)) << endl; // The Item object correctly identifies the type before conversion cout << uc.ItemOf("Int").DataType().ToString(cb.ArgPtr(4)) << endl; } void ucalc_call MyFunction2(uCalcBase::Callback cb) { auto uc = cb.uCalc(); cout << "------ MyFunc2 ------" << endl; cout << uc.DataTypeOf(BuiltInType::Integer_8).ToString(cb.ArgPtr(1)) << endl; } void ucalc_call MyFunction3(uCalcBase::Callback cb) { auto uc = cb.uCalc(); cout << "------ MyFunc3 ------" << endl; cout << uc.DataTypeOf(BuiltInType::Integer_16).ToString(cb.ArgPtr(1)) << endl; } int main() { uCalc uc; uc.DefineVariable("x As Int = 123"); // Int32 uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)"); uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", MyFunction); uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)"); uc.DefineVariable("x2 As Int8 = -123"); uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)"); uc.DefineFunction("MyFunc2(d As Int8 Ptr)", MyFunction2); uc.Eval("MyFunc2(xPtr2)"); uc.DefineVariable("x3 As Int16 = 1234"); uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)"); uc.DefineFunction("MyFunc3(d As Int16 Ptr)", MyFunction3); uc.Eval("MyFunc3(xPtr3)"); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub MyFunction(ByVal cb As uCalc.Callback)
Dim uc = cb.uCalc
Console.WriteLine("------ MyFunc ------")
'// Retrieve standard 32-bit and 64-bit integer arguments directly
Console.WriteLine(cb.ArgInt32(1))
Console.WriteLine(cb.ArgInt64(2))
'// Retrieve the value of a pointer argument by referencing its exact data type.
Console.WriteLine(uc.ItemOf("Int8").DataType.ToString(cb.ArgAddr(3)))
'// The Item object correctly identifies the type before conversion
Console.WriteLine(uc.ItemOf("Int").DataType.ToString(cb.ArgPtr(4)))
End Sub
Public Sub MyFunction2(ByVal cb As uCalc.Callback)
Dim uc = cb.uCalc
Console.WriteLine("------ MyFunc2 ------")
Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_8).ToString(cb.ArgPtr(1)))
End Sub
Public Sub MyFunction3(ByVal cb As uCalc.Callback)
Dim uc = cb.uCalc
Console.WriteLine("------ MyFunc3 ------")
Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_16).ToString(cb.ArgPtr(1)))
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("x As Int = 123") '// Int32
uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)")
uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", AddressOf MyFunction)
uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)")
uc.DefineVariable("x2 As Int8 = -123")
uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)")
uc.DefineFunction("MyFunc2(d As Int8 Ptr)", AddressOf MyFunction2)
uc.Eval("MyFunc2(xPtr2)")
uc.DefineVariable("x3 As Int16 = 1234")
uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)")
uc.DefineFunction("MyFunc3(d As Int16 Ptr)", AddressOf MyFunction3)
uc.Eval("MyFunc3(xPtr3)")
End Sub
End Module
------ MyFunc ------
1230
2
-1
123
------ MyFunc2 ------
-123
------ MyFunc3 ------
1234 Imports System Imports uCalcSoftware Public Module Program Public Sub MyFunction(ByVal cb As uCalc.Callback) Dim uc = cb.uCalc Console.WriteLine("------ MyFunc ------") '// Retrieve standard 32-bit and 64-bit integer arguments directly Console.WriteLine(cb.ArgInt32(1)) Console.WriteLine(cb.ArgInt64(2)) '// Retrieve the value of a pointer argument by referencing its exact data type. Console.WriteLine(uc.ItemOf("Int8").DataType.ToString(cb.ArgAddr(3))) '// The Item object correctly identifies the type before conversion Console.WriteLine(uc.ItemOf("Int").DataType.ToString(cb.ArgPtr(4))) End Sub Public Sub MyFunction2(ByVal cb As uCalc.Callback) Dim uc = cb.uCalc Console.WriteLine("------ MyFunc2 ------") Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_8).ToString(cb.ArgPtr(1))) End Sub Public Sub MyFunction3(ByVal cb As uCalc.Callback) Dim uc = cb.uCalc Console.WriteLine("------ MyFunc3 ------") Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_16).ToString(cb.ArgPtr(1))) End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("x As Int = 123") '// Int32 uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)") uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", AddressOf MyFunction) uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)") uc.DefineVariable("x2 As Int8 = -123") uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)") uc.DefineFunction("MyFunc2(d As Int8 Ptr)", AddressOf MyFunction2) uc.Eval("MyFunc2(xPtr2)") uc.DefineVariable("x3 As Int16 = 1234") uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)") uc.DefineFunction("MyFunc3(d As Int16 Ptr)", AddressOf MyFunction3) uc.Eval("MyFunc3(xPtr3)") End Sub End Module
Determining properties of an expression part
using uCalcSoftware;
var uc = new uCalc();
static void ItemCallback(uCalc.Callback cb) {
Console.WriteLine($"Name: {cb.Item.Name}");
Console.WriteLine($"Data type: {cb.Item.DataType.Name}");
Console.WriteLine($"Param count: {cb.Item.Count}");
Console.Write("Procedure type: ");
if (cb.Item.IsProperty(ItemIs.Operator)) {
Console.WriteLine("Operator");
} else if (cb.Item.IsProperty(ItemIs.Function)) {
Console.WriteLine("Function");
}
Console.WriteLine(cb.Item.Text);
Console.WriteLine(cb.Item.Description);
Console.WriteLine("---");
}
uc.DefineFunction("AAA() As Double", ItemCallback).Description = "Does this and that";
uc.DefineFunction("BBB(x, y, z) As String", ItemCallback).Description = "Does something else";
uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity.LeftToRight, ItemCallback);
uc.EvalStr("AAA()");
uc.EvalStr("BBB(9, 8, 7)");
uc.EvalStr("5 CCC 4");
Name: aaa
Data type: double
Param count: 0
Procedure type: Function
Function: AAA() As Double
Does this and that
---
Name: bbb
Data type: string
Param count: 3
Procedure type: Function
Function: BBB(x, y, z) As String
Does something else
---
Name: ccc
Data type: int
Param count: 2
Procedure type: Operator
Operator: {x} CCC {y} As Int32
--- using uCalcSoftware; var uc = new uCalc(); static void ItemCallback(uCalc.Callback cb) { Console.WriteLine($"Name: {cb.Item.Name}"); Console.WriteLine($"Data type: {cb.Item.DataType.Name}"); Console.WriteLine($"Param count: {cb.Item.Count}"); Console.Write("Procedure type: "); if (cb.Item.IsProperty(ItemIs.Operator)) { Console.WriteLine("Operator"); } else if (cb.Item.IsProperty(ItemIs.Function)) { Console.WriteLine("Function"); } Console.WriteLine(cb.Item.Text); Console.WriteLine(cb.Item.Description); Console.WriteLine("---"); } uc.DefineFunction("AAA() As Double", ItemCallback).Description = "Does this and that"; uc.DefineFunction("BBB(x, y, z) As String", ItemCallback).Description = "Does something else"; uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity.LeftToRight, ItemCallback); uc.EvalStr("AAA()"); uc.EvalStr("BBB(9, 8, 7)"); uc.EvalStr("5 CCC 4");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
void ucalc_call ItemCallback(uCalcBase::Callback cb) {
cout << "Name: " << cb.Item().Name() << endl;
cout << "Data type: " << cb.Item().DataType().Name() << endl;
cout << "Param count: " << cb.Item().Count() << endl;
cout << "Procedure type: ";
if (cb.Item().IsProperty(ItemIs::Operator)) {
cout << "Operator" << endl;
} else if (cb.Item().IsProperty(ItemIs::Function)) {
cout << "Function" << endl;
}
cout << cb.Item().Text() << endl;
cout << cb.Item().Description() << endl;
cout << "---" << endl;
}
int main() {
uCalc uc;
uc.DefineFunction("AAA() As Double", ItemCallback).Description("Does this and that");
uc.DefineFunction("BBB(x, y, z) As String", ItemCallback).Description("Does something else");
uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity::LeftToRight, ItemCallback);
uc.EvalStr("AAA()");
uc.EvalStr("BBB(9, 8, 7)");
uc.EvalStr("5 CCC 4");
}
Name: aaa
Data type: double
Param count: 0
Procedure type: Function
Function: AAA() As Double
Does this and that
---
Name: bbb
Data type: string
Param count: 3
Procedure type: Function
Function: BBB(x, y, z) As String
Does something else
---
Name: ccc
Data type: int
Param count: 2
Procedure type: Operator
Operator: {x} CCC {y} As Int32
--- #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call ItemCallback(uCalcBase::Callback cb) { cout << "Name: " << cb.Item().Name() << endl; cout << "Data type: " << cb.Item().DataType().Name() << endl; cout << "Param count: " << cb.Item().Count() << endl; cout << "Procedure type: "; if (cb.Item().IsProperty(ItemIs::Operator)) { cout << "Operator" << endl; } else if (cb.Item().IsProperty(ItemIs::Function)) { cout << "Function" << endl; } cout << cb.Item().Text() << endl; cout << cb.Item().Description() << endl; cout << "---" << endl; } int main() { uCalc uc; uc.DefineFunction("AAA() As Double", ItemCallback).Description("Does this and that"); uc.DefineFunction("BBB(x, y, z) As String", ItemCallback).Description("Does something else"); uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity::LeftToRight, ItemCallback); uc.EvalStr("AAA()"); uc.EvalStr("BBB(9, 8, 7)"); uc.EvalStr("5 CCC 4"); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub ItemCallback(ByVal cb As uCalc.Callback)
Console.WriteLine($"Name: {cb.Item.Name}")
Console.WriteLine($"Data type: {cb.Item.DataType.Name}")
Console.WriteLine($"Param count: {cb.Item.Count}")
Console.Write("Procedure type: ")
If cb.Item.IsProperty(ItemIs.Operator) Then
Console.WriteLine("Operator")
ElseIf cb.Item.IsProperty(ItemIs.Function ) Then
Console.WriteLine("Function")
End If
Console.WriteLine(cb.Item.Text)
Console.WriteLine(cb.Item.Description)
Console.WriteLine("---")
End Sub
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("AAA() As Double", AddressOf ItemCallback).Description = "Does this and that"
uc.DefineFunction("BBB(x, y, z) As String", AddressOf ItemCallback).Description = "Does something else"
uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity.LeftToRight, AddressOf ItemCallback)
uc.EvalStr("AAA()")
uc.EvalStr("BBB(9, 8, 7)")
uc.EvalStr("5 CCC 4")
End Sub
End Module
Name: aaa
Data type: double
Param count: 0
Procedure type: Function
Function: AAA() As Double
Does this and that
---
Name: bbb
Data type: string
Param count: 3
Procedure type: Function
Function: BBB(x, y, z) As String
Does something else
---
Name: ccc
Data type: int
Param count: 2
Procedure type: Operator
Operator: {x} CCC {y} As Int32
--- Imports System Imports uCalcSoftware Public Module Program Public Sub ItemCallback(ByVal cb As uCalc.Callback) Console.WriteLine($"Name: {cb.Item.Name}") Console.WriteLine($"Data type: {cb.Item.DataType.Name}") Console.WriteLine($"Param count: {cb.Item.Count}") Console.Write("Procedure type: ") If cb.Item.IsProperty(ItemIs.Operator) Then Console.WriteLine("Operator") ElseIf cb.Item.IsProperty(ItemIs.Function ) Then Console.WriteLine("Function") End If Console.WriteLine(cb.Item.Text) Console.WriteLine(cb.Item.Description) Console.WriteLine("---") End Sub Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("AAA() As Double", AddressOf ItemCallback).Description = "Does this and that" uc.DefineFunction("BBB(x, y, z) As String", AddressOf ItemCallback).Description = "Does something else" uc.DefineOperator("{x} CCC {y} As Int32", 0, Associativity.LeftToRight, AddressOf ItemCallback) uc.EvalStr("AAA()") uc.EvalStr("BBB(9, 8, 7)") uc.EvalStr("5 CCC 4") End Sub End Module