A boolean expression in XJEase is an expression that is considered to evaluate to either false or true. Boolean values are represented by an integer, where 0 is false and any other value is considered to be true. The standard Globals.xje that is included in all new projects has two constants defined, FALSE and TRUE.
In XJEase we have three logical operators: NOT represented by !, AND represented by &&, and OR represented by || that operate on boolean values.
This is an example of some XJEase that uses the && operator:
IF x > 1 && x < 10 THEN PRINT("x is in range\n"); END;
Unlike many other languages, the && and || operators in XJEase do not short circuit. For example, in the expression above, if x is equal to 0, then the left hand side of the expression is FALSE, so there is no need to evaluate the right hand side where we check for x being less than 10 – we already know x is outside the range. Similarly for ||, if the left hand side of the expression is TRUE, then there is no need to evaluate the right hand side – we know that the whole expression must be true. XJEase, however, does not short-circuit – it always evaluates both sides.
Originally this was not an issue – there was nothing that could be used in an expression that had any side effects, so whether the second part was evaluated or not did not matter (apart from a minor performance difference). However, it is now possible to call a function inside an expression. This means that we can now observe whether the right hand side is evaluated or not, and it may matter whether a function is called or not. In XJTAG v3.5 there are some particular scenarios where it is important not to evaluate the right hand side if the left hand side evaluates to FALSE.
In XJTAG v3.4.9, we introduced two new operators: &&? and ||?. These are identical to && and ||, except that: with &&? if the left hand side evaluates to FALSE, or with ||? if the left hand side is TRUE, then the right hand side is not evaluated. Although these operators were introduced to support some new features in 3.5, they are more generally useful and supporting them in v3.4 means we can start using them in our library files earlier.
Here is an example where we prompt the user for a serial number, and if it begins with the letter ‘A’, we know that the board we’re testing is a certain variant.
serialNumber := INPUTBOX("Serial number", "Please enter a serial number", ""); IF WIDTHOF(serialNumber) > 0 &&? serialNumber = "A" THEN PRINT("Device is variant 'A'\n"); END;
If we replaced the &&? with &&, and then the user entered an empty string, we would get a runtime error accessing the first character of the string. Using the short circuiting operator means that if the string length is 0, we don’t try and evaluate the right hand side.