====== Bitlash Conditionals: if, while, and switch ====== The earlier Bitlash 1.0 language had the limitation that the entire tail of the line was treated as a statement group for **while** and **if**. And there was no **else**. This made many constructs clumsy and awkward to express. In Bitlash 2.0 the **while** and **if** commands have been remodeled to act much more like C. The **while** command iterates either a simple statement or a list of simple statements in curly braces. Execution of the rest of the function continues after the while condition fails, without the previous regard for "rest of the line". The **if** construct now has an **else** clause, and execution continues after the appropriate if/else clause. Finally, the **switch** command now allows any Bitlash statement to be a case handler. ==== while (expr) {stmt1; ...; stmtN;} ==== The **while** command repeats execution of the while-statements as long as the test expression is true. When the test expression is false, execution continues after the while's statement list. > while (millis() < 100000) {d13=!d13;} print "Done"; (light flickers) Done > Execution of the **while** loop is blocking. In other words, during the execution of a **while** command, no other functions can run, since Bitlash is working as hard as it can to get to the end of that command line. The combination of **while 1** with **delay()** is particularly deadly, since it uses the whole processor: > print "this works but NOTE it will hog the whole arduino" > while 1 {print millis(); delay(1000);} (no prompt again until you press ^C) Bitlash polls the serial port for Control-C during while loops, so you can break out. ---- ==== if (expr) {stmt1; ...; stmtN;} [else {stmt1; ...; stmtN;}] ==== The **if** command executes the first statement list if the test condition is true; otherwise, the optional else part is executed, if present. Unlike Bitlash 1.0, execution continues on the rest of the program text after the if/else statement. > if (d4) {print "the light is on";} ==== Omitting { } for a single statement ==== When using **while** and **if**, it is legal syntax to omit the {} if only a single statement is to be executed, just like in C. (In other words a statement is recursively defined as a statement or a list of statements in curly braces.) > i=0; while (++i<3) print i; print "done"; 1 2 done > ---- ==== switch (expr) {stmt0; stmt1; ...; stmtN;} ==== The switch command selects one of N statements to execute based on the value of a numeric expression. This provides a very easy way to build state machines, among other things. Syntax: switch (selection-expression) { stmt0; stmt1; ...; stmtN;} The selection-expression is evaluated to produce an integer result, which is used to select one of the supplied statements in curly braces. The selected statement, **and only the selected statement** from among those in curly braces, is executed, then execution continues after the switch statement. (Note: This construct is similar to but not strictly compatible with the C switch statement, which has "case x:" tags to specify each case.) If the value of the selection expression is less than zero it is treated as zero and therefore the first supplied statement is executed. If the value is greater than N, the last statement is executed. Example: This switch statement in the elevator2.btl example calls **wating**, **goingup**, or **goingdown**, depending on the value of s, the variable that represents the state of the elevator system: switch s {waiting; goingup; goingdown;} If the value of s is <= 0, the **waiting** function will be called. If the value of s is == 1, the **goingup** function will be called. If the value of s is >= 2, the **goingdown** function will be called. Example: Unlike Bitlash 1.0, the case handlers can be any Bitlash statement, for example: switch (d) {print "foo"; print "bar"; print "baz"; boot;} ---- ==== Nesting ==== Nested conditionals work as you would expect: > a=0;while (a++<2) {b=0; while (b++<2) {print a,b;}} 1 1 1 2 2 1 2 2 >   ---- ==== How to simulate a "for" loop ==== The simplest way is to unroll it as a **while**. Here is an example that initializes pins 3 through 8 as outputs and sets them to HIGH: > i=3; while i<=8 {pinmode(i,1); dw(i,1); i++;} For extra credit, let's initialize the even ones on and the odd ones off: > i=3; while i<=8 {pinmode(i,1); dw(i,(i&1)); i++;}