Zbex conditional compiles and other features
Zbex provides you with some compile time features that can add flexibility and readability to your programs. The following commands must start in column one.
#define
The #define command has two fields, separated by one more blanks. The second field is defined as a compile time replacement for the first field. The effect during compilation is that whenever the compiler finds a string of characters (outside a put statement) that matches the first field, it substitutes the string of characters in the second field. This feature allows you to identify arbitrary constants (sometimes called "magic numbers") with a name, so that these can later be easily found and changed. It also allows you to identify program parameters by name (e.g., the size of arrays) so that these can be easily changed. The #define command is also used to set the value of boolean variables used in conditional compiles. The variable is identified in the first field, and its value is set by the second field. The value is 1, if and only if the second field is a "1". Example:
Program --------------------- #define LIMIT 40 int h,i,j(LIMIT) j(1) = 1 j(2) = 1 loop for i = 3 to LIMIT j(i) = j(i-1) + j(i-2) repeat loop for i = 1 to LIMIT putc ~j(i) ... h = i / 5 if rem = 0 putc end repeat putc run
Execution ------------------------------------- ** S=15, P=57, L=243, M=450 ** 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 Ready for program
#if, #else, #endif
This group of commands works much like the if/else/end group in Zbex, except that the effect is to tell the compiler which lines of code to compile. The #if command requires a boolean variable, whose value must be set by a #define command (see above). If the value of the variable is 1, the lines following the #if will be compiled, up to the #else (which is optional) or the #endif of the group. It is possible to have nested #if-#else-#endif groups. Example:
Program --------------------- #define OPTION_1 1 #define OPTION_2 0 str name.30,subname.10(3) int i name = "Ronald Wilson Reagan" mpt = 0 loop for i = 1 to 3 subname(i) = txt(name,[' ']) repeat putc The candidate's name is ... #if OPTION_1 putc ~subname(1) ... #if OPTION_2 putc ~subname(2) ... #else putc ~subname(2){1} . ... #endif #endif putc ~subname(3) run
Execution ------------------------------------- ** S=12, P=56, L=263, M=431 ** The candidate's name is Ronald W. Reagan Ready for program
#process
This command allows you to identify groups of lines that you want included in a compile. Groups of lines are identified by letters, caps and small (52 groups total). The compiler will include all groups identied by letters found on #process command line. You may use the #process command more than once. Program lines belonging to a group are identified by an ampersand "&" in column one, followed by a single letter in column two and a blank space in column three. Example:
Program --------------------- #process A b D &A putc Option A &b putc Option B &c putc Option C &D putc Option D &E putc Option E &F putc Option F run
Execution ------------------------------------- ** S=4, P=17, L=231, M=410 ** Option A Option B Option D Ready for program
The #process command is very useful for removing debug statements from the compile process after your program is running properly. I have found it helpful to keep debug statements available in case something goes wrong with one of my programs later on. The advantage is that I don't have to rethink the debugging process from scratch. By using the %<letter> method for removing these lines, I can turn them back on in an instant by simply including the proper process statement at the top my program. In the small example below, I can turn on the dputc statement by replacing the "*" in front of process with a "#".
Program --------------------- *process A int i loop for i = 1 to 10 &A dputc ~i repeat run
#autodef
If you are writing a short program and you are feeling too lazy to declare your variables, you may be able to use the #autodef command. #autodef automatically declares the letters 'a'..'t' to be integers and the letters 'u'..'z' to be real numbers. All other symbols will be declared as strings with maximum length of 160. Example:
Program --------------------- #autodef A = "" loop for i = 1 to 1000 A = A // "x" repeat run
Execution ------------------------------------- ** S=5, P=16, L=237, M=451 ** Run-time error: maximum length of string variable: A has been exceeded at line = 4 attempted length = 161, maximum length = 160 Ready for program
Abbreviations
The Zbex compiler recognizes a few abbreviations that have become standard in other programing languages. These are listed below, along with what they represent.
Abbreviation Expanded to ... -------------- ------------------------- ++i i = i + 1 (integer only) --i i = i - 1 (integer only) x += 1.0 x = x + 1.0 (integer and real) i -= 10 i = i - 10 " " " y *= x + 3.0 y = y * (x + 3.0) " " " k /= 4 k = k / 4 " " " i &= 0x01 i = i & 0x01 (integer only) i |= 0x04 i = i | 0x04 " " i >>= 3 i = i >> 3 " " i <<= 4 + j i = i << (4 + j) " "