ucDefineOperator
See Also: ucDefine, ucDefineFunction, ucParam, ucParamCount, ucParamHandle, ucReturn
Defines an operator.
ucDefineOperator(Definition [, FunctionAddress
[, tHandle]])
Many of the details for defining an operator are very closely related to the details for defining a function (native vs non-native callbacks, data types, ByVal, ByExpr, etc). The ucDefineFunction topic covers those details. The operand in an operator definition is related to an argument in a function definition. They both can be passed ByRef, ByVal, ByExpr, or ByHandle, and can be assigned a data type. Although operands on the left side of ":=", in a self-contained definition, are enclosed within curly braces, on the right side they are bare, just like the arguments are on the right side of "=" in a function definition. This topic here focuses mainly on the unique aspects of defining operators.
The Definition part can take one of the following three forms, depending on whether the operator you are defining is Prefix, Postfix, or Infix (binary):
[Prec] Operator {Operand} [ := DefinitionCode ]
[Prec] {Operand} Operator [ := DefinitionCode ]
[Prec] {LeftOperand} Operator {RightOperand} } [ := DefinitionCode ]
Definition parts
Prec
Optional. Though optional, it is highly recommended that all operator definitions include a specified precedence level. If none is supplied, then a default precedence value is used. Prec is an arbitrary positive integer value less than 2^31, which derives its meaning by whether this value is greater, less than, or equal to the precedence levels of other given operators. See the precedence levels used in the operator definitions in the uCalc header/include file for your compiler to determine what numeric values to set your definitions with, relative to those definitions. In addition to a literal numeric value, in the Standard License (because it relies on uCalc()), Prec can also be Precedence(Op); that is, the word Precedence followed by parentheses, enclosing a string argument containing the name of an already defined operator.
Operator
Required. Unlike function names which can only be alphanumeric, operator names can also consist of symbols, such as +, -, **, etc. An operator name can be alpha numeric, or non-alphanumeric, but not a combination of both.
Operand, or LeftOperand, RightOperand
Required. Operands are defined the same way as function arguments, in terms of using directives like ByRef, ByVal, and specified data types. Optional arguments or indefinite number of arguments do not apply in this context.
DefinitionCode
Optional. If the definition is not a callback, then you can supply a self-contained definition. It is important to note that unlike function definitions which use the equal sign, "=", operator definitions use a colon followed by an equal sign, ":=". This allows the equal sign by itself to be defined as an operator. Nothing is hard-coded. So should you need to define ":=" itself as an operator, you can modify the include file and change ":=" to something else.
Remarks
Example 1: Miscellaneous self-contained operator definitions
This example demonstrates several variations of self-contained operator definitions: an operator with an alphanumeric name (ShiftLeft), operators named using symbols (%, and !), and prefix, postfix, and infix versions of an operator (the ! symbol). The numeric values at the beginning of each definition represent precedence levels. For instance, ShiftLeft is defined with a precedence level of 20, while the % operator has a precedence level of 50.
Visual Basic
|
' This example demonstrates various self-contained
operator definitions ucDefineOperator "20
{x} ShiftLeft {y} := x * 2^y" ' Infix ucDefineOperator "50
{x}% := x / 100" ' Postfix ucDefineOperator "60
!{x} := x - 1" ' Prefix ucDefineOperator "30
{x}! := x * 2" ' This one hides the pre-defined factorial op ucDefineOperator "10
{x} ! {y} := x * y" Print ucEvalStr("2 ShiftLeft 3") ' returns 16 Print ucEvalStr("25%") ' returns 0.25 Print ucEvalStr("!5") ' returns 4 Print ucEvalStr("!5!") ' (!5)! returns 8 Print ucEvalStr("!5!4") ' (!5) ! 4 returns 16 ' Here the precedence levels are switched ucDefineOperator "30
!{x} := x - 1" ucDefineOperator "60
{x}! := x * 2" ucDefineOperator "50
{x} ! {y} := x * y" Print ucEvalStr("2 ShiftLeft 3") ' returns 16 Print ucEvalStr("25%") ' returns 0.25 Print ucEvalStr("!5") ' returns 4 Print ucEvalStr("!5!") ' !(5!) returns 9 Print ucEvalStr("!5!4") ' !(5 ! 4) returns 19 |
Example 2: Non-native operator callback definition
This example uses the same callback routine as the one found in Example C2 of the ucDefineFunction topic. There, in addition to VB code, you will find source code for the other supported compilers as well. The difference here is that the definition attached to the StringRepeat callback is an operator instead of a function. It is designed to repeat a string a given number of times. In the other example, StringRepeat("Ha ", 3) would return "Ha Ha Ha ", whereas here, the * operator is defined with string as the left operand, and a number as the right operand, so that "Ha " * 3 would return "Ha Ha Ha ". This example uses a non-native callback. Native callbacks, like the one in the next example, are faster, and also easier to implement, especially when strings are involved.
Visual Basic
|
' The following line can be placed in
Form_Load() ' Notice here that uCalc's WideString is
what matches VB's String ucDefineOperator
"20 {ByRef MyString As WideString} * {ByVal Count As Long} As
WideString", AddressOf StringRepeat ' The following callback routine goes in a separate module, such as DemoVB.Bas Function StringRepeat(ByRef MyString As String,
ByVal Count As Long) As String Dim x As
Long, TotalString As String For x =
1 To Count
TotalString = TotalString + MyString Next
StringRepeat = TotalString End Function |
Example 3: Native operator callback definition
This definition does the same thing as the previous example, except it is implemented using a native callback. More details can be found in the Native Callbacks section of the ucDefineFunction topic. Native callbacks are generally much faster than non-native callbacks. They are also less tricky to implement when strings are involved.
Visual Basic
|
' The following line can be placed in
Form_Load() ucDefineOperator "Native: 20 {MyString As String} * {Count} As
String", AddressOf Native_StringRepeat ' The following callback routine goes in a separate module, such as DemoVB.Bas Sub Native_StringRepeat(ByVal Expr As Long) Dim x As
Long, TotalString As String For x =
1 To ucParam(Expr, 2) TotalString
= TotalString + ucParamStr(Expr, 1) Next
ucReturnStr Expr, TotalString End Sub |
Note: With the Standard license (this can also be tested in the demo), if you wanted the above definition to have the same precedence level as the multiplication operator that is already defined, then instead of using the number 20, you could do it like this:
ucDefine "Op:: Precedence('*') {MyString As String} * {Count } As String", AddressOf Native_StringRepeat
New or enhanced in version 2.96
New or enhanced in version 2.9+
Issues for users migrating from version 2.0