| 1 | <HTML> |
| 2 | <HEAD><TITLE> |
| 3 | Generalized conditionals |
| 4 | </TITLE></HEAD> |
| 5 | <BODY> |
| 6 | <P> |
| 7 | <A HREF="macros.html"><-- previous page</A> |
| 8 | |
| 9 | <A HREF="index.html">Table of Contents</A> <A HREF="include.html">next page --></A> |
| 10 | </P> |
| 11 | |
| 12 | <H3> |
| 13 | Generalized conditionals |
| 14 | </H3> |
| 15 | <P> |
| 16 | Mup also supports more general "if" clauses. If you happen to be |
| 17 | familiar with the preprocessors for the C and C++ programming |
| 18 | languages, Mup "if" clauses are very similar. |
| 19 | If you're not, that's okay, since things are explained below. |
| 20 | Also, some of the operations are really very rarely needed, so if |
| 21 | you find some of them confusing, you just can skip past this section; |
| 22 | you'll likely never have a need for the complicated operations anyway. |
| 23 | </P> |
| 24 | <P> |
| 25 | The general form is |
| 26 | <BR><PRE> |
| 27 | <B>if</B> <I>condition</I> <B>then</B> <I>Mup statements</I> <B>else</B> <I>Mup statements</I> <B>endif</B> |
| 28 | </PRE><BR> |
| 29 | As with the "ifdef," the "else" and second set of Mup statements is optional. |
| 30 | </P> |
| 31 | <P> |
| 32 | One form of "if" is really just a variation of ifdef. It uses the |
| 33 | keyword "defined" followed by a macro name. So |
| 34 | <BR><PRE> |
| 35 | ifdef DUET |
| 36 | </PRE><BR> |
| 37 | could also be written |
| 38 | <BR><PRE> |
| 39 | if defined DUET then |
| 40 | </PRE><BR> |
| 41 | You may put a set of parentheses around the macro name for clarity |
| 42 | if you wish: |
| 43 | <BR><PRE> |
| 44 | if defined(DUET) then |
| 45 | </PRE><BR> |
| 46 | </P> |
| 47 | <P> |
| 48 | The ! is used to mean "not," so |
| 49 | <BR><PRE> |
| 50 | ifndef TRIO |
| 51 | </PRE><BR> |
| 52 | could also be written as |
| 53 | <BR><PRE> |
| 54 | if ! defined(TRIO) then |
| 55 | </PRE><BR> |
| 56 | </P> |
| 57 | <P> |
| 58 | So far, this just looks longer, so what's the advantage? |
| 59 | The difference is that ifdef and ifndef can only be used to check if a single |
| 60 | macro is defined or not, whereas the "if" condition is much more general, |
| 61 | and therefore much more powerful. |
| 62 | Decisions can be based on the values of macros, not just whether they are |
| 63 | defined or not, and can also be based on more than one macro at a time, |
| 64 | Here is an example of a condition based on several macros at once: |
| 65 | <BR><PRE> |
| 66 | if defined(FULL_SCORE) && defined(TRANSPOSE_UP) && ! defined(MIDI) then |
| 67 | </PRE><BR> |
| 68 | would be true only if both FULL_SCORE and TRANSPOSE_UP were defined, |
| 69 | but MIDI was not defined. The && means "and." |
| 70 | There is also || which means "or," so |
| 71 | <BR><PRE> |
| 72 | if defined(CELLO) || defined(STRINGBASS) |
| 73 | </PRE><BR> |
| 74 | would be true as long as at least one of the macros was defined. |
| 75 | </P> |
| 76 | <P> |
| 77 | The condition can also include numbers and macros used as numeric values |
| 78 | in arithmetic and comparisons. For example, |
| 79 | <BR><PRE> |
| 80 | define STAFFS 3 @ |
| 81 | define S 5 @ |
| 82 | if STAFFS > 5 then |
| 83 | // ... this would not be executed, since 3 is not greater than 5 |
| 84 | endif |
| 85 | if 2 <= STAFFS then |
| 86 | // ... This would be executed, since 2 is less than or equal to 3 |
| 87 | endif |
| 88 | if STAFFS + 1 == S - 1 then |
| 89 | // ... This would be executed, since 3+1 equals 5-1 |
| 90 | endif |
| 91 | </PRE><BR> |
| 92 | Note that the symbol to test for "equals" is two equals signs, not just |
| 93 | one. This is to be consistent with what is used in the C and C++ languages. |
| 94 | The operators for comparisons are: |
| 95 | <TABLE BORDER=4> |
| 96 | <TR> |
| 97 | <TD><</TD> <TD>less than</TD> |
| 98 | </TR> |
| 99 | <TR> |
| 100 | <TD>></TD> <TD>greater than</TD> |
| 101 | </TR> |
| 102 | <TR> |
| 103 | <TD><=</TD> <TD>less than or equal</TD> |
| 104 | </TR> |
| 105 | <TR> |
| 106 | <TD>>=</TD> <TD>greater than or equal</TD> |
| 107 | </TR> |
| 108 | <TR> |
| 109 | <TD>==</TD> <TD>equal</TD> |
| 110 | </TR> |
| 111 | <TR> |
| 112 | <TD>!=</TD> <TD>not equal</TD> |
| 113 | </TR> |
| 114 | </TABLE> |
| 115 | |
| 116 | </P> |
| 117 | <P> |
| 118 | Note that the values in the conditions can only be either literal numbers |
| 119 | or macros whose values evaluate to a number. They cannot be things like |
| 120 | <A HREF="param.html">Mup parameters.</A> |
| 121 | A macro which is not defined is treated as having a value of zero. |
| 122 | Macro values are substituted for macro names just as elsewhere in Mup, |
| 123 | so if you use a macro whose resulting value does not evaulate to a number, |
| 124 | you may get an error or other unexpected result. |
| 125 | </P> |
| 126 | <P> |
| 127 | If you are familiar with "octal" and "hexadecimal" numbers, they can be |
| 128 | used, following the C language convention of a leading zero for octal |
| 129 | or a leading 0x for hexadecimal. (If you're not familiar with these |
| 130 | numbers or conventions, don't worry about it; it's never really necessary |
| 131 | to use them. Just make sure you don't accidentally start a number other |
| 132 | than a zero with a zero). |
| 133 | </P> |
| 134 | <P> |
| 135 | Values are limited to 32-bit signed numbers. (If you don't know |
| 136 | what that means, all you need to know is that you |
| 137 | can only use numbers between -2147483648 and 2147483647. |
| 138 | </P> |
| 139 | <P> |
| 140 | Before we introduce the remaining operators, it would be good to discuss |
| 141 | two concepts, called precedence and associativity. These determine the |
| 142 | order in which operations are done. Consider the following expression: |
| 143 | <BR><PRE> |
| 144 | 5 + 3 * 8 |
| 145 | </PRE><BR> |
| 146 | What is its value? If we just went left to right, we would add 5 and 3, |
| 147 | getting 8, then multiple by 8, for a final value of 64. However, |
| 148 | multiplication is generally considered to have higher "precedence" |
| 149 | than addition, meaning that multiplications should be done before additions. |
| 150 | In other words, the expression should actually be treated as |
| 151 | <BR><PRE> |
| 152 | 5 + (3 * 8) |
| 153 | </PRE><BR> |
| 154 | so we would first multiply 3 by 8, getting 24, and then add 5 and 24, |
| 155 | obtaining a final answer of 29. |
| 156 | </P> |
| 157 | <P> |
| 158 | If you really intended the 64 meaning, that could be shown by parentheses, |
| 159 | indicating you want the addition to be done first: |
| 160 | <BR><PRE> |
| 161 | (5 + 3) * 8 |
| 162 | </PRE><BR> |
| 163 | </P> |
| 164 | <P> |
| 165 | Associativity determines whether operators of equal precedence are done |
| 166 | left to right or right to left. Parentheses and |
| 167 | all of the operators that have two |
| 168 | operands associate left to right, while all the others |
| 169 | associate right to left. For example, since addition and subtraction |
| 170 | associate left to right, the expression |
| 171 | <BR><PRE> |
| 172 | 10 - 6 - 1 |
| 173 | </PRE><BR> |
| 174 | would be evaluated by first subtracting 6 from 10 to get 4, |
| 175 | then subtracting 1, yielding 3. |
| 176 | If they associated right to left, first 1 would be subtracted from 6 |
| 177 | to get 5, which would then be subtracted from 10, yielding 5. |
| 178 | So using different associativity can lead to different answers! |
| 179 | </P> |
| 180 | <P> |
| 181 | Since the "not" operator and unary minus associate right to left, |
| 182 | in the expression |
| 183 | <BR><PRE> |
| 184 | ! - (5) |
| 185 | </PRE><BR> |
| 186 | the unary minus would be applied first to get -5, then the "not" would be |
| 187 | applied. But what does "not -5" mean? The "not" operator will treat its |
| 188 | operand as a boolean value, with a value of zero meaning false, and |
| 189 | any non-zero value being true. Since -5 is not zero, it represents "true," |
| 190 | and "not true" would be "false," or zero. By the way, |
| 191 | any operator that yields a boolean result |
| 192 | (not, logical and, logical or, less than, greater than, |
| 193 | less than or equal, greater than or equal, equal, or not equal) will |
| 194 | always yield 1 for true, even though any non-zero value could mean true. |
| 195 | </P> |
| 196 | <P> |
| 197 | The operators are listed below. Those on the same line have the same |
| 198 | precedence, with those on each line having higher precedence than the |
| 199 | lines below. |
| 200 | <TABLE BORDER=4> |
| 201 | <TR> |
| 202 | <TD><B>operators</B></TD> <TD><B>operations</B></TD> <TD><B>associativity</B></TD> |
| 203 | </TR> |
| 204 | <TR> |
| 205 | <TD><TT>( )</TT></TD> <TD>grouping</TD> <TD>left to right</TD> |
| 206 | </TR> |
| 207 | <TR> |
| 208 | <TD><TT>! ~ - +</TT></TD> <TD>not, one's complement, unary minus, unary plus</TD> <TD>right to left</TD> |
| 209 | </TR> |
| 210 | <TR> |
| 211 | <TD><TT>* / %</TT></TD> <TD>multiply, divide, modulo</TD> <TD>left to right</TD> |
| 212 | </TR> |
| 213 | <TR> |
| 214 | <TD><TT>+ -</TT></TD> <TD>add, subtract</TD> <TD>left to right</TD> |
| 215 | </TR> |
| 216 | <TR> |
| 217 | <TD><TT><< >></TT></TD> <TD>left shift, right shift</TD> <TD>left to right</TD> |
| 218 | </TR> |
| 219 | <TR> |
| 220 | <TD><TT>< <= > >=</TT></TD> <TD>less than, less or equal, greater than, greater or equal</TD> <TD>left to right</TD> |
| 221 | </TR> |
| 222 | <TR> |
| 223 | <TD><TT>== !=</TT></TD> <TD>equal, not equal</TD> <TD>left to right</TD> |
| 224 | </TR> |
| 225 | <TR> |
| 226 | <TD><TT>&</TT></TD> <TD>bitwise AND</TD> <TD>left to right</TD> |
| 227 | </TR> |
| 228 | <TR> |
| 229 | <TD><TT>^</TT></TD> <TD>bitwise XOR</TD> <TD>left to right</TD> |
| 230 | </TR> |
| 231 | <TR> |
| 232 | <TD><TT>|</TT></TD> <TD>bitwise OR</TD> <TD>left to right</TD> |
| 233 | </TR> |
| 234 | <TR> |
| 235 | <TD><TT>&&</TT></TD> <TD>logical AND</TD> <TD>left to right</TD> |
| 236 | </TR> |
| 237 | <TR> |
| 238 | <TD><TT>||</TT></TD> <TD>logical OR</TD> <TD>left to right</TD> |
| 239 | </TR> |
| 240 | <TR> |
| 241 | <TD><TT>? :</TT></TD> <TD>interrogation</TD> <TD>right to left</TD> |
| 242 | </TR> |
| 243 | </TABLE> |
| 244 | |
| 245 | </P> |
| 246 | <HR><P> |
| 247 | <A HREF="macros.html"><-- previous page</A> <A HREF="index.html">Table of Contents</A> <A HREF="include.html">next page --></A> |
| 248 | </P> |
| 249 | </BODY></HTML> |