2005/5/10

     
 

CfgScript Branch Statements

artefaktur

| Expression statement | block {} Statement | Branch Statements | Loop Statements | Type Declaration | Variable Declaration | Synchronize Statements | With Statement | Using Statement | Type Alias |

Branches are conditional or unconditinal


Content of this chapter:

   BranchStatement
     ConditinalBranchStatement
       IfStatement
       SwitchStatement
     UnconditionalBranchStatement
       ReturnStatement
       BreakStatement
       ContinueStatement
       GotoStatement
       ThrowStatement
       TryCatchStatement


 BranchStatement

UnconditionalBranchStatement
:  ConditinalBranchStatement
|  UnconditionalBranchStatement
;

 ConditinalBranchStatement

ConditinalBranchStatement
:  IfStatement
|  SwitchStatement
;

 IfStatement

IfStatement
: 'if' '('  Expression ')' Statement [ 'else' Statement ]

 SwitchStatement

SwitchStatement
: 'switch' '(' Expression ')' 
  '{'
    CaseStatement*
    [ DefaultCaseStatement ]
   '}'
;

CaseStatement
: 'case' ExpressionList ':' Statement*
;

ExpressionList
: Expression [ ',' ExpressionList ]
;

DefaultCaseStatement 
: 'default' ':' Statement*
;

The switch statement is a little bit different to C++:
  • The case branches will be tested from top to down.
    The first case branch matches will be executed.
  • Exceptional to this default branches will be executed only if no other case branch match, independent to its location.
  • The case expressions are normal expressions, not constant expressions.
  • a case branch can have multiple expressions, separated by a ','.
  • If a case expression itself contains a ',' which is not surrounded by '( )' has to be bracket with '( )'.
  • A case expression starting with an non-postfix operator the expression will be evaluated as operator expression with the case expression as left site argument.
    If the case expression want to access a global variable or an with statement, the expression has to be bracket with '( )'.
  • case branches will be fall through next case branch if it is not terminated by break;.

Sample using expression:

bool switchOk = false;

switch(42)
{
  case 1, 2, 3: // test for 1 or 2 or 3
    break;
  case .toString().equals("41"): // calls 42.toString().equals("41")
    switchOk = false;
    break;
  case >= 41: // calls 42 >= 41
    switchOk = true;
    break;
  default:
    switchOk = false;
    break;
}
Sample:  csf_tests_acdk_cfgscript_2_statements_70_Switch_Test_csf.

 UnconditionalBranchStatement

UnconditionalBranchStatement
:  ReturnStatement
|  BreakStatement
|  ContinueStatement
|  GotoStatement
|  ThrowStatement
|  TryCatchStatement
;


 ReturnStatement

ReturnStatement
: 'return' [  Expression ] ';'

 BreakStatement

BreakStatement
: 'break' ';'

See also:  Loop Statements.

 ContinueStatement

ContinueStatement
: 'continue' ';'

See also:  Loop Statements.

 GotoStatement

goto is not implemented.

 ThrowStatement

ThrowStatement
: 'throw'  Expression ';'
;
The throw statement throws an exception.
Exception can be caught by the try catch statement.
Because the implementation of exceptions in CfgScript uses native C++ exceptions, it is possible to catch exceptions thrown in C++ in CfgScript and vice versa.

Sample:

try {
  StringArray sa = new StringArray(0);
  String s = sa[1];
} catch (acdk.lang.IndexOutOfBoundsException ex) {
  out.println(ex.getMessage());
}
A side effect of the construction of the CfgScript interpreter you also can catch exceptions caused by interpreter failures. See also  Debugging.

 TryCatchStatement

TryCatchStatement
: 'try' Statement ( 'catch' '(' TypeName VarName ')' Statement )* [ 'finally' Statement ]
;

The try catch statement works the same way like in Java.

Different to C++ and Java the catch will be tested in the same order as they declared:

  try {
    throw new RuntimeError("asdf"); 
  } catch (Throwable ex) {
    // this catch branch will be executed
  } catch (RuntimeException ex) {
    // never reach here
  }

The
  • finally
  • block will be executed unrelated if an exception was thrown in the try block and independed if the exception was handled by a catch block.

    
      try {
        
      } catch (RuntimeException ex) {
      } finally {
        // this code block will be executed independ if inside try block an exception
        // was thrown or the the exception was handled in a catch block
      }
    

    If an exception should be re-thrown in a catch Exception block throw ex; should be used (throw; doesn't work).