load help; @[name] dao.control @[name] @[title] Control Constructs @[title] @[text] Control constructs are essential for a program to do complex work. Dao supports the common controls such as: @[green]if-else@[green], @[green]for@[green], @[green]while@[green], @[green]do-while@[green], @[green]switch-case@[green], @[green]break@[green] and @[green]skip@[green] etc. @[text] @[name] dao.control.if-else @[name] @[title] If-Else Conditional Control @[title] @[text] The @[green]if-else@[green] control allows the program to branch and execute different blocks of codes, based on the results of the condition expressions. @[subsection] Definition @[subsection] @[code(syntax)] ControlBlock ::= Statement | '{' [ StatementBlock ] '}' IfElseStmt ::= 'if' '(' [ LocalVarDeclaration ';' ] Expression ')' ControlBlock { 'else' 'if' '(' [ LocalVarDeclaration ';' ] Expression ')' ControlBlock } [ 'else' ControlBlock ] @[code(syntax)] @[subsection] Use Cases @[subsection] @[subsubsection] Single Statement @[subsubsection] This is the simplest use case of @[code]if@[code]. It generally looks like the following: @[code] if( condition ) statement @[code] Where the @[code]statement@[code] is executed only if the @[code]condition@[code] evaluated to true (non-zero number or enum value). @[subsubsection] Single Block @[subsubsection] If multiple statements need to be executed if the @[code]if@[code] test is true, a pair of braces can be used to group these statements into a block. Of course, such block can also nest other blocks. @[code] if( condition ) { block } @[code] @[subsubsection] Else Statement or Block @[subsubsection] If there is another statement or block should be executed when the condition test failed, one can add the @[code]else@[code] clause to the if statement. @[code] if( condition ) statement1 else statement2 if( condition ) { block1 } else { block2 } @[code] Please note that, the braces are needed only if the block constains more than a single statement. @[subsubsection] Multiple Conditions and Blocks @[subsubsection] If there are multiple conditions to be tested for multiple statements or blocks, the @[code]else if@[code] clause can be used. @[code] if( condition1 ){ block1; }else if( condition2 ){ block2; }else{ block3; } @[code] If @[code]condition1@[code] is true, @[code]block1@[code] is executed; otherwise, if @[code]condition2@[code] is true, @[code]block2@[code] is executed; otherwise, @[code]block3@[code] is executed; zero or more @[code]else if@[code] and zero or one @[code]else@[code] statement can be used. @[subsubsection] Optional Declaration @[subsubsection] Before each condition expression, there can be an optional variable declaration. @[code] if( declaration; condition ) { block } @[code] For example, @[code] if( a = sin(100); a > 0 ) io.writeln( "positive sine" ); if( var a = sin(100); a > 0 ) io.writeln( "positive sine" ); @[code] @[subsection] More Examples @[subsection] @[code(dao)] var a = 5 if( a > 1 ) io.writeln( 'a > 1' ) if( a > 2 ) io.writeln( 'a > 2' ) else io.writeln( 'a <= 2' ) if( a < 3 ) io.writeln( 'a < 3' ) else if( a < 4 ) io.writeln( 'a < 4' ) else io.writeln( 'a >= 4' ) @[code(dao)] @[text] @[name] dao.control.for @[name] @[title] For Looping Control @[title] @[text] Dao supports three different styles of for loops: @[list] -- For-in loop; -- Range for loop; -- C style for loop; @[list] @[subsection] Definition @[subsection] @[code(syntax)] ForIn ::= 'for' '(' ['var'|'invar'] Identifier 'in' Expression {';' Identifier 'in' Expression} ')' ControlBlock RangeFor ::= 'for' '(' ['var'|'invar'] Identifier '=' Expression ':' [Expression ':'] Expression ')' ControlBlock CFor ::= 'for' '(' [ LocalVarDeclaration ] ';' [ Expression ] ';' [ ExpressionList ] ')' ControlBlock ForStmt ::= ForIn | RangeFor | CFor @[code(syntax)] @[subsection] For-In @[subsection] For-in loop can normally used to iterate over the items of a container object. It is probably most useful with list, @[code] var numbers = { 1, 2, 3, 4, 5 } for( num in numbers ) io.writeln( num ) @[code] For-in loop can also be used with map or hash map, @[code] var mapping = { 'AA'=>11, 'BB'=>22, 'CC'=>33 } for( pair in mapping ) io.writeln( pair ) @[code] When iterating over a map or hash map, the iteration variable (@[code]pair@[code]) will store each pair of key and value as a tuple. In a single for-in loop, multiple @[code]in@[code] expressions can be used to iterate over multiple objects simutaneously, @[code] var numbers = { 1, 2, 3, 4, 5 } var mapping = { 'AA'=>11, 'BB'=>22, 'CC'=>33 } for(var num in numbers; var pair in mapping ) io.writeln( num, pair ) @[code] @[subsection] Range For @[subsection] A range for loop uses an arithmetic progression condition to control the loop. The arithmetic progression condition usually consists of an initial value, an optional step value and a stopping value. @[code] for(var index = 1 : 2 : 10 ) { # step value = 2; io.writeln( index ) } for(var index = 1 : 10 ) { # step value = 1; io.writeln( index ) } @[code] The loops will start with @[code]index=1@[code], and with each loop cycle, @[code]index@[code] is increased by two or one, when @[code]index@[code] become greater than 10, the loop will stop. @[subsection] C Style For @[subsection] C-style for loop is the most flexible for loop construct. It generally looks like the following: @[code] for( init; condition; step ){ block; } @[code] The essential execution logic or steps of @[green]for@[green] statement is the following, @[list] == Execute the initial expression @[code]init@[code]; == Check the condition expression @[code]condition@[code]; == If true continue to the next step, otherwise exit the loop; == Execute the code block @[code]block@[code]; == Execute the step expression @[code]step@[code] and go to 2; @[list] The detailed steps may depends on the implementation but the basic execution logic is the same. Example, @[code(dao)] for(var i=0; i<3; ++i){ io.writeln( i ); } for(var i, j=0; i<10; ++i, j+=2){ io.writeln( i, j ); } @[code(dao)] @[text] @[name] dao.control.while @[name] @[title] While Looping Control @[title] @[text] @[green]while@[green] is a simple looping construct that executes a block if the looping condition is true, and repeats the execution as long as the condition is true. @[subsection] Definition @[subsection] @[code(syntax)] WhileStmt ::= 'while' '(' [ LocalVarDeclaration ';' ] Expression ')' ControlBlock @[code(syntax)] A while loop generally looks like the following: @[code] while( expression ){ block; } @[code] If @[code]expression@[code] is true, @[code]block@[code] is executed and repeated until @[code]expression@[code] becomes false, namely, while @[code]expression@[code] is true, execute @[code]block@[code]. @[subsection] Examples @[subsection] @[code] var i = 0; while( i < 5 ){ io.writeln( i ); i += 1; } @[code] @[text] @[name] dao.control.do-while @[name] @[title] Do-While Looping Control @[title] @[text] @[green]Do-while@[green] is a simple looping construct that executes a block and repeats the execution until its looping condition become false. @[subsection] Definition @[subsection] @[code(syntax)] DoWhileStmt ::= 'do' ControlBlock 'while' '(' Expression ')' @[code(syntax)] A do-while loop generally looks like the following: @[code] do { block; } while ( condition ) @[code] It executes @[code]block@[code], and then repeat executing it until the @[code]condition@[code] become false. @[subsection] Examples @[subsection] @[code(dao)] var i = 0 do i += 1 while( i < 10 ) do { i += 1 io.writeln( i ) } while( i < 15 ) @[code(dao)] @[text] @[name] dao.control.switch-case @[name] @[title] Switch-Case Control @[title] @[text] Switch-case control provides a convenient way to branch the code and choose a block of code to execute based on the value of a object. @[subsection] Definition @[subsection] @[code(syntax)] SwitchCaseStmt ::= 'switch' '(' Expression ')' '{' { 'case' Expression [ ( ',' | '...' ) Expression ] ':' ControlBlock } [ 'default' ':' ControlBlock ] '}' @[code(syntax)] A switch-case statement generally looks like the following: @[code] switch( expresssion ){ case C_1 : block_1 case C_2 : block_2 case C_3 : block_3 ... default: block0 } @[code] If the @[code]expresssion@[code] equals to @[code]C_i@[code], @[code]block_i@[code] will be executed. Here @[code]C_i@[code] must be a constant, but they can be of different types, that means, you can mix numbers and strings as case values. Unlike in C/C++, no @[green]break@[green] statement is required to get out of the @[green]switch@[green]. If you want to execute the same block of codes for different case values, you just need to put them together in the same case: @[code] switch( expresssion ){ case C1, C2, C3 : block3 ... default: block0 } @[code] As a simple example, @[code(dao)] var a = "a"; switch( a ){ case 1, "a" : io.write("case 1 or a"); default : io.write("case default"); } @[code(dao)] @[text]