OPERATORS & PRECEDENCE ORDER
Updated: Feb 10, 2009


STRING CONCATENATION: + or & examples and tips

+ and & are treated the same:  b$ + c$ is the same as b$ & c$.

For efficiency, HotBasic uses one of three buffers for the result of each
concatenation statement.  RAM is allocated only if concatenation is used in a
program.  Typically, the same RAM allocations can be used over and over again
in string processing programs with many concatenation statements, eliminating
an OS-dependent RAM allocation/deallocation cycle for each statement at
run-time.

In sum, string processing speed is traded for a limitation to three result
buffers.  There are three buffers to handle a moderate amount of "nested
concatenation" such as

  a$ = MyFunction(b$ + c$) + ".bas"

or

  a$ = MyFunction + ".bas"

where MyFunction might itself contain one or more concatenation statements.
If MyFunction contains concatenation statements and these cause "rotation"
of the result buffers used, unexpected, unwanted results may be obtained.
Therefore, if HotBasic finds a user function (MyFunction above) as an item
in a concatenation statement, a WARNING message is produced, so you can focus
on the correctness of your result string in this situation.

Consider the special case

  a$ = a$ + b$

where concatenation is used to append b$ to a$.  This is very slow compared to

  a$.write(b$)

because the .Write method truly appends b$ directly to a$ without creating
an intermediate result string which is then copied to a$.  Likewise, with

  a$ = a$ + b$ + c$  'and so on

use of

  a$.append b$, c$   'and so on

is much faster.


OPERATORS AND PRECEDENCE ORDER: higher to lower

  ^ * / \ SHL SHR MOD INV + - [relational] NOT AND OR XOR

SHL is shift bits left.  5 SHL 3 = 40 = 5 * 8

SHR is shift bits right.  1000 SHR 2 = 250 = 1000 / 4

Please note that SHL and SHR may operate on floating values:

  2.5 SHR 1  'is 1.25; same as 2.5 / 2

  3.1 SHL 2  'is 12.4; same as 3.1 * 4

and also, values may be "shifted" by a floating amount:

  2.5 SHR 1.3

In short, SHR and SHL operators can use floating values (SINGLE, DOUBLE,
REAL10) and produce fractional, floating results.

Most often, coders will think of "shifts" as "bit shifts" applied to
non-floating values, e.g., 32-bit INTEGER (alias LONG) values.  For
conventional bit shifts, the ISHR and ISHL statements or functions should be
used.

MOD is modulus.  17 MOD 3 = 2 = remainder of 17 / 3

INV is inverse modulus.  Please see examples in HotTypes.bas

Relational operators used in conditional statements are

  =  <>  >  >=  <  <=

Each operator is located in a precedence order which is used only when a
quantity is both preceeded and followed by an operator.  For example, for b in
a * b / c, precedence order determines whether * or / is processed first.

Note: Some basic compilers have operators of "equal precedence".  A quantity
cannot be preceded and followed by relational operators; thus, there is no
precedence question among the relational operators.  

  a * b / c  multiplies a * b first, then divides by c
  a / b * c  multiplies b * c first, then divides a by (b * c)
  (a / b) * c  divides a by b first, then multiplies by c

The -P switch and the $EQUALPREC ON directive causes (*, /, \) and (+, -) to be
evaluated with equal operator precedence.  Default is OFF, as described above.
Please see Directives and Switches.

$EQUALPREC OFF (default):

  12 - 4 + 4 = 4
  1 / 2 * 2 = 0.25

$EQUALPREC ON

  12 - 4 + 4 = 12
  1 / 2 * 2 = 1


NECESSARY AND UNNECESSARY BRACKETS (parentheses)

Brackets are necessary only to over-ride normal operator precedence as shown
above.

  IF a = b AND a$ > b$ THEN

needs no brackets since any relational operator has a higher precedence than
any logical operator.  If (a = b) AND (a$ > b$) were written, there should be
no effect.

  IF (a OR b) AND (c OR d) THEN

needs brackets since OR has lower precedence than AND.  Indeed, without any
brackets, the above is equivalent to (unnecessary brackets added for clarity):

  IF a OR (b AND c) OR d THEN  'same as a OR b AND c OR d 


NESTED PRECEDENCE OVER-RIDES

An example of a nested operator precedence over-ride using () is:

  2 * (6 + (4 AND 2)) = 12

Above the precedence of * over + is deferred.  Further, nested in this
precedence over-ride is another -- + should be processed after AND.  Likewise,

  2 * ((4 AND 2) + 6) = 12

Please also be aware that different compilers may return different results for
the same numeric expression.  And both compilers may be right!  Why?  The
compilers may vary in many ways -- rules of precedence, how floating and 
non-floating values are handled, rules for rounding, etc.  The only thing that
matters is that *you* say the result is correct.  So for any compiler, checking
your work is essential.


Copyright 2003-2009 James J Keene PhD
Original Publication: Oct 8, 2003
