The operators in Maia are generally identical to those in C, except that Maia adds bitslice and rotate operators, and some attribute operators. None of the C operators related to pointers are supported. Where the operators are identical, Maia and C have identical precedence and associativity. The primary difference from C is that most Maia operators may also be optionally sized and signed.
A 'signed' operator is one which sign-extends its inputs (which are expected to be 2's complement), and which may also possibly have a different behaviour from its unsigned counterpart (signed and unsigned comparisons have different behaviour, for example). A signed operator is specified by immediately following the base operator with a # character.
A sized operator is one which carries out an explicitly-sized operation; it is specified by immediately following the base operator (and the # character, if there is one) with a $ character and a decimal integer.
Various operators also have an ASCII equivalent form, as well as the standard form. Some examples of operators are:
+$10 10-bit integer addition /#$20 Signed 20-bit integer division <=# Signed integer less-than-or-equal .SLE Signed integer less-than-or-equal =# Sign-extending assignment
Note that assignment is an operator in both Maia and C (unlike VHDL and Verilog). From a hardware perspective, an assignment is an operation which is essentially identical to, for example, a shift. Assignments may therefore be signed, and sized, as for any other operator.
Floating-point operators use a slightly different format. These operators cannot be signed, and operate on (conceptually, at least) only three different data sizes: IEC60559 single, double, and extended. Floating-point operators are normally prefixed with .F, and the integer 1, 2, or 3, to specify the required size (the integer defaults to 2 if it is omitted). Some examples are:
.F3- Extended subtraction (or unary minus, depending on context) .F2* Double multiply .F1<= Single less-than-or-equal .FLE Double less-than-or-equal
When considering the data types (bit and var, and their specialisations) Maia's type system is essentially hardware-oriented. Operators generally specify precisely the required operation, rather than relying on the compiler to deduce the required operation from the surrounding context. Writing an expression in Maia is not unlike drawing a circuit diagram of the expression, where each logic unit must be correctly labelled.
However, in many circumstances it would be tedious to continuously write +$10, for example, where a data path is known to be exclusively 10-bit. Maia does therefore deduce the required operator size when a base unsized integer or logic operator is used. The procedure used is the normal one: for binary operators, for example, an unsized operator is assumed to be the same size as the larger of the two operands. Note that this is very different from the Verilog procedure for operator sizing, which involves an analysis from the leaves of the expression, up to the destination, and back again.
The form of an operator is potentially complex, and may be enclosed in parentheses if preferred. These operations are all identical:
var8 i, j, k; i = j -#$10 k; // 10-bit 2's complement subtraction i = j-#$10k; // the operators are tokens; whitespace is not required i = j (-#$10) k;