Langur uses the following, in order of descending precedence.
category  operators  associativityL/R 

after (for function calls and indexing)  () [] 
leftL 
prefix    
exponent  ^ ^/  rightR 
product  x / \ rem mod 
leftL 
sum  +   leftL 
range  .. to  leftL 
concatenate  ~ (tilde)  leftL 
less/greater  < <= > >= <? <=? >? >=? 
leftL 
logical negation  not not? 

equality  == != ==? !=? 
leftL 
logical and  and nand and? nand? 
leftL 
logical equivalence  xor nxor xor? nxor? 
leftL 
logical or  or nor or? nor? 
leftL 
assignment  =  rightR 
See the numbers page for math operator descriptions.
Most infix operators* can be used as combination operators with the equal sign. For example, writing .x += 1 is the same as writing .x = .x + 1.
It is as though the righthand is wrapped in parentheses, so that .x x= .a + .b is the equivalent of .x = .x x (.a + .b), not .x = .x x .a + .b.
*not the comparison or assignment operators
Normal operators treat null as an ordinary value (don't favor propogating null). Testing null == null returns true and null == false returns false.
Operators ending with ? are database operators. For these, if either side is null, the result is null. Testing null ==? anything returns null.
The and, or, nand and nor operators are shortcircuiting.
Database operators are shortcircuiting in a different manner (only if the left value is null). This includes all operators that end with ?, such as and?, nor?, ==?, xor?, etc.
Testing NaN == NaN returns false, and NaN ==? null returns null. The isNaN() function may be helpful here.
Items of the same type (arrays, hashes, or ranges) may be directly compared for equality or inequality.
These comparisons are not affected by the NaN issue. That is, NaN within composite items compare as being the same. So, NaN != NaN, but [NaN] == [NaN].
Whereas 1 == 1.0, within a composite comparison, this is not true, so that [1] != [1.0].