X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mup/blobdiff_plain/cdb3c0882392596f814cf939cbfbd38adc6f2bfe..ddf6330b56bcfb657e0186b24b9b1422c51d3424:/mup/docs/uguide/ifclause.html diff --git a/mup/docs/uguide/ifclause.html b/mup/docs/uguide/ifclause.html new file mode 100644 index 0000000..2a9ca72 --- /dev/null +++ b/mup/docs/uguide/ifclause.html @@ -0,0 +1,249 @@ + + +Generalized conditionals + + +

+   <-- previous page + +     Table of Contents    next page --> +

+ +

+Generalized conditionals +

+

+Mup also supports more general "if" clauses. If you happen to be +familiar with the preprocessors for the C and C++ programming +languages, Mup "if" clauses are very similar. +If you're not, that's okay, since things are explained below. +Also, some of the operations are really very rarely needed, so if +you find some of them confusing, you just can skip past this section; +you'll likely never have a need for the complicated operations anyway. +

+

+The general form is +

+if condition then Mup statements else Mup statements endif
+

+As with the "ifdef," the "else" and second set of Mup statements is optional. +

+

+One form of "if" is really just a variation of ifdef. It uses the +keyword "defined" followed by a macro name. So +

+  ifdef DUET
+

+could also be written +
+  if defined DUET then
+

+You may put a set of parentheses around the macro name for clarity +if you wish: +
+  if defined(DUET) then
+

+

+

+The ! is used to mean "not," so +

+  ifndef TRIO
+

+could also be written as +
+  if ! defined(TRIO) then
+

+

+

+So far, this just looks longer, so what's the advantage? +The difference is that ifdef and ifndef can only be used to check if a single +macro is defined or not, whereas the "if" condition is much more general, +and therefore much more powerful. +Decisions can be based on the values of macros, not just whether they are +defined or not, and can also be based on more than one macro at a time, +Here is an example of a condition based on several macros at once: +

+ if defined(FULL_SCORE) && defined(TRANSPOSE_UP) && ! defined(MIDI) then
+

+would be true only if both FULL_SCORE and TRANSPOSE_UP were defined, +but MIDI was not defined. The && means "and." +There is also || which means "or," so +
+ if defined(CELLO) || defined(STRINGBASS)
+

+would be true as long as at least one of the macros was defined. +

+

+The condition can also include numbers and macros used as numeric values +in arithmetic and comparisons. For example, +

+  define STAFFS 3 @
+  define S 5 @
+  if STAFFS > 5 then
+     // ... this would not be executed, since 3 is not greater than 5
+  endif
+  if 2 <= STAFFS then
+     // ... This would be executed, since 2 is less than or equal to 3
+  endif
+  if STAFFS + 1 == S - 1 then
+     // ... This would be executed, since 3+1 equals 5-1
+  endif
+

+Note that the symbol to test for "equals" is two equals signs, not just +one. This is to be consistent with what is used in the C and C++ languages. +The operators for comparisons are: + + + + + + + + + + + + + + + + + + + +
< less than
> greater than
<= less than or equal
>= greater than or equal
== equal
!= not equal
+ +

+

+Note that the values in the conditions can only be either literal numbers +or macros whose values evaluate to a number. They cannot be things like +Mup parameters. +A macro which is not defined is treated as having a value of zero. +Macro values are substituted for macro names just as elsewhere in Mup, +so if you use a macro whose resulting value does not evaulate to a number, +you may get an error or other unexpected result. +

+

+If you are familiar with "octal" and "hexadecimal" numbers, they can be +used, following the C language convention of a leading zero for octal +or a leading 0x for hexadecimal. (If you're not familiar with these +numbers or conventions, don't worry about it; it's never really necessary +to use them. Just make sure you don't accidentally start a number other +than a zero with a zero). +

+

+Values are limited to 32-bit signed numbers. (If you don't know +what that means, all you need to know is that you +can only use numbers between -2147483648 and 2147483647. +

+

+Before we introduce the remaining operators, it would be good to discuss +two concepts, called precedence and associativity. These determine the +order in which operations are done. Consider the following expression: +

+   5 + 3 * 8
+

+What is its value? If we just went left to right, we would add 5 and 3, +getting 8, then multiple by 8, for a final value of 64. However, +multiplication is generally considered to have higher "precedence" +than addition, meaning that multiplications should be done before additions. +In other words, the expression should actually be treated as +
+   5 + (3 * 8)
+

+so we would first multiply 3 by 8, getting 24, and then add 5 and 24, +obtaining a final answer of 29. +

+

+If you really intended the 64 meaning, that could be shown by parentheses, +indicating you want the addition to be done first: +

+   (5 + 3) * 8
+

+

+

+Associativity determines whether operators of equal precedence are done +left to right or right to left. Parentheses and +all of the operators that have two +operands associate left to right, while all the others +associate right to left. For example, since addition and subtraction +associate left to right, the expression +

+  10 - 6 - 1
+

+would be evaluated by first subtracting 6 from 10 to get 4, +then subtracting 1, yielding 3. +If they associated right to left, first 1 would be subtracted from 6 +to get 5, which would then be subtracted from 10, yielding 5. +So using different associativity can lead to different answers! +

+

+Since the "not" operator and unary minus associate right to left, +in the expression +

+  ! - (5)
+

+the unary minus would be applied first to get -5, then the "not" would be +applied. But what does "not -5" mean? The "not" operator will treat its +operand as a boolean value, with a value of zero meaning false, and +any non-zero value being true. Since -5 is not zero, it represents "true," +and "not true" would be "false," or zero. By the way, +any operator that yields a boolean result +(not, logical and, logical or, less than, greater than, +less than or equal, greater than or equal, equal, or not equal) will +always yield 1 for true, even though any non-zero value could mean true. +

+

+The operators are listed below. Those on the same line have the same +precedence, with those on each line having higher precedence than the +lines below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
operators operations associativity
( ) grouping left to right
! ~ - + not, one's complement, unary minus, unary plus right to left
* / % multiply, divide, modulo left to right
+ - add, subtract left to right
<< >> left shift, right shift left to right
< <= > >= less than, less or equal, greater than, greater or equal left to right
== != equal, not equal left to right
& bitwise AND left to right
^ bitwise XOR left to right
| bitwise OR left to right
&& logical AND left to right
|| logical OR left to right
? : interrogation right to left
+ +

+

+   <-- previous page     Table of Contents    next page --> +

+