Precedence Chart
         The precedence of operators in expressions is as follows:
        
        
          
           
            
             
          
           
        
Thus 2+6*3 means 2+(6*3) rather than (2+6)*3. Operators on the same line have equal precedence and are evaluated left to right.
        
The use of explicit parenthesis when mixing anything other than the four main arithmetic
        
The equals symbol ('=', or ':=') used in an assignment statement is not an operator, just part of the syntax of the language, whereas it is an operator (same as '==') when used mid-expression. You may prefer to use the ':=' and '==' forms to avoid any potential ambiguity, albeit such things are normally pretty self-evident from context anyway.
       
        
Technically the ellipsis operator (..) within a slice has the lowest possible precedence, so that eg
        
On a related note,
       
Other programming languages may have subtle differences in precedence. For instance, in python 'or' has a lower precedence than 'and', so take that into account when translating some python code and Phix starts demanding extra parenthesis. In python the 'not' operator has a lower precedence than '+', so
       
Note that phix does not really do associativity handling: of course unary operators are right associative, because they have to be, but everything else is left associative. eg
       
      
     | parenthesis/function calls | ||
| subscripts/slices . | ||
| unary- unary+ not ~ | (pUnary = 10) | |
| * / | (pMuldiv = 9) | |
| + - | (pAddsub = 8) | |
| >> << | (pBitshift = 7) | |
| & | (pConcat = 6) | |
| && || | (pBitops = 5) | |
| < > <= >= | (pRelops = 4) | |
| = != | (pEqorne = 3) | |
| and or xor | (pLogop = 2) | |
| { , , , } | (pAllops = 0) | 
Thus 2+6*3 means 2+(6*3) rather than (2+6)*3. Operators on the same line have equal precedence and are evaluated left to right.
The use of explicit parenthesis when mixing anything other than the four main arithmetic
( * / + - ), 
        unary ( + - not ~ ) and concatenation ( & ) operators is generally advised, 
        except when doing so would be blatently gratuitous, overly tedious, and/or completely unnecessary.
        The equals symbol ('=', or ':=') used in an assignment statement is not an operator, just part of the syntax of the language, whereas it is an operator (same as '==') when used mid-expression. You may prefer to use the ':=' and '==' forms to avoid any potential ambiguity, albeit such things are normally pretty self-evident from context anyway.
In many other languages '=' is an operator that returns the result of the assignment, allowing and encouraging the infamous and notoriousParenthesis is required to mixslip-up, an otherwise legal but often mis-typed if(a=b), which has made many a programmer desperately resort to coding all their tests in an awkward and un-natural 'backward' style, eg if(a==b), which obviously cannot possibly help one iota when comparing two variables anyway. if('Y'==ch)
In contrast, the only way to achieve an assignment mid-expression in phix would be via a function call, which cannot modify local variables, and due to short-circuit evaluation may not even get called.
Hence that sort of thing is generally discouraged, that is when aiming for clear, intuitive, and readable code. I would also note that it is easier to debug, plus (with a better name) it can be easier/faster to comprehend, while having no real additional overhead compared to the un-named temp that the compiler would otherwise quietly use anyway - the only overhead is that some symbol table entry will have say "padding" rather than -1 as a name, and any ex.err will/may have an extra potentially helpful line or two. integer tmp = <expr>; if tmp
In practice, for instance, pLogop causes parsing ofto pause at the a and b and cstage, whereas (an outer) pAllops triggers left-association, ie a and b. Note that I agonised over setting the precedence levels of && || << and >>, eventually copying from Python/C/JavaScript only to find several expressions still required parenthesis, eg (a and b) and cis treated as hi << 16 + lorather than the hi << (16 + lo)that was needed and initially expected. Conversely, the (usually) equivalent (hi << 16) + loworks the same as hi << 16 || loeven without the parenthesis, and likewise (hi << 16) || lois the same as lo || hi << 16. lo || (hi << 16)
Note thatis a && b != cas per Python, rather than (a && b) != cas per C/JavaScript. a && (b != c)
Aside: watch out forhitting 32-bit limits (ie truncating/masking inputs) that ||does not. +
The eagle-eyed may have spotted the leap from 0 to 2 over a missing 1. Originally it was intended for "and" to have a slightly different precedence than "or" (/"xor") but in the end I decided that forcing parenthesis was simply better. (Even with Python/C/JavaScript operator precedence tables to hand, I still can’t quite say which should be lower/higher. Don’t tell me. No, seriously, just don’t bother telling me, and if you try I will stick my fingers in my ears and start humming.)
Should you ever need to refer to this table to figure out what something means or should do, then for the love of Pete please add the appropriate paranthesis to the code in question. Needing too many parenthesis is a pretty sure sign that hoisting (common) subexpressions out into appropriately named temporary variables is the good and decent thing to do. Extra parenthesis will never make anything slower, except where doing the right thing and getting the right answer is slower than doing the wrong thing and getting the wrong answer.
and, or, and xor
        in an expression. If the compiler finds "a or b and c" it will not assume 
        "(a or b) and c" over "a or (b and c)" (or vice versa) but demands that
        you state exactly which you mean. Most programmers have at one point or another coded something apparently "obvious" such as
    if a and b
    or c and d then
       or
    if  a or b 
    and c or d then
        and then been surprised when (in some other programming language) it does not work. Other compilers may treat them as
    (a and b) or (c and d)  -- which is probably as intended
    (a or (b and c)) or d   -- somewhat less likely to be as intended
    ((a and b) or c) and d  -- even ""
    ((a or b) and c) or d   --  ""
        To avoid such issues, phix simply forces the programmer to supply enough additional explicit parenthesis until everything is completely unambiguous, eg/ie
    if (a and b)
    or (c and d) then
        or
    if  (a or b)
    and (c or d) then
        The higher precedence of not means that (eg) not a or not b and (not a) or (not b)
        are equivalent, making the extra parenthesis strictly unnecessary, however I consider the latter good practice, plus be warned that phix is 
        more like C-based languages, which treat (!a==b) as ((!a)==b) whereas in Python 
        (for example) the precedence of the otherwise equivalent "not" is much lower, so not a == b is treated as 
        not (a == b) - fwiw, I would agree that having not a == b behave exactly the same
        as a != b is not particularly helpful, so Phix don’t do dat. Mind you, it’s not quite as whacky
        as PHP and Ruby having && and and, likewise || and 
        or, as two (pairs of two) operators with the same meaning but different precedences (wow!).
        [In Phix, & is the concatenation operator, there are no | or ^ or ** operators and no single-character alternatives to and/or/xor.
         The && is bitwise whereas "and" is logical, likewise || and "or".]
        Technically the ellipsis operator (..) within a slice has the lowest possible precedence, so that eg
s[i-1..i+1] is 
        s[(i-1)..(i+1)] and not some nonsense like s[i-((1..i)+1)] which is of course meaningless and illegal.
        On a related note,
"a*(b/c)" and "(a*b)/c" are mathematically equivalent, however 
        precision limits of the physical hardware may mean they give very different results, especially for partial results that approach or exceed 
        the floating point hardware limits.
        In practice the compiler treats "a*b/c" as "(a*b)/c", however in general that is an 
        implementation detail that should not be overly relied on - should one day some bright spark invent a safe and simple method to automatically 
        minimise precision loss in the un-parenthesised case, I would take it. (I did once work with an actual Dr Watson, PhD in Nuclear Physics, no
        less, who spent many weeks on almost exactly such a routine, that I never quite managed to understand, but it’s all long gone now.)
       Other programming languages may have subtle differences in precedence. For instance, in python 'or' has a lower precedence than 'and', so take that into account when translating some python code and Phix starts demanding extra parenthesis. In python the 'not' operator has a lower precedence than '+', so
idx + not flag + offset is treated as idx + not (flag + offset), 
        quite unlike the Phix interpretation which is idx + (not flag) + offset. 
        My recommendation is to use as much parenthesis as you can bear, and when it gets too much that is as good an excuse as any to break the 
        expression down into more manageable pieces. Besides, storing partial results in appropriately named variables can not only make the intent 
        much clearer but also make debugging significantly easier and faster, and does not normally incur any additional penalty whatsoever 
        over the hidden unnamed temporary variable that the compiler would otherwise use anyway (except as noted at the very end of the 
        ternary ops technicalia drop-down).
       Note that phix does not really do associativity handling: of course unary operators are right associative, because they have to be, but everything else is left associative. eg
    a*b/c*d/e is ((((a*b)/c)*d)/e)
    a*-b/c*not d/e is ((((a*(-b))/c)*(not d))/e)
    a == b == c is (a == b) == c    -- (unlike Python in which it is a == (b == c)...)
        See also Perl/Raku operators
       