Statements

Programs are lists of statements

In butter a program is a list of statements basically. Each statement belongs to a certain function definition. Its not possible to put a statement outside of a function in butter. The most simple statement is the so-called void-expression statement. Other statements offer loop control and conditional execution. In general each statement in butter needs to be separated from the next with a ";" character, unless the statement ends with a block of code. Blocks of code are enclosed within the curly-braces "" and "{"

Optionally statements can be prefixed with a label. Such a label is referenced by other statements like the goto-statement. In case you want to do that you need to state the labelname and a following ':'.
          printsomething ("hello");    // plain statement
label1:   printsomething ("hello");    // statement with label

Here is a list of the currently available statements in butter:

More words on If/Else statements

Almost program needs to react to certain dynamic conditions. Thats why you will find conditional-statements in any straight-forward programming-language. This one supports a if or if-else statement that behaves 100% like the ones you find in c, c++ or java.

Each if statement is followed immediately by an expression which must be enclosed in parentheses. The next statement or block of statements after this expression are executed only if the expression evaluates to a true value. In butter everything but the numerical value 0 or the null-pointer is considered to be true. After this statement (or statement block) there may be an optional else keyword. This keyword signals there is code to be executed if the condition did not evalute to a true value. The else-branch consists of a single statement or a block of statements, which is similiar to the code following the if statement's expression. Here are a few examples of if and if-else statements:
int result;
if (1) { result = 100; }                  // result is always set to 100
if (1) result = 100;                      // equivalent to the above
if (1) result = 100 else result = 200;    // result is still always = 100
if (!1) result = 100 else result = 200;   // result is set to 

// the following will test whether result is in the range between 20-80
if ((result >= 20) && (result <= 80)) {
  do_something(); /* result is inside the interval */
}
else {
  react_to_error(); /* result is not within the interval */
}

The if-expression can be any valid expression of the language and thus allows testing for several conditions, which can be concatenated with the logical operators like || (or), && (and) and ! (not).

Please note that any else statement belongs to the closest if statement appearing before it in the source. Note the following example:

Global variables, and the init/exit blocks

Even though it is not possible to have statements other than declaration-statments outside of blocks, you can still put declaration- statements outside of any function (including the special init-block function, details will follow). These declarations declare global variables, which are only existing once and changes made to any of these will persist over the lifespan of functions invocations.

A typical example usage of globals could look like this:
int i, j;

//
// an init-block can be used to initialize globals.
// note that an init-block is similiar to a function.
// it is only run through once upon program invocation
// though.
//
init {
  i = j = 10;
  j += i;
  prs ("globals initialized .. \n");
}
 
//
// a simple main function, printing out the values computed
// above
//
void main ()
{
  prs ("i + j = "); pri (i + j); prs (" (is it 30?)");
  nl ();
}
Global variables are implicitly initialized to 0 for numerical variables and to the null-object for all object variables like user-defined structures, the basic object or the string object.

In case you want to initialize such global variables, you can make use of a init-block construct. This is also shown in the above example. Its best to think of the init-block like any other user-defined function, with the exception that its automatically invoked once at startup by the runtime implicitly. Thus it is a suitable place for initializing global variables.

The complement of the init-block is the exit-block. Its code is executed after all threads have terminated right before program termination.