<head><title>ColdC: Language Structure: Statements</title></head> <body> <h1 align=center><a href="/ColdC/">ColdC</a>: <a href="/ColdC/Structure/">Language Structure</a>: Statements</h1> <hr> <EM>Statements</EM> are instructions to the interpreter. Statements can be simple (such as comments), or they can be complex (such as loops and conditionals). However, most statement types in ColdC have simple structures. Because statements can include other statements, you can use these simple statement types to build complex directives. <P>The following sections describe simple statements, which perform simple actions once, conditional statements, which perform different actions depending on the value of an expression, looping statements, which perform an action multiple times, and error-handling statements, which affect how the interpreter handles error conditions. <h2>Simple Statements</h2> <h3><i>comment statement</i></h3> <p>The <EM>comment statement</EM> does nothing at all. A comment statement is just a comment token, which is a sequence of two slashes (<SAMP>`//'</SAMP>) followed by any characters up to the end of the lines. For instance: <blockquote><PRE> // This is a comment. </PRE></blockquote> <p>The interpreter ignores comment statements completely; they are for the benefit of human readers. Note that comments in ColdC are actual statements, unlike comments in <CODE>C</CODE>, which are filtered out by the preprocessor. <h3><i>expression statement</i></h3> <p>The <EM>expression statement</EM> evaluates an expression and discards its value. The syntax of the expression statement is: <blockquote><PRE> <VAR>expression</VAR>; </PRE></blockquote> <p>The following are expression statements: <blockquote><PRE> 3; sender().tell($sys.who()); </PRE></blockquote> <h3><i>compound statement</i></h3> <P>The <EM>compound statement</EM> allows you to treat one or more statements as a single statement. The compound statement has the following syntax: <blockquote><PRE> { <VAR>statement1</VAR> <VAR>statement2</VAR> <VAR>.</VAR> <VAR>.</VAR> <VAR>.</VAR> } </PRE></blockquote> <P>The interpreter executes each of <VAR>statement1</VAR>, <VAR>statement2</VAR>, <VAR>...</VAR> in turn. <h3><i>return statement</i></h3> <P>The <EM>return statement</EM> allows a method to stop exeuting statements and to return a value other than the default return value of <CODE>this()</CODE>. The return statement can have either of the following two forms: <blockquote><PRE> return <VAR>expression</VAR>; return; </PRE></blockquote> <p>The interpreter stops executing statements in the method and returns the value of <VAR>expression</VAR>, or the objnum of the current object if <VAR>expression</VAR> is not given. <h2>Conditional Statements</h2> <p>There are three types of conditional statements in ColdC. The <h3><i>if statement</i></h3> <EM>if statement</EM> has the following syntax: <blockquote><PRE> if (<VAR>expression</VAR>) <VAR>statement</VAR> </PRE></blockquote> <p>The interpreter evaluates <VAR>expression</VAR>. If the value of <VAR>expression</VAR> is true (see section <A HREF="types.html">Data Types</A>), then the interpreter executes <VAR>statement</VAR>. <h3><i>if-else statement</i></h3> <P>The <EM>if-else statement</EM> is similar to the if statement. The if-else statement has the following syntax: <blockquote><PRE> if (<VAR>expression</VAR>) <VAR>true-statement</VAR> else <VAR>false-statement</VAR> </PRE></blockquote> <p>The interpreter evaluates <VAR>expression</VAR>, as before. If the value of <VAR>expression</VAR> is true, then the interpreter executes <VAR>true-statement</VAR>; otherwise, it executes <VAR>false-statement</VAR>. <P> Because the if statement and the if-else statement are similar, they can sometimes be ambiguous. The following code will produce unexpected results: <blockquote><PRE> if (a) if (b) c; else d; </PRE></blockquote> <p>The indentation suggests that the <CODE>else</CODE> clause should apply to the first <CODE>if</CODE> clause, but in fact it applies to the more recent one. You can avoid ambiguities like this by using braces to create compound statements out of conditional and looping statements, even if there is only one of them. In this case, you might write: <blockquote><PRE> if (a) { if (b) c; } else { d; } </PRE></blockquote> <h3><i>switch statement</i></h3> <p>The third type of conditional statement is the <EM>switch statement</EM>, which allows you to compare one value against a series of other values. The switch statement is the most complicated statement type in ColdC, and does vary from it's counterpart in C, so we'll start with an example: <blockquote><PRE> switch (val) { case 0: echo("The value is zero."); case 1 .. 10: echo("The value is between one and ten inclusive."); case 11 .. a: echo("The value is between eleven and a inclusive."); case "foo", "bar".."baz": echo("The value is \"foo\" or between \"bar\" and \"baz\""); case a .. b, c .. d, 42: count = count + 1; echo("The value is in the counted area."); case ~perm: echo("Permission denied while getting the value."); default: echo("Did not recognize value."); } </PRE></blockquote> <p>This example illustrates all of the capabilities of the switch statement. The expression given by <CODE>val</CODE> in the example is the <EM>controlling expression</EM>, and is compared against each of the cases inside the switch body. Each case has a value or list of values to compare against. The values can be of any type, and need not be constant expressions. You can also specify ranges, using two dots (<SAMP>`..'</SAMP>) to separate the lower and upper bounds. The keyword <CODE>default</CODE> specifies an action to perform if no cases were matched by the controlling expression. <P>Here is a more formal description of the syntax of the switch statement: <blockquote><PRE> switch (<VAR>controlling-expression</VAR>) { case <VAR>expr-or-range</VAR>, <VAR>expr-or-range</VAR>, <VAR>...</VAR>: <VAR>statements</VAR> case <VAR>expr-or-range</VAR>, <VAR>expr-or-range</VAR>, <VAR>...</VAR>: <VAR>statements</VAR> <VAR>.</VAR> <VAR>.</VAR> <VAR>.</VAR> default: <VAR>default-statement</VAR> } </PRE></blockquote> <P>When executing a switch statement, the interpreter scans through the list of cases and compares <VAR>controlling-expression</VAR> against each of the lists of values in the cases, evaluating the value lists from left to right until there is a match. The lower and upper bounds of ranges must be of the same type and must be either integers or strings, or the interpreter will throw a <CODE>~type</CODE> error. When the interpreter finds a match, it will execute the statement for that case. The interpreter will not continue checking cases after a match. <P>If the interpreter does not find a match, it will execute <VAR>default-statement</VAR>, the statement corresponding to the default case. You do not need to provide a default case if you do not wish to provide a default action. <P><CODE>C</CODE> programmers should note that switch statements in ColdC differ from switch statements in <CODE>C</CODE> in several respects. Because case values do not have to be constants, they may conflict, in which case the first match will take precedence. Also, there is no fall-through in ColdC switch statements; only the statements corresponding to the matching case will be executed. Because there is no fall-through, the <CODE>break</CODE> statement does not apply to switch statements. Finally, the default case must be placed last in the list of cases if it is given. <h2>Looping Statements</h2> <p>ColdC provides three kinds of looping statements. These statements allow you to traverse a list or a range of numbers, or to execute a statement as long as a certain condition is true. ColdC also provides two kinds of jump statements which allow you to prematurely exit from a loop or continue onto the next iteration. <h3><i>for-list statement</i></h3> <p>The <EM>for-list statement</EM> allows you to traverse a list. It has the following syntax: <blockquote><PRE> for <VAR>variable</VAR> in (<VAR>what</VAR>) <VAR>statement</VAR> </PRE></blockquote> <p><VAR>variable</VAR> must be a local variable (it cannot be an object variable), and <VAR>what</VAR> must be an expression resulting in a list or dictionary type. The interpreter executes <VAR>statement</VAR> once for each element in <VAR>what</VAR>, assigning the value of the element to <var>variable</var> during the iteration. Here is an example of using a for-list statement on a list: <blockquote><PRE> for s in (["foo", "bar", "baz"]) .tell(s); </PRE></blockquote> <p>When executed, the method <var>tell</var> is called three times, the first time with an argument of <code>"foo"</code> (the first element in the list), the second time with <code>"bar"</code> (the second element in the list), and the third time with <code>"baz"</code> (the last element in the list). <p>When using a dictionary as <var>what</var>, the interpreter assigns each association in the dictionary to <var>variable</var> (see <a href="types.html#dict">Data Types: Dictionaries</a>). For example, if the dictionary <code>#[['count, 21], ['name, "foo"]]</code> were to be used in a for-list statement, the first iteration would set <var>variable</var> to <code>['count, 21]</code>, and the second iteration would set it to <code>['name, "foo"]</code>. <p>Assigning to <VAR>variable</VAR> within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in <var>what</var>. <h3><i>for-range statement</i></h3> <p>The <EM>for-range statement</EM> allows you to traverse a range of integers. The range is specified by seperating the lower and upper bounds of the range with the range operator (<code>..</code>), contained within the left and right square brackets (<code>[</code> and <code>]</code>). A for-list statement of this nature would look like: <blockquote><PRE> for <VAR>variable</VAR> in [<VAR>lower</VAR> .. <VAR>upper</VAR>] <VAR>statement</VAR> </PRE></blockquote> <p><VAR>lower</VAR> and <VAR>upper</VAR> must be expressions resulting in an integer type (unlike a range in a switch). The interpreter executes <VAR>statement</VAR> once for each number from <VAR>lower</VAR> to <VAR>upper</VAR>, with <var>variable</var> being assigned the current number in the range. An example of using a range in a list follows: <blockquote><PRE> for i in [1 .. 10] .tell("iteration " + i); </PRE></blockquote> <p>Assigning to <VAR>variable</VAR> within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in <var>what</var>. <h3><i>while statement</i></h3> <p>The <EM>while statement</EM> allows you to execute code as long as the condition expression is true. The while statement has the following syntax: <blockquote><PRE> while (<VAR>expression</VAR>) <VAR>statement</VAR> </PRE></blockquote> <p>The interpreter continually evaluates <VAR>expression</VAR> and executes <VAR>statement</VAR> until the return value of <VAR>expression</VAR> is false. Here is an example using a while statement: <blockquote><PRE> a = 1; while (a < 35) a = a * 2; .tell("total: " + a); </PRE></blockquote> <h3><i>break statement</i></h3> The <EM>break statement</EM> allows you to exit a looping statement prematurely. The break statement has the following syntax: <blockquote><PRE> break; </PRE></blockquote> <p>The interpreter jumps to the end of the <em>innermost</em> for-list, for-range, or while statement. It is important to note that using the <em>break statement</em> within nested looping statements only breaks out of the innermost looping statement. <h3><i>continue statement</i></h3> <p>The <EM>continue statement</EM> allows you to jump to the next iteration of a loop. The continue statement has the following syntax: <blockquote><PRE> continue; </PRE></blockquote> <p>The interpreter skips the remainder of the loop body and begins another iteration of the innermost looping statement. As with the <em>break statement</em> the <em>continue statement</em> only is relevant to the innermost looping statement. <h2><a name="errors">Error-Handling Statements</a></h2> <p>The <a name="catch"><EM>catch statement</EM></a> allows you to indicate how errors should be handled. This statement can be used to anticipate an error and handle it gracefully. The catch statement has the following syntax: <blockquote><PRE> catch <VAR>error code</VAR>, <VAR>error code</VAR>, <VAR>...</VAR> <VAR>body-statement</VAR> with handler <VAR>handler-statement</VAR> </PRE></blockquote> <p>You can substitute the keyword <CODE>any</CODE> for the list of errors to indicate that you wish to catch all errors. You can leave out the <CODE>with handler</CODE> and the handler statement if you do not wish to do anything in the handler. <P> If an error listed in the error list is thrown inside <VAR>body-statement</VAR>, the interpreter will execute the handler rather than aborting the method. After the handler is done, control continues after the end of the catch statement, as if <VAR>body-statement</VAR> had completed with no errors. <P> Inside the handler, you can use the function <a href="/ColdC/Functions/error.html"><CODE>error()</CODE></a> to determine the error code which triggered the handler, the function <a href="/ColdC/Functions/throw.html"><CODE>throw()</CODE></a> can be used to initiate an error, and the function <a href="/ColdC/Functions/traceback.html"><CODE>traceback()</CODE></a> can be used to retrieve the propagated error stack. You can use the function <a href="/ColdC/Functions/rethrow.html"><CODE>rethrow()</CODE></a> to continue propagating an error. <P>Here is an example of how you might use a catch statement to intelligently handle a <CODE>~methodnf</CODE> error from the <CODE>list_method()</CODE> function: <blockquote><PRE> catch ~methodnf { code = list_method(method_name); } with handler { .tell("There is no method named " + tostr(method_name) + "."); } </PRE></blockquote> <p>Note that <a href="expressions.html#critical">critical expressions</a> inside <VAR>body-statement</VAR> will override the behavior of the catch statement. <p> <hr size=4><p align=center><i>Last Modified on Feb 26 1996</i> <br><i>Copyright © 1995, 1996, Brandon Gillespie</i> </body>