Commit | Line | Data |
---|---|---|
fac14bbe MW |
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> |