Operators are sequences of characters within function
bodies that denote operations to be carried out.
There are many different operators for use in scripts. Operators are predefined
tokens.
Operator ::= ( | ) | [ | ] | . | -> |
OperatorKeyword | ++ | -- | ~ | ! | - | * | & |
TypeCastOperator | / | % | + | << | >> | == | != |
>= | <= | > | < | ^ | | | && | || | = |
+= | -= | *= | /= | %= | &= | ^= | |= | ,
Operators are recognized by a precise number of consecutive
characters exactly matching the predefined sequence, and do not
need to be terminated by whitespace or any other delimiter.
Operators have a discrete number of expressions with which they
must be associated. Most operators are either binary (two
expressions) or unary (one expression). The operators
can have two possible forms:
-
Horizontal Association Form: expression(s) to be evaluated
appear to sides
of operator (left side, right side, or both sides).
-
Parenthetical Form: expression(s) to be evaluated appear in
parentheses to right of operator.
Below is a precedence table for operators. Expressions
associated with higher-priority operators are always evaluated
before lower-priority operators.
Operator
|
Description |
Expression Count
|
Expression Form
|
Priority
|
()
|
Parenthetical precedence/Function call |
(Varies)
|
Parenthetical
|
256
|
[]
|
Array/Pointer indexed dereference |
Binary
|
Parenthetical
|
180
|
.
|
Structure object member selector |
Binary
|
Left/Right
|
180
|
->
|
Pointer-to-Structure member selector |
Binary
|
Left/Right
|
180
|
debugmsg
|
Output text to log |
Unary
|
Parenthetical
|
100
|
sizeof
|
Size of expression |
Unary
|
Parenthetical
|
100
|
new
|
Memory buffer allocation |
Unary
|
Parenthetical
|
100
|
newchild
|
Child memory buffer allocation |
Unary
|
Parenthetical
|
100
|
getparent
|
Get pointer to parent node |
Unary
|
Parenthetical
|
100
|
getnext
|
Get pointer to next node |
Unary
|
Parenthetical
|
100
|
getprevious
|
Get pointer to previous node |
Unary
|
Parenthetical
|
100
|
getchild
|
Get pointer to child node |
Unary
|
Parenthetical
|
100
|
getsize
|
Get byte size of node |
Unary
|
Parenthetical
|
100
|
getbitsize
|
Get bit size of node |
Unary
|
Parenthetical
|
100
|
getuid
|
Get construct UID of node |
Unary
|
Parenthetical
|
100
|
getname
|
Get construct name of node |
Unary
|
Parenthetical
|
100
|
getuidfromname
|
Get construct UID when given name |
Unary
|
Parenthetical
|
100
|
getchildcount
|
Get child count of node |
Unary
|
Parenthetical
|
100
|
getrelpos
|
Get relative position of node |
Unary
|
Parenthetical
|
100
|
gethlevel
|
Get hierarchy level of node |
Unary
|
Parenthetical
|
100
|
getnodetype
|
Get node type of node |
Unary
|
Parenthetical
|
100
|
round
|
Round to nearest whole number |
Unary
|
Parenthetical
|
100
|
floor
|
Floor function |
Unary
|
Parenthetical
|
100
|
ceil
|
Ceiling function |
Unary
|
Parenthetical
|
100
|
abs
|
Absolute value function |
Unary
|
Parenthetical
|
100
|
sgn
|
Sign function |
Unary
|
Parenthetical
|
100
|
sin
|
Trigonometric sine function |
Unary
|
Parenthetical
|
100
|
cos
|
Trigonometric cosine function |
Unary
|
Parenthetical
|
100
|
tan
|
Trigonometric tangent function |
Unary
|
Parenthetical
|
100
|
log10
|
Base-10 logarithmic function |
Unary
|
Parenthetical
|
100
|
log
|
Natural logarithmic function |
Unary
|
Parenthetical
|
100
|
exp
|
Natural power function |
Unary
|
Parenthetical
|
100
|
sqrt
|
Square root function |
Unary
|
Parenthetical
|
100
|
atan
|
Partial arctangent function |
Unary
|
Parenthetical
|
100
|
rand
|
Random integer function |
Unary
|
Parenthetical
|
100
|
asin
|
Inverse sine function |
Unary
|
Parenthetical
|
100
|
acos
|
Inverse cosine function |
Unary
|
Parenthetical
|
100
|
sinh
|
Hyperbolic sine function |
Unary
|
Parenthetical
|
100
|
cosh
|
Hyperbolic cosine function |
Unary
|
Parenthetical
|
100
|
tanh
|
Hyperbolic tangent function |
Unary
|
Parenthetical
|
100
|
asinh
|
Inverse hyperbolic sine function |
Unary
|
Parenthetical
|
100
|
acosh
|
Inverse hyperbolic cosine function |
Unary
|
Parenthetical
|
100
|
atanh
|
Inverse hyperbolic tangent function |
Unary
|
Parenthetical
|
100
|
atan2
|
Full arctangent function |
Binary
|
Parenthetical
|
100
|
powr
|
Power function |
Binary
|
Parenthetical
|
100
|
modf
|
Floating-point mod function |
Binary
|
Parenthetical
|
100
|
++
|
Prefix increment |
Unary
|
Right
|
100
|
--
|
Prefix decrement |
Unary
|
Right
|
100
|
~
|
Bitwise NOT |
Unary
|
Right
|
100
|
!
|
Logical NOT |
Unary
|
Right
|
100
|
-
|
Negate |
Unary
|
Right
|
100
|
*
|
Pointer dereference |
Unary
|
Right
|
100
|
&
|
Address-of |
Unary
|
Right
|
100
|
(type)
|
Typecast |
Unary
|
Right
|
100
|
*
|
Multiply |
Binary
|
Left/Right
|
90
|
/
|
Divide |
Binary
|
Left/Right
|
90
|
%
|
Modulo |
Binary
|
Left/Right
|
90
|
+
|
Add |
Binary
|
Left/Right
|
80
|
-
|
Subtract |
Binary
|
Left/Right
|
80
|
<<
|
Shift left |
Binary
|
Left/Right
|
70
|
>>
|
Shift right |
Binary
|
Left/Right
|
70
|
>=
|
Relational greater than or equal to |
Binary
|
Left/Right
|
65
|
<=
|
Relational less than or equal to |
Binary
|
Left/Right
|
65
|
>
|
Relational greater than |
Binary
|
Left/Right
|
65
|
<
|
Relational less than |
Binary
|
Left/Right
|
65
|
==
|
Relational equal to |
Binary
|
Left/Right
|
60
|
!=
|
Relational not equal to |
Binary
|
Left/Right
|
60
|
&
|
Bitwise AND |
Binary
|
Left/Right
|
55
|
^
|
Bitwise XOR |
Binary
|
Left/Right
|
53
|
|
|
Bitwise OR |
Binary
|
Left/Right
|
50
|
&&
|
Logical AND |
Binary
|
Left/Right
|
45
|
||
|
Logical OR |
Binary
|
Left/Right
|
40
|
=
|
Assignment |
Binary
|
Right/Left
|
5
|
+=
|
Addition assignment |
Binary
|
Right/Left
|
5
|
-=
|
Subtraction assignment |
Binary
|
Right/Left
|
5
|
*=
|
Multiplication assignment |
Binary
|
Right/Left
|
5
|
/=
|
Division assignment |
Binary
|
Right/Left
|
5
|
%=
|
Modulo assignment |
Binary
|
Right/Left
|
5
|
&=
|
Bitwise AND assignment |
Binary
|
Right/Left
|
5
|
^=
|
Bitwise XOR assignment |
Binary
|
Right/Left
|
5
|
|=
|
Bitwise OR assignment |
Binary
|
Right/Left
|
5
|
<<=
|
Shift left assignment |
Binary
|
Right/Left
|
5
|
>>=
|
Shift right assignment |
Binary
|
Right/Left
|
5
|
,
|
Argument separator |
Binary
|
Left/Right
|
3
|
Parenthetical precedence/Function call
ParentheticalExpression ::= ( S? Expression S? )
Anything inside of parentheses is evaluated before any expression to the
immediate left or right of the parenthetical boundaries.
If the parentheses denote a function call argument list or expressions
associated with an operator of parenthetical form, the arguments inside are
evaluated left-to-right prior to operator application:
ArgumentExpression ::= ( S? Expression (S? , S? Expression)* S? )
A function without arguments is still required to have a pair of parentheses to
denote the function call, but without any expression on the inside:
FunctionCallNoArguments ::= ( S? )
Array/Pointer indexed dereference
IndexedDereference ::= Expression S? [ S? Expression S? ]
The first expression must be an array or pointer;
the second expression must be a scalar type. The second
expression is automatically cast to an integer type. Anything
inside of square brackets is evaluated before any expression to the left of the
brackets.
Structure object member selector
StructureMemberSelection ::= Expression S? . S? Identifier
The expression must be a non-derived-from-simple structure type;
the identifier must be a valid member name (variable or
function name) of the structure type.
Pointer-to-Structure member selector
PointerToStructureMemberSelection ::= Expression S? -> S? Identifier
The expression must be a pointer to a non-derived-from-simple structure
type; the identifier must be a valid member name (variable
or function name) of the structure type.
Output to debug log
DebugExpression ::= debugmsg S? ( S? Expression S? )
The expression must be a pointer to null-terminated character data. The
string passed to debugmsg is dumped to BARfly's log when
BARfly is open. In any other context, this operator has no effect.
Use debugmsg to trace parts of the I.F. code during the
testing process.
Size of expression
SizeOfExpression ::= sizeof S? ( S? (DataStructureType | VariableName)
S? )
The expression returns a constant 32-bit integer representing
the byte size of a type or variable.
For a type, the type must be either a simple type name or structure
name. For a variable, the name must be a valid local,
parameter, member, or global variable
name.
Memory buffer/node handle allocation
NewExpressionSingular ::= new S (DataStructureType | OrganizedBlockType)
NewExpressionPlural ::= new S UnorganizedBlockType S? [ S? Expression S?
]
There are two syntaxes for allocating a substitute node. Both
of these can only be executed in the body of a Deserialize or
Serialize method or sub-function calls, and only as part of deserialization
or serialization. Furthermore, only one
successful allocation may take place during the function call.
The singular syntax is used when allocating a substitute
data structure node or a substitute organized block node,
and cannot make use of an instance count (only one instance can be created).
The plural syntax is used when allocating a substitute
unorganized block node. This syntax must have an expression
that evaluates to a positive, integral unit count.
Both syntaxes return a pointer to the newly created node memory
(on success) or a null pointer (on failure).
Child memory buffer/node handle allocation
NewChildExpressionSingular ::= newchild S? ( S? Expression S? , S?
(DataStructureType | OrganizedBlockType) S? )
NewChildExpressionPlural ::= newchild S? ( S? Expression S? , S?
UnorganizedBlockType S? [ S? Expression S? ] S? )
There are two syntaxes for allocating a child node. Both
of these can only be executed in the body of a Deserialize or
Serialize method or sub-function calls, and only as part of deserialization
or serialization. Furthermore, the pointer used
to specify the parent must trace up to the substitute node allocated
earlier in the function body with the new operator.
The singular syntax is used when allocating a child data
structure node or a child organized block node, and
cannot make use of an instance count (only one can be created). The
expression is the parent pointer (must point to organized block).
The plural syntax is used when allocating a child
unorganized block node. The first expression is the parent
pointer (must point to organized block). This syntax
must have a second expression that evaluates to a positive, integral unit
count.
Both syntaxes return a pointer to the newly created node memory
or handle (on success) or a null pointer (on failure).
Navigation Parenthetical Operators
NavigationExpressionSingular ::= (getparent | getnext | getprevious |
getsize | getbitsize | getuid | getname | getuidfromname |
getchildcount | getrelpos | gethlevel | getnodetype) S? ( S?
Expression S? )
NavigationExpressionPlural ::= getchild S? ( S? Expression S? , S?
Expression S? )
There are two navigation expression syntaxes. Both syntaxes expect the
first (or only) expression to evaluate to a pointer to one of the
following: a node handle, the first byte of a node in node memory, or a
null-terminated string. For all operators except getuidfromname,
the pointer used to specify the node must trace up to the top-level node of
the current BAR object instance; it cannot represent a node owned
by another BAR object instance.
For all singular operators except getuidfromname,
the system accepts as input a pointer to a node. For getuidfromname,
the system accepts as input a pointer to a null-terminated string,
to be interpreted as a construct name.
If the singular syntax for getparent, getnext,
and getprevious is unable to obtain a pointer to a node, a
null pointer is returned instead. If the singular
syntax for getname is unable to obtain a name, a null
pointer is returned instead. All other singular
operators return a negative value if unable to look up the
appropriate quantity for a node.
The plural syntax gets a pointer to one of the provided
nodes children. The second expression must evaluate to
an integer, which represents the zero-based child position
of the node to retrieve. If unable to obtain such a node, a null
pointer is returned instead.
These operators only look up information about nodes associated with the BAR
object instance that owns the function being called. Navigation
operators do not work with other BAR object instances.
Unary Mathematical Parenthetical Operators
UnaryMathExpression ::= (round | floor | ceil | abs | sgn | sin
| cos | tan | log10 | log | exp | sqrt | atan | rand | asin |
acos | sinh | cosh | tanh | asinh | acosh | atanh) S? ( S?
Expression S? )
The expression must be a scalar value. The operators round,
floor, ceil, sin, cos,
tan, log10, log, exp,
sqrt , atan, asin, acos,
sinh, cosh, tanh, asinh,
acosh, and atanh automatically cast the
expression to type double, and always return a double
type. The operator rand automatically casts the
expression to type long and always returns a long
type.
Binary Mathematical Parenthetical Operators
BinaryMathExpression ::= (atan2 | powr | modf) S? ( S? Expression S?
, S? Expression S? )
The two expressions must be scalar values. The operators
automatically cast the expressions to type double, and
always return a double type.
Prefix Increment/Decrement
PrefixIncrement ::= (++ | --) S? Expression
The expression must be an L-value (an expression that can serve
as the left side of an assignment operation). The expression must be of
integral or pointer type.
Unary Inversion Operators
UnaryInversion ::= (~ | ! | -) S? Expression
The expression must be a scalar value. The bitwise NOT
operator ('~') cannot be used with floating point types.
The logical NOT operator ('!') returns "longlong" type for
expression type "longlong," and "long" type
for all expression types other than "longlong."
Pointer Dereference
PointerDeref ::= * S? Expression
The expression must be a pointer to a non-void type. This
operator returns the value at the address stored in the
pointer.
Address-of
AddressOf ::= & S? Expression
The expression must be an L-value (an expression that can serve
as the left side of an assignment operation).
Typecast
TypeCastOperator ::= ( S? ((DataStructureType S? *?) | (void S? *)))
S? ) TypeCastExpression ::= TypeCastOperator S? Expression
The typecast operator returns an expression of the indicated type
(or pointer to the indicated type if an asterisk appears after
the type). The expression must be of similar enough type to the cast for
the conversion to work:
-
Expression is scalar: type must also be scalar
(non-void, non-structure; asterisk cannot appear).
-
Expression is pointer: type must also be pointer
(asterisk must appear).
-
Expression is structure: typecast not possible.
Multiply
Multiply ::= Expression S? * S? Expression
Both expressions must be scalar. If the types of the
expressions differ, the right expression is always converted to the lefts
type before operator evaluation.
Divide
Divide ::= Expression S? / S? Expression
Both expressions must be scalar. If the types of the
expressions differ, the right expression is always converted to the lefts
type before operator evaluation.
Modulo
Modulo ::= Expression S? % S? Expression
Both expressions must be integers. If the types of the
expressions differ, the right expression is always converted to the lefts
type before operator evaluation.
Add
Add ::= Expression S? + S? Expression
The left expression can be many things, but the right expression must be scalar.
Expression pairing has the following rules:
-
Left expression is scalar: This is a scalar addition
operation. If the types of the expressions differ, the right
expression is always converted to the lefts type
before operator evaluation.
-
Left expression is pointer: This is a pointer offset
operation. The left expression cannot be a pointer to void.
The right expression must be of integral type. The
addition operation is scaled: the pointer is moved by a
number of bytes equaling the size of the type pointed to by the left expression
multiplied by the value of the right expression.
The left expression cannot be a structure type.
Subtract
Subtract ::= Expression S? - S? Expression
The left and right expressions can be many things. Expression pairing has
the following rules:
-
Left expression is scalar: This is a scalar subtraction
operation; the right expression must also be scalar. If
the types of the expressions differ, the right expression is always
converted to the lefts type
before operator evaluation.
-
Left expression is pointer, right expression is scalar: This
is a pointer offset operation. The left expression
cannot be a pointer to void. The right expression must
be of integral type. The subtraction operation is scaled:
the pointer is moved by a number of bytes equaling the size of the type pointed
to by the left expression multiplied by the value of the right expression
multiplied by -1.
-
Left expression is pointer, right expression is pointer: This
is a pointer difference operation; the operator returns type long.
The pointers cannot be void and must point to the exact
same type. The subtraction operation is scaled:
the byte difference between the two pointers is then divided by the size of the
type pointed to by both pointers.
The left expression cannot be a structure type.
Shift Left
ShiftLeft ::= Expression S? << S? Expression
Both expressions must be integers. If the types of the
expressions differ, the left expression is always the returned
type.
Shift Right
ShiftRight ::= Expression S? >> S? Expression
Both expressions must be integers. If the types of the
expressions differ, the left expression is always the returned
type. If the left expression is of signed integer type,
the shifted-in bits are sign-filled; otherwise, the shifted-in
bits are zero-filled.
Relational Comparison
Relational ::= Expression S? (== | != | >= | <= | > |
<) S? Expression
Relational comparison operators return type long. The
left and right expressions can be many things. Expression pairing has the
following rules:
-
Left expression is scalar: This is a scalar comparison
operation; the right expression must also be scalar. If
the types of the expressions differ, the right expression is always
converted to the lefts type
before operator evaluation.
-
Left expression is pointer: This is a pointer comparison
operation; the right expression must be a pointer to the same type
as the left expression.
-
Left expression is structure: This is a structure
comparison operation; the right expression must be a structure
of the same type as the left expression. Only == and !=
operators can be used with structures; the remaining relational comparison
operators cannot be used.
Bitwise Operators
Bitwise ::= Expression S? (& | ^ | |) S? Expression
Both expressions must be integers. If the types of the
expressions differ, the right expression is always converted to the lefts
type before operator evaluation.
Logical Operators
Logical ::= Expression S? (&& | ||) S? Expression
The expressions must be of either scalar or pointer
type; they cannot be of structure type.
Assignment
Assignment ::= Expression S? = S? Expression
The left expression must be an L-value. The right
expression must come reasonably close in type to the first expression.
Expression pairing has the following rules:
-
Left expression is scalar: This is a scalar assignment
operation. The right expression must also be scalar.
If the types of the expressions differ, the right expression is always
converted to the lefts type
before operator evaluation.
-
Left expression is pointer to void: This is a pointer
assignment operation; the right expression must be a pointer
to any type.
-
Left expression is pointer to non-void: This is a pointer
assignment operation; the right expression must be a pointer
to the same type
as the left expression.
-
Left expression is structure: This is a structure
assignment operation; the right expression must be a structure
of the same type as the left expression. The result of this
expression is the left structure. The structure cannot contain pointers.
Assignment with Operation
AssignmentWithOperation ::= Expression S? (+= | -= | *= | /= | %=
| &= | ^= | |= | <<= | >>=) S? Expression
The left expression must be an L-value. The right
expression must come reasonably close in type to the first expression.
Expression pairing has the following rules:
-
Left expression is scalar: This is a scalar assignment
operation. The right expression must also be scalar.
If the types of the expressions differ, the right expression is always
converted to the lefts type before operator evaluation. For
bitwise, shift, and modulo assignment
operators, the right expression must be an integer.
-
Left expression is pointer: This is a pointer assignment
operation. Additional rules depend on the assignment operation.
-
Addition assignment: This is a pointer offset
operation. The left expression cannot be a pointer to void.
The right expression must be of integral type. The
addition operation is scaled:
the pointer is moved by a number of bytes equaling the size of the type pointed
to by the left expression multiplied by the value of the right expression.
-
Subtraction assignment: This is a pointer offset
operation. The left expression cannot be a pointer to void. The
right expression must be of integral type. The
subtraction operation is scaled:
the pointer is moved by a number of bytes equaling the size of the type pointed
to by the left expression multiplied by the value of the right expression
multiplied by -1.
-
Other type of assignment: Pointers cannot be used in any other
type of assignment-with-operation context.
The expressions cannot be of structure type.
Argument Separator
Comma ::= Expression S? , S? Expression
The expressions can be either scalar or pointer
type; they cannot be of structure type.
You do not need to include whitespace before or after operators
in order to distinguish them from most other I.F. components. However,
some operators, such as the '==' equality operator, are automatically assumed
if two equal signs are spliced together without whitespace.
See also: [Punctuators] [Operators]
[Keywords]
[Identifiers] [Numbers]
[String literals] [Remarks]
[Preprocessor directives] [Whitespace]
[Unrecognized characters]
|