ModMultiSim help v3.07 - 5.2. Phrase Structure

Download manual: HTML

5.2. Phrase Structure

Expressions

An expression is a sequence of operators and operands that specifies the computation of a value.

The precedence of operators decreases from the top of the list of operators (see the "Operators" section under Lexical Structure section), to the bottom. So the primary_expr operator ( ) has highest precedence and the logical_or has the lowest. The unary_sign ( - + ) operators have higher precedence than the binary_sign ( - + ) operators.

Operators on the same line in the list of operators have the same precedence.

For binary operators with the same precedence, evaluation occurs from left to right.

The ModMultiSim compiler evaluates operands of the mathematically associative and commutative operators + * & ^ | in the order in which they appear (i.e. it does not rearrange the order of evaluating several additions, multiplications or bitwise operations at the same level).

The usual arithmetic conversions are performed.

  1. Primary Expressions - grouping operator

    primary_expr:
            identifier 
            constant
            CycleTime
            TimeNow
            left_parenth bitwise_expr right_parenth
          

    left_parenth : ( 
    right_parenth :   )
          

    Use the left_parenth and right_parenth operators to signal the start and end of the expression to be evaluated. This will change the order of evaluation, or simply clarify the order if it is the same as the order would be without the ( ). For example:

             3 * ($4 - 10) / 2

    will cause ModMultiSim to do the subtraction before the multiplication or division.

     

  2. Bitwise Complement Expressions - complement operator

    bitwise_complement_expr:
            bitwise_complement ? primary_expr
          

    bitwise_complement : ~
          

    The bitwise_complement operator manipulates bits in integer types. (This description assumes an understanding of the way integers are represented in binary.)

    The bitwise_complement operator has only one operand, which must have arithmetic type. If the operator is applied to a float or double, it will be converted to an integer first.

    The ~ operator returns the complement of its operand, that is to say, it converts each bit containing a 1 to zero and vice versa. As the next example shows, taking the complement of -1 yields the result 0 since -1 is represented in binary as 16 1s (in an integer of size 16 bits). The second example yields the result 8, when doing the complement of -9. (This will be clearer if you are familiar with the representation of numbers in binary.)

             ~(-1):
                1111111111111111   : -1
                0000000000000000   : result 0
             ~(-9):
                1111111111110111   : -9
                0000000000001000   : result 8

    In a bitwise_complement_expr the bitwise_complement ~ operator is optional.

    For ways to use the bitwise_complement ~ operator see Handling Control/Status Flags in Holding/Input registers.

     

  3. Term Expression - multiplicative operators

    term_expr : 
            bitwise_complement_expr {multiplier bitwise_complement_expr}* 
          

    multiplier : * | / | %
          

    The * operator returns the product of its operands.

    The / operator returns the quotient from the division of the first operand by the second.

    The % operator returns the remainder from the division of the first operand by the second.

    Both operands of these operators must have arithmetic type.

    In a term_expr there may be zero or more of the multiplier bitwise_complement_expr expressions. For example, the following are all valid term_exprs:

             4 * 9 
             4 * 9 / (3 / 6)* 8
             4 * 9 / (3 / 6 *(8 * 9 /2))* 8

  4. Numeric Expression - additive operators

    numeric_expr :
            unary_sign? term_expr {binary_sign term_expr}*
          

     unary_sign : + | -
          

     binary_sign : + | -
          

    The unary_sign operators have one operand. The unary_sign + operator returns the value of its operand (i.e. it has no affect). The unary_sign - operator returns the negative of its operand.

    The binary_sign operators have two operands, both of arithmetic type. The binary_sign + operator returns the sum of its operands. The binary_sign - operator returns the difference between the operands.

    In a numeric_expr the unary_sign is optional. There may be zero or more of the binary_sign term_exprs. For example, the following are all valid numeric_exprs:

             -4 - 9
             -4 + (9 +-3) / 8 * 6

  5. Bitwise Shift Expression - shift operators

    bitwise_shift_expr :
            numeric_expr {bitwise_shift numeric_expr}*
          

     bitwise_shift : << | >>
          

    The bitwise_shift operators manipulate bits in integer types. If applied to a float or double, it will be converted to an integer first. (This description assumes an understanding of the way integers are represented in binary.)

    The bitwise_shift operators have two operands, both of arithmetic type. These operators shift their left operands by the number of bit positions specified by their right operand.

    The << operator shifts the bits to the left and fills vacated bits on the right with 0s. The >> operator shifts the bits to the right and fills the vacated bits on the left with 0s if the left operand is positive, or it fills it with 1s if the left operand is negative (this is to preserve the sign).

    In the following example, the result of the shift is 28 (shifting to the left by 2 is the same as multiplying by 4 and shifting to the right by 2 is the same as dividing 4). The binary representation below shows the shift.

             7 << 2:
                0000000000000111   : 7
                0000000000011100   : result 28

    There may be zero or more of the bitwise_shift numeric_exprs. For example, the following are valid bitwise_shift_exprs:

             7 << 2 + $12 + ~($201 / 2)
             7 << 2 << $1

    For ways to use the bitwise_shift operators see Handling Control/Status Flags in Holding/Input registers.

  6. Bitwise And Expression - bitwise-and operator

    bitwise_and_expr :
            bitwise_shift_expr {bitwise_and bitwise_shift_expr}*
          

     bitwise_and : &
          

    This operator manipulates bits in integer types. If applied to a float or double, it will be converted to an integer first. (This description assumes an understanding of the way integers are represented in binary.)

    The bitwise_and operator has two operands, both of arithmetic type. It sets bits to 1 only if the value of the corresponding bit in both left and right operands is 1.

    For example, the following expression yields 0 since none of the corresponding bit positions in the binary representation of 6 and 8 are both 1.

             6 & 8:
                0000000000000110    : 6
                0000000000001000    : 8
                0000000000000000    : result 0

    In the next example, the result is 4 since the third bit position in each operand is a 1-bit, so will be set to 1 in that bit position, which is 4 in decimal radix.

             6 & 4
                0000000000000110    : 6
                0000000000000100    : 4
                0000000000000100    : result 4

    There may be zero or more of the bitwise_and bitwise_shift_exprs. For example, the following are valid bitwise_and_exprs:

             7 & 2 & $7000 
             5 & $1 << 1 & ($6 - 1)

    For ways to use the bitwise_and & operator see Handling Control/Status Flags in Holding/Input registers.

  7. Bitwise Expression - bitwise-or operators

    bitwise_expr :
            bitwise_and_expr {bitwise_or bitwise_and_expr}*
          

     bitwise_or :
            inclusive_or
            exclusive_or
          

    inclusive_or : |
    exclusive_or :   ^
          

    The bitwise_or operators manipulate bits in integer types. If applied to a float or double, it will be converted to an integer first. (This description assumes an understanding of the way integers are represented in binary.)

    These operators have two operands, both of arithmetic type.

    The inclusive_or | operator sets a bit to 1 if the value of the bit in the same bit-position of either or both operands is 1.

    The exclusive_or ^ operator sets a bit to 1 if the bit-position is set to 1 in one of the operands and only one.

    In the following example, the result of the inclusive-or is 12 since 1 is set in the bit-positions that represent 8 in one operand and 1 is set for the bit-position that represents 4 in the other operand.

             8 | 4:
                0000000000001000    : 8
                0000000000000100    : 4
                0000000000001100    : result 12

    In the next example the result is zero since both operands have the same bit-position set to 1.

             8 ^ 8:
                0000000000001000    : 8
                0000000000001000    : 8
                0000000000000000    : result 0

    There may be zero or more of the bitwise_or bitwise_and_exprs. For example, the following are all valid bitwise_exprs:

             12 | $4 | $7000
             6 ^ 6 ^ 4
             5 | $12 >> 1 ^ (($6 << 1) & $1)

    For ways to use the bitwise_or operators see Handling Control/Status Flags in Holding/Input registers.

  8. Comparison Expressions - relation operators

    comparison_expr:
            bitwise_expr relation bitwise_expr
          

    relation: 
            less_than
            greater_than
            not_greater_than
            not_less_than
            equal_to
            not_equal_to
          

    less_than : <
    greater_than :   >
    not_greater_than :  <=
    not_less_than :   >= 
    equal_to :  == 
    not_equal_to :  !=
            

    Both operands of these operators must have arithmetic type. The operators returns true if the relation is true, otherwise false.

    A comparison_expr occurs in the controlling expression within a selection_statement.

  9. Relational Term Expressions - negation operator

    relational_term_expr:
             logical_not? relational_primary_expr
          

    relational_primary_expr:
             comparison_expr
             left_parenth relational_expr right_parenth
          

    logical_not : !
          

    A relational_term_expr may be preceded by logical_not. The ! operator has only one operand, which must be boolean type. It returns true if the value of the relational_primary_expr is false, and false otherwise. In the example that follows, the parentheses are not necessary - they are there to aid clarity:

             !($23 / 60 > $12)

  10. Conjunction Expression - conjunction operator

    conjunction_expr : 
          relational_term_expr {logical_and relational_term_expr}*
            

           

    logical_and : &&
          

    Both operands must have boolean type. The operator returns true if both operands are true, otherwise false.

    There may be zero or more of the logical_and relational_term_exprs. For example:

             $23 / 60 > $12 && !($4 == 100) && (5 > 6 ) 

  11. Relational Expression - disjunction operator

    relational_expr:
            conjunction_expr {logical_or conjunction_expr}*
          

    logical_or : ||
          

    Both operands of the || operator have boolean type. The operator returns true if either operand is true, otherwise false.

    There may be zero or more of the logical_or relational_term_exprs. For example:

             $5 > $2 || $64 < $65 || (CycleTime > 1 || $2 == $9)

Statements

statement:
        expr_statement 
        selection_statement 
      

A statement denotes an action to be performed. The only ModMultiSim actions are the assignment of a value to a register or environment property (see expr_statement) and the selection of an action based on an evaluation (see selection_statement).

  1. Expression Statement

     expr_statement: 
            bitwise_expr 
          

    The expr_statement is an assignment statement: the value of the expression is assigned to the register or environment property for which it is a statement.

  2. Selection Statement

     selection_statement:
            if relational_expr then statement
            if  relational_expr then statement  else statement 
          

    The expression after the if must have boolean type. If the expression after the if is true, then the statement after then is executed. If false, then in the first form of the selection_statement, no action is taken, and in the second, the statement after else is executed. An else is connected to the last if without an else. Note that the grammar allows nested selection statements, as in:

             if (($62 % 3600) == 0) 
             then 
                if ($1 + $4) >  $5
                then 0
                else $1 + $4
             else $5