BARfly Help - BAR Implementation File Reference - Fundamental Components

  Operators

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 node’s 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 left’s 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 left’s 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 left’s 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 left’s 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 left’s 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 left’s 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 left’s 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 left’s 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 left’s 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]


BARfly Help Copyright © 2009 Christopher Allen