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:
| Level | Operators |
|---|---|
| 1 | ^ |
| 2 | unary - |
| 3 | * / |
| 4 | \ |
| 5 | mod |
| 6 | shl shr |
| 7 | + - |
| 8 | & |
| 9 | = <> < <= > >= |
| 10 | not |
| 11 | and |
| 12 | or |
| 13 | xor |
| 14 | andalso orelse |
Operators on one level group from left to right.
The places that catch people out, all shown in the example:
-2 ^ 2is -4.^binds tighter than the minus sign, so it means-(2 ^ 2). And2 ^ 3 ^ 2groups to the left, giving 64, not 512.\andmodsit below*.7 \ 2 * 2is7 \ 4, which is 1, not 6.9 mod 5 \ 2is9 mod 2, which is 1, not 2.- Shifts bind tighter than
+.1 shl 2 + 3shifts first, giving 7. - Comparisons bind tighter than
and.n and 1 <> 0compares first and gives 6, not the bit test it looks like. Write( n and 1 ) <> 0. notis looser than comparisons.not a = bmeansnot ( a = b ).andalsoandorelseshare a level. They group left to right, sotrue orelse false andalso falseis( true orelse false ) andalso false, which is false.
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
- Predict
2 + 3 * 4 ^ 2 \ 5and check it. - Print
cbool( ( n and 1 ) <> 0 )for n = 6 and n = 7, then the same without the parentheses, and explain the difference.