Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Precedence

When an expression has no parentheses, precedence decides which operator applies first: 2 + 3 * 4 is 14 because * binds tighter than +. Most of tiko's order is the one you know from arithmetic, but a few places differ from other languages, and those are where bugs hide.

'' Each line shows an expression and its value, then the same
'' expression with the grouping tiko gives it written out.
sub Show( byval e1 as ustring, byval v1 as float64, _
          byval e2 as ustring, byval v2 as float64 )
    print left( e1 & space( 14 ), 14 ); "= "; left( v1 & space( 6 ), 6 ); _
          left( e2 & space( 18 ), 18 ); "= " & v2
end sub

'' ^ binds tighter than unary minus, and groups to the left.
Show( "-2 ^ 2", -2 ^ 2, "-(2 ^ 2)", -( 2 ^ 2 ) )
Show( "2 ^ 3 ^ 2", 2 ^ 3 ^ 2, "(2 ^ 3) ^ 2", ( 2 ^ 3 ) ^ 2 )

'' * and / come before \, which comes before mod.
Show( "7 \ 2 * 2", 7 \ 2 * 2, "7 \ (2 * 2)", 7 \ ( 2 * 2 ) )
Show( "9 mod 5 \ 2", 9 mod 5 \ 2, "9 mod (5 \ 2)", 9 mod ( 5 \ 2 ) )

'' Shifts bind tighter than + and -.
Show( "1 shl 2 + 3", 1 shl 2 + 3, "(1 shl 2) + 3", ( 1 shl 2 ) + 3 )

'' Comparisons bind tighter than and, or and not.
dim as int32 n = 6, a = 3, b = 0
Show( "n and 1 <> 0", n and 1 <> 0, "n and (1 <> 0)", n and ( 1 <> 0 ) )
Show( "not a = b", not a = b, "not (a = b)", not ( a = b ) )
print

'' & joins after the arithmetic, and comparisons come after &.
print """x"" & 1 + 2 = ""x3"" is "; cbool( "x" & 1 + 2 = "x3" )

'' and binds tighter than or.
print "true or false and false   = "; cbool( true or false and false )
print "true or (false and false) = "; cbool( true or ( false and false ) )

'' andalso and orelse share one level and group left to right.
print "true orelse false andalso false   = "; _
      cbool( true orelse false andalso false )
print "(true orelse false) andalso false = "; _
      cbool( ( true orelse false ) andalso false )

Output

-2 ^ 2        = -4    -(2 ^ 2)          = -4
2 ^ 3 ^ 2     = 64    (2 ^ 3) ^ 2       = 64
7 \ 2 * 2     = 1     7 \ (2 * 2)       = 1
9 mod 5 \ 2   = 1     9 mod (5 \ 2)     = 1
1 shl 2 + 3   = 7     (1 shl 2) + 3     = 7
n and 1 <> 0  = 6     n and (1 <> 0)    = 6
not a = b     = -1    not (a = b)       = -1

"x" & 1 + 2 = "x3" is true
true or false and false   = true
true or (false and false) = true
true orelse false andalso false   = false
(true orelse false) andalso false = false

From tightest to loosest:

LevelOperators
1^
2unary -
3* /
4\
5mod
6shl shr
7+ -
8&
9= <> < <= > >=
10not
11and
12or
13xor
14andalso orelse

Operators on one level group from left to right.

The places that catch people out, all shown in the example:

  • -2 ^ 2 is -4. ^ binds tighter than the minus sign, so it means -(2 ^ 2). And 2 ^ 3 ^ 2 groups to the left, giving 64, not 512.
  • \ and mod sit below *. 7 \ 2 * 2 is 7 \ 4, which is 1, not 6. 9 mod 5 \ 2 is 9 mod 2, which is 1, not 2.
  • Shifts bind tighter than +. 1 shl 2 + 3 shifts first, giving 7.
  • Comparisons bind tighter than and. n and 1 <> 0 compares first and gives 6, not the bit test it looks like. Write ( n and 1 ) <> 0.
  • not is looser than comparisons. not a = b means not ( a = b ).
  • andalso and orelse share a level. They group left to right, so true orelse false andalso false is ( true orelse false ) andalso false, which is false.

Pitfall

In most languages and binds tighter than or, and that is true here for and and or. It is not true for andalso and orelse. Put parentheses round every condition that mixes the two.

Activities

  1. Predict 2 + 3 * 4 ^ 2 \ 5 and check it.
  2. Print cbool( ( n and 1 ) <> 0 ) for n = 6 and n = 7, then the same without the parentheses, and explain the difference.