Integrated Development
Environment (IDE) Documentation:

Expressions

Expressions are strings of variables, function calls, constants, parenthesis, and operators which indicate what sort of calculation the program should do. Expressions are analyzed by the compiler according to the following table. Operations at the top of the table are a higher priority than those farther down:

Operands Evaluated Meaning
func( args ),
port[ expr ],
( expr )
Left-to-right Function call,
port identifier,
grouping operator
not, -, + Right-to-left Unary operands
*, /, % Left-to-right Multiplication, division, modulo
+, - Left-to-right Addition, subtraction
<, <=, >, >= Left-to-right Less than, less than or equal to, greater than, greater than or equal to
==, != Left-to-right Equal to, not equal to
& Left-to-right Bitwise AND
^ Left-to-right Bitwise XOR
| Left-to-right Bitwise OR
and Left-to-right Logical AND
xor Left-to-right Logical XOR
or Left-to-right Logical OR
cond ? true : false Left-to-right Ternary operator

In other words, the expression X + 5 * -2 would be calculated as if the following grouping parenthesis were present: X + (5 * (-2)). The two would be negated first, then the multiply would be executed, and then the addition.

Note:

Few people actually take the time to memorize the above table beyond the bits we learned in algebra (i.e. multiply happens before addition). I know I didn't. If you think there is any reasonable chance that someone reading your code will be confused by how an expression will be parsed, then use parenthesis! These will make your code far more legible, even if they do not affect execution.

Less-Common Operators

Although it's safe to say that you will recognize many of the above operators, some of them may be a little less familiar. Here's a quick run-down of the ones you may not have encountered before:

func( args )

Function calls do specific tasks and return a value based on the function name and arguments to the function. The flowchart compiler supports one general-purpose function (abs), and five Modbus request related functions (MBGetDI, MBGetDO, MBGetInput, MBGetHold, and MBGetErr). For more information on functions, see the function reference in the appendix.

expr1 / expr2

The forward-slash symbol (/) indicates division (since there's no ÷ symbol on the keyboard).

expr1 % expr2

The percent-sign symbol (%) indicates modulo, which is the remainder after a division is performed. 23 % 5 will evaluate as 3, since 5 goes into 23 four times and leaves a remainder of 3.

expr1 <= expr2, and expr1 >= expr2

The comparison operators <= and >= indicate less-than-or-equal-to and greater-than-or-equal-to, respectively (since there are no ≤ and ≥ symbols on the keyboard). expr1 <= expr2 will evaluate to 1 if expr1 is less than or equal to expr2, and 0 otherwise. expr1 >= expr2 will evaluate to 1 if expr1 is greater than or equal to expr2, and 0 otherwise.

expr1 == expr2, and expr1 != expr2

The comparison operators == and != indicate equal-to and not-equal-to, respectively. expr1 == expr2 will evaluate to 1 if expr1 is equal to expr2, and 0 otherwise. expr1 != expr2 will evaluate to 1 if expr1 is not equal to expr2, and 0 otherwise.

Boolean Operators

The following operators are boolean (true/false) in nature. Since C doesn't have a boolean type, it uses 0 to represent false and 1 to represent true (as you may have noticed in the comparison operators, above). Integer values other than 1 or 0 are also treated as true.

not expr

Logical not inverts a boolean value. If expr is true, then not expr will evaluate to false. If expr evaluates to false, then not expr will evaluate to true. Traditionally, C uses ! to indicate "logical not", but not seemed more clear.

expr1 and expr2

The logical operator and evaluates to true if both expr1 and expr2 are true. It will evaluate to false if either argument is false. Traditionally, C uses && to indicate "logical and", but and seemed more clear.

expr1 or expr2

The logical operator or evaluates to true if either expr1 or expr2 are true. It will evaluate to false if both arguments are false. Traditionally, C uses || to indicate "logical or", but or seemed more clear.

expr1 xor expr2

The logical operator xor performs what is known as an "exclusive or". It evaluates to true if either one, and only one of expr1 and expr2 are true. It will evaluate to false otherwise. Traditionally, C doesn't have a "logical xor" operator.

To sum up:

expr not expr
false true
true false

expr1 expr2 expr1 and expr2 expr1 or expr2 expr1 xor expr2
false false false false false
false true false true true
true false false true true
true true true true false

The Coyote IDE compiler uses "eager evaluation" to evaluate boolean operations.

Bitwise Operators

The bitwise operators work the same way as and, or, and xor, except that they operate on each bit within the arguments. In other words, to calculate expr1 & expr2, the zeroth bit of the result is calculated by performing an and operation on bit zero of expr1 and bit zero of expr2. The same is done for bit one, the bit two, etc., all the way up to bit 15.

The Coyote IDE version of C uses the traditional C symbols for these operators.

&

& is the bitwise version of and.

|

| is the bitwise version of or.

^

^ is the bitwise version of xor.

Ternary Operator

The ternary operator is a convenient way of picking one value or another based on the value of a third. In other words, the expression:

cond_expr ? true_expr : false_expr

would first evaluate the cond_expr expression. If this evaluated to true, then the true_expr expression would be evaluated and used as the resulting expression. If it evaluated to false, then false_expr would be evaluated and used as the resulting expression.

The Coyote IDE compiler uses "lazy evaluation" to evaluate ternary operations.

Still confused? Here's a simple example. Let's suppose that we wanted one of our flowchart blocks to add one to a count, but we didn't want that count to ever get above 99. First, let's make sure that the variable is defined, and we'll also take a moment to define a constant to hold this maximum:

Traditionally, constants are named in all capital letters with underscores ("_") used to separate words. This helps differentiate them from variables.

We could use a conditional block to test whether we need to update the count, but since we have the ternary operator, let's just use that. Let's create a variable block to update the value of the variable Counter. Once we place the block, the editor will pop up a dialog to describe what we want done:

Note that I used parenthesis, not because they were required, but because they made the expression more clear. This block sets a new value for the variable Counter. That new value depends on whether Counter was already (i.e. the current value of Counter) was greater than or equal to our maximum value. If the value is already too high, then Counter gets the value MAX_COUNT, otherwise it is incremented (gets a value of Counter + 1).

String Expressions

Serial output blocks may contain either a constant string or a string expression. Constant strings are pretty simple as they output the string you entered exactly. The expression option, however, is far more interesting as it allows you to output more dynamic content.

String expressions are assembled from string constants, parenthesis, the + operator, the FormatInt function, and even the ternary operator. The other operators that work for integer values cannot be applied to strings.

Operands Evaluated Meaning
FormatInt( args ),
( expr )
Left-to-right int formatter,
grouping operator
+ Left-to-right Concatenation
cond ? true : false Left-to-right Ternary operator

String Constants

String constants may be entered in two ways; either directly into a string expression by enclosing it in double-quotes, or by creating a const string value in the Variables and Constants spreadsheet (without quotes).

String constants may not be blank. There has to be at least one character in any constant.

String constants entered in quotes (this does not apply to constants entered in the spreadsheet) may include some special "escaped" characters:

Code Meaning
\" Quote (0x22)
\\ Backslash (0x5C)
\n Carriage-return, line-feed (0x0D, 0x0A)
\t Tab (0x09)
\octal_num ASCII code
\xhex_num ASCII code

If you're familiar with C programming, you'll note that the Coyote IDE interprets \n as CRLF instead of the traditional CR. To output just a carriage return, use \x0D.

The Concatenation Operator (+)

When used in a string expression, the + operator concatenates strings together.

For example, suppose you had a serial output block configured as:

If the variable Counter had a value of 7, then this block would output: Events: 7 followed by a carriage return (0x0D) and a line feed (0x0A).

The FormatInt Function

The FormatInt function converts an integer to a string so it can be output within a serial output block. This is the way to output the value of a variable. Trying to concatenate an integer directly to a string (i.e. without using the FormatInt function) will result in an error.

The syntax for calling the FormatInt function is:

FormatInt( value_expr [ , opt_param=N ... ] )

The optional parameters may include zero or more of the following:

Parameter Value Default Meaning
Width 0 - 15 0 Minimum number of characters to reserve
Commas 0 - 1 0 1 adds comma separators
RightJ 0 - 1 0 1 right-justifies text
ZeroF 0 - 1 0 1 pads with 0s instead of spaces
FSign 0 - 1 0 1 forces a sign character

Parameters RightJ and ZeroF are really only interesting when the Width parameter has been set.

Ternary Operator

The ternary operator can be applied to string expressions in exactly the same way it is applied to integer parameters. The only thing to keep in mind here is that the condition needs to be boolean (an integer value) and that the true and false expressions need to evaluate to strings.

For example, let's say we need to output a string but we want to maintain good grammer when it comes to plurals. i.e. If the variable, Events, was 5 then we would want to output 5 events, but if Events was 1 then we would want to output 1 event.

Here's a serial output block configuration that would do just that:

Note the parenthesis. The ones around Events == 1 are just for clarity, but the ones around the ternary expression are not. This is because the operator + has a much higher priority than the ternary operator.

In other words, without the outer parenthesis, the compiler will try to combine the results of the FormatInt call with the (Events == 1) comparison. This will fail because the comparison has a boolean result and + cannot be used to combine strings and integers.

Note:

Resist the urge to use the ternary operator to handle plurals by either adding an s ("s") or nothing (""). Remember, string constants must contain at least one character, so "" is invalid.

SerialIn and ParseInt

Both the SerialIn and ParseInt functions can be used in variable blocks of a flowchart, but we consider this too advanced a topic for that tool. If you need to parse serial input, we strongly recommend that you create your programs with the C source editor, instead.