Local
Variables
See Also: ucDefineVariable
uCalc lets you define variables that are local to an expression. The definition is done within the expression itself. If a variable with the same name was already defined, the local variable will not interfere with the previously defined variable of the same name. A local variable can hold a separate value from the previously defined variable. An expression can have any number of local variables, separated by commas.
Example 1: Multiple local variables in an expression
This example uses two local variables: x, and y. After the expression is finished, x reverts to being undefined, and y still has its original value of 123, which it had before the expression was evaluated.
Visual Basic
ucDefineVariable
"y = 123" Print ucEvalStr("Local(x, y, (uc_For(x,
1, 5, 1, SetVar(y, y+x^2)); y))") ' Returns 55 Print ucEvalStr("x")
' Returns an error: Undefined identifier Print ucEvalStr("y")
' Returns 123 |
Example 2: Local variable, and ByHandle argument (Summation)
This example defines a summation routine named Sum(). The actual callback function is named Sum_(), and requires 5 arguments, where the last one is a variable passed ByHandle. A syntax construct named Sum() is defined so that the last two arguments are optional. The last argument is made local. If omitted it defaults to a variable named x. By making it local you don't have to worry about defining a variable ahead of time for use with Sum(). Plus it will not interfere with another variable of the same name, whether it is outside the expression, or Sum is nested several times within the same expression. Expressions such as the following can be entered:
Sum(x^2, 1, 10) ' returns 385
Sum(n+5, 1, 25, 1,
n) ' returns 450
Sum(Sum(x^2, 1, 10)*10, 1, 5) ' returns 19250
Visual Basic
' The following 3 lines can be placed
in Form_Load() ucDefineFunction
"Native: Sum_(ByExpr Expr,
Start, Finish, Step, ByHandle Var)",
AddressOf ucSum ucDefineSyntax
"Sum({Expr}, {Start}, {Finish} [, {Step=1} [,
{Var=x}]])" _
+ "::= Local({Var}, Sum_({Expr}, {Start},
{Finish}, {Step}, {Var}))" ' The following callback routine goes
in a separate module, such as DemoVB.Bas Sub ucSum(ByVal Expr As Long) Dim
Expression As Long, VarHandle As Long Dim Start
As Long, Finish As Long, sStep As Long Dim x As
Double, Total As Double
Expression = ucArgHandle(Expr,
1) Start = ucArg(Expr, 2) Finish = ucArg(Expr, 3) sStep = ucArg(Expr, 4) VarHandle = ucArgHandle(Expr, 5) For x =
Start To Finish Step sStep ucSetVariableValue VarHandle, x Total
= Total + ucEvaluate(Expression) Next ucReturn Expr, Total End Sub |
This same example is also found in the source code for the demo program for C#, C++ Builder, PB, VB (classic), VB.NET, and VC++.
Example 3: Local variable, and ByHandle argument (Equation Solver)
The concept in this example is very similar to that of the previous example. This routine is a simple equation solver based on an adaptation of the bisection method algorithm. This code is just enough to get you started. You will want to add to it for a more robust solver. Here are examples of equations it can solve:
Solve(x^2 + 1 = 26) ' returns 5
Solve(x^2 + 1 = 26, -1000, 0) ' returns -5
Visual Basic
' The following lines can be placed in Form_Load() ucDefineFunction
"Native: Solve_(ByExpr Expr,
a, b, ByHandle Var)",
AddressOf ucSolve ucDefineSyntax
"Solve({Expr} [, {a=-100000000} [,
{b=100000000} [, {Var=x}]]]) " _ + "::= Local({Var}, Solve_({Expr}, {a}, {b},
{Var}))" ucDefineSyntax
"Solve({Left} = {Right} [, {etc}]) ::=
Solve({Left}-({Right}) {etc: , {etc}})" ' The following callback routine goes
in a separate module, such as DemoVB.Bas Sub ucSolve(ByVal Expr As Long) Dim
Expression As Long, Variable As Long, Iterations As Long Dim a As
Double, b As Double, fa As Double, fb As Double Dim Value
As Double, tmp As Double
Expression = ucArgHandle(Expr,
1) a = ucArg(Expr, 2) b = ucArg(Expr, 3) Variable = ucArgHandle(Expr, 4) ucSetVariableValue Variable, a: fa
= ucEvaluate(Expression) ucSetVariableValue Variable, b: fb
= ucEvaluate(Expression) If fb < fa Then tmp = a: a = b: b = tmp 'swap a, b Do While
Abs(b - a) > 0.000000000000001 ucSetVariableValue Variable, (a + b) / 2 Value
= ucEvaluate(Expression) If
Value = 0 Then a = (a + b) / 2: Exit Do If
Value < 0 _ Then a
= (a + b) / 2 _ Else b
= (a + b) / 2 Iterations
= Iterations + 1 If
Iterations = 100 Then Exit Do Loop If
Abs(Value) > 0.0000000001 Then ucRaiseErrorMessage
Expr, "Solution not found" ucReturn Expr, a End Sub |
This same example is also found in the source code for the demo program for C#, C++ Builder, PB, VB (classic), VB.NET, and VC++.