Menu

Statements

Donald Strong

[Home]


Language Features

Control Statements

Scoped Code Blocks

ClassMaker provides the following methods to create scoped code blocks.

    public Labelled Begin() throws ClassMakerException
    public void End() throws ClassMakerException

A Begin and End pair create a code block that limits the scope of variables
declared within the code block. Other statements may include a code block of multiple statements
but they do not limit variable scope.

In the following code the variable a is declared twice in different scoped code blocks.
Consequently, the variable can be declared as an integer in one code block and a character in the other.

Java codeClassMaker code
    if (n > 0)
    {
        int a;
        a = n++;
    }
    else
    {
        char a;
        a = '0';
        n = a - n;
    }
    If(GT(Get("n"), Literal(0)));
    Begin();
        Declare("a", int.class, 0);
        Set("a", Inc("n"));
    End();
    Else();
    Begin();
        Declare("a", char.class, 0);
        Set("a", Literal('0'));
        Set("n", Subt(Get("a"), Get("n")));
    End();
    EndIf();

Begin and End are also used to define the code block for a method, as described in the section
about [Methods].

If Statement

ClassMaker provides the following methods to create if statements.

    public Labelled If(Type condition) throws ClassMakerException;
    public void Else() throws ClassMakerException;
    public void EndIf() throws ClassMakerException;

There may be any number of statements between the If, Else and EndIf method calls.
Unlike java, there is an implicit code block between each clause.

An exception will be thrown if the clauses do not balance, for example, if an Else method is
called when not preceded by an If call and followed by an EndIf call.

Java codeClassMaker code
    if (a<0) {
        a = 0;
    }
    If(LT(Get("a"), Literal(0)));
        Set("a", Literal(0));
    EndIf();
    if (a<0) {
        a = 0;
    } else {
        a = 1;
    }
    If(LT(Get("a"), Literal(0)));
        Set("a", Literal(0));
    Else();
        Set("a", Literal(1));
    EndIf();

While loop

A while loop can be created using the following methods from ClassMaker.

    public Labelled Loop() throws ClassMakerException
    public void While(Type condition) throws ClassMakerException
    public void EndLoop() throws ClassMakerException

The While clause can appear at the start or end of the loop, either after the Loop
clause or just before the EndLoop clause. In actual fact it could appear anywhere in the loop
as ClassMaker places no restrictions on the placement of the While clause, but the traditional
place is at the start of the loop or occasionally at the end.

Java codeClassMaker code
    x = 1;
    while (n>0)
    {
        x = x * n;
        --n;
    }
    Eval(Set("x", Literal(1)));
    Loop();
        While(GT(Get("n"), Literal(0)));
        Eval(Set("x", Mult(Get("x"), Get("n"))));
        Eval(Dec("n"));
    EndLoop();

For loop

The methods for generating a for loop in ClassMaker look like this.

    public ForWhile For(Type declare) throws ClassMakerException;
    interface ForWhile
    {
        ForStep While(Type condition) throws ClassMakerException;
    }
    interface ForStep
    {
        Labelled Step(Type step) throws ClassMakerException;
    }
    public void EndFor() throws ClassMakerException

While this looks daunting it actually comes down to this simple sequence.

    For( <assignment> ).While( <condition> ).Step( <increment> );

The For method expects an expression which is usually an assignment, although this is not enforced.
The While method expects a boolean expression and will complain if it doesn't get one.
The Step method expects another expression which usually increments a value, although again, this is not enforced.
Any or all of the expressions may be omitted by providing null.

The call to EndFor terminates the loop.

The following code calculates factorial for a given n.

Java codeClassMaker code
 
    for (x=1; n>0; --n) 
    {
        x = x * n;
    }
 
    For(Set("x", Literal(1))).While(GT(Get("n"), Literal(0))).Step(Dec("n"));
        Eval(Set("x", Mult(Get("x"), Get("n"))));
    EndFor();

Break & Continue

The usual way to shortcut evaluation in the middle of a loop in java is to use a break
or continue statement. The equivalents in ClassMaker are named similarly.

    public void Break() throws ClassMakerException
    public void Continue() throws ClassMakerException

The While clause in a loop is optional; a break can be used instead. The following
code sums values up to n, the second version excludes multiples of 2.

Java codeClassMaker code
    // Sum all values up to n.
    x = 0;
    while (true) {
        if (n<=0) {
            break;
        }
        x = x + n;
        --n;
    }
    Eval(Set("x", Literal(0)));
    Loop();
        If(LE(Get("n"), Literal(0)));
            Break();
        EndIf();
        Eval(Set("x", Add(Get("x"), Get("n"))));
        Eval(Dec("n"));
    EndLoop();
    // Sum all values up to n, except multiples of 2
    x = 0;
    while (true) {
        y = n--;
        if (y<=0) {
            break;
        }
        if ((y % 2) == 0) {
           continue;
        }
        x = x + y;
    }
     Eval(Set("x", Literal(0)));
     Loop();
         Eval(Set("y", PostDec("n")));
         If(LE(Get("y"), Literal(0)));
             Break();
         EndIf();
         If(EQ(Rem(Get("y"), Literal(2)), Literal(0)));
             Continue();
         EndIf();
         Eval(Set("x", Add(Get("x"), Get("y"))));
     EndLoop();

Switch

ClassMaker provides the following methods to support the switch statement.

    public Labelled Switch(Type switchType) throws ClassMakerException;
    public void Case(int key) throws ClassMakerException;
    public void Break() throws ClassMakerException
    public void Break(String label) throws ClassMakerException
    public void Default() throws ClassMakerException;
    public void EndSwitch() throws ClassMakerException;

The Case(int key) method will accept an int, char, short or byte type.

ClassMaker will generate different byte-code for the switch depending upon whether the keys
are contiguous or non-contiguous. It will generate a table-switch in the former situation or a
lookup-switch in the latter.

Java codeClassMaker code
 
    y = 0;
    switch (x)
    {
        case 0:
            y = 1;
            break;
        case 4:
            y = 2;
            break;
        case 2:
            y = 3;
            break;
        case 6:
            y = 4;
            break;
        default:
            y = 0;
            break;
    }
 
    Set("y", Literal(0));
    Switch(Get("x"));
    {
        Case(0);
            Set("y", Literal(1));
            Break();
        Case(4);
            Set("y", Literal(3));
            Break();
        Case(2);
            Set("y", Literal(2));
            Break();
        Case(6);
            Set("y", Literal(4));
            Break();
        Default();
            Set("y", Literal(0));
            Break();
    }
    EndSwitch();

Try catch finally

ClassMaker provides the following methods to perform exception handling.

    public Labelled Try();
    public void Catch(Class javaClass, String name) throws ClassMakerException;
    public void Catch(String exceptionName, String name)
    public void Finally() throws ClassMakerException;
    public void EndTry() throws ClassMakerException;

There are two versions of the Catch method. You will use the version that
takes a reflection Class most of the time. The version that takes a
!String is necessary when you are catching an exception class
that you are generating at runtime.

The generated code in the Finally clause is always executed, as you would expect.
The code is put in a subroutine and the subroutine is invoked:

  • after execution of the Try block completes normally
  • after a Catch clause processes an exception
  • as appropriate when Break, Continue or Return methods are called
  • whenever an exception passes through the method without being caught.
Java codeClassMaker code
     try
     {
         x = func.unary(x);
     }
     catch (FileNotFoundException ex1)
     {
         x = 10000;
     }
     catch (IllegalArgumentException ex1)
     {
         x = 20000;
     }
     finally
     {
         x = x + 100;
     }
     Try();
     {
         Eval(Set("x", Call(Get("func"), "unary", Push(Get("x")))));
     }
     Catch(FileNotFoundException.class, "ex1");
     {
         Eval(Set("x", Literal(10000)));
     }
     Catch(IllegalArgumentException.class, "ex2");
     {
         Eval(Set("x", Literal(20000)));
     }
     Finally()
     {
         Eval(Set("x", Add(Get("x"), Literal(100))));
     }
     EndTry();

Labelled Break & Continue

ClassMaker provides the following interface and methods to support labelled Break and Continue.

    public interface Labelled
    {
        void setLabel(String label);
        String getLabel();
    }
    public void Break(String label) throws ClassMakerException
    public void Continue(String label) throws ClassMakerException

The Labelled interface is returned by all !ClassMaker statements to allow
them to be labelled. It is then possible to Break to the labelled
statement. Labelled loops can also be the target of a Continue method.

Statements may be labelled as follows.

    Begin().setLabel("HERE");
    If(<cond>).setLabel("THERE");
    Loop().setLabel("LOOP");
    For(<expr>).While(<cond>).Step(<expr>).setLabel("FORLOOP");
    Switch().setLabel("EXIT");
    Try().setLabel("TRYING");

The following example demonstrates several of these uses.

Java codeClassMaker code
    outer: {
        loop:  for (j=1; j<=3; j++) 
        {
            switch (i) {
            case 1:
                break;
            case 2:
                continue;
            case 3:
                break loop;
            case 4:
                continue loop;
            case 5:
                break outer;
            }
            n++;
        }
    }
    Begin().setLabel("outer");
        For(Set("j", Literal(1))).While(LE(Get("j"), Literal(3))).Step(Inc("j")).setLabel("loop");
            Switch(Get("i"));
            Case(1);
                Break();
            Case(2);
                Continue();
            Case(3);
                Break("loop");
            Case(4);
                Continue("loop");
            Case(5);
                Break("outer");
            EndSwitch();
            Eval(Inc("n"));
        EndFor();
    End();

[Home]


Related

Wiki: Home

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.