• Ingen resultater fundet

Translation Module

In document Translation of a Subset of RSL into Java (Sider 118-122)

3.2 Architechtural Design of the Translator

3.2.3 Translation Module

The task of the translation module in the translator is to do a translation from an RSL AST into a Java AST. This is done in two steps.

1. A number of passes over the RSL AST to decorate it with types.

2. Create a Java AST based on a RSL AST.

Type Decorating the RSL AST

Before creating a Java AST the RSL AST has to be decorated with types.

There are two reasons for this:

1. According to the translations specified in Chapter 2 several constructs in RSL must be translated to a number of different expressions in Java depending on the context and the parts involved.

2. The empty list requires a typing in Java.

An example of a construct, which requires different translations, is the ap-plication expression in RSL. In Example 3.3 a number of apap-plication expres-sions are listed in the test cases. The translation of these are presented in the listing of code in the example. The Java source code shows that the ap-plication of mk MyShortRecordDefinition is translated as a class instance creation expression in Java, while the application of the functionmyFunction is translated as a method invocation of a method in Java. The application of myList is translated as a method invocation of a method on an object in Java. In order to handle these expressions differently, even though they are all application expressions, they must be decorated in some way.

Example 3.3 Different kinds of application expressions in RSL.

type

MyVariantDefinition == Alternative1,

MyShortRecordDefinition :: variant : MyVariantDefinition value

myList : Text =h00a00, 00b00i, myFunction : Real→ Real MyFucntion(r) ≡r + 1.0 test case

[ 1 ] mk MyShortRecordDefinition(Alternative1), [ 2 ] myList(1),

[ 3 ] myFunction(myFunction(5.0))

/∗T r a n s l a t i o n o f t y p e s and v a l u e s o m i t t e d .∗/

public s t a t i c void main ( S t r i n g [ ] a r g s ) { System . out . p r i n t l n ( ” [ t 1 ] : ” + new

M y S h o r t R e c o r d D e f i n i t i o n (new A l t e r n a t i v e 1 ( ) ) ) ; System . out . p r i n t l n ( ” [ t 2 ] : ” + myList . g e t ( 1 ) ) ; System . out . p r i n t l n ( ” [ t 3 ] : ” +

myFunction ( myFunction ( 5 . 0 d ) ) ) ; }

The passes over the RSL AST are done by a number of visitors. The first visitor passing over the RSL AST is a ParentVisitor, which takes care of setting the parent of each node in the RSL AST. One could argue, that this could have been done in the creation of the RSL AST in the front end.

This would have lead to more complex action code in the grammar file of the front end. The second and third pass over the RSL AST is done by a TypeDecorateVisitor, which tries to determine the type of an expression, and, if successful, sets the type of the expression.

The reason that a typing of the empty list is required is somewhat com-plex. The translation of a list in RSL is an instance of the RSLListDefault<E>

class in Java. The class in Java is a generic class which needs a typing. It is possible to use an untyped list if it is used as argument to a method in Java, but it is not possible to use an untyped list as argument to a constructor.

Therefore all lists must be typed, even if they are empty.

In Example 3.4 an explicit function definition with a value expression containing two empty lists is shown. There is an empty list in the condition of the if–then–else expression, and there is an empty list in the if–branch of the if–then–else expression.

To determine the type of the empty list in the condition of the if–then–

else expression, theTypeDecorateVisitor looks at the parent expression. The parent expression is a value infix expression using the equal operator. The syntax rules of RSL dictate, that both operands of a value infix expression must be of the same type if the operator is the equal operator. The type of the empty list in the condition can therefore be set to the type of the left–hand side operand. The type of the left–hand side operand is known, because it is a parameter of the function, where the type can be determined from the function type expression and the binding list.

To determine the type of the empty list in the if–branch the fact that each branch of an if–then–else expression must have the same type is used. The type of the else–branch of the if expression can be determined by determining the type of the value infix expression. The type of the value infix expression is determined by looking at the operator and the operands. In case of an operator for which the type of the result is the same as the operands, the type of the value infix expression can be set by determining the type of the operands. In Example 3.4 the operator of the value infix expression is the concatenation operator. The result of the concatenation operator is a list or a text, which is a list of Char. The operands of the concatenation operator must also be lists of the same type. The type of both value infix expression as well as the operands can be set, because of the type of the operands of the value infix expression is known. This means that the type of the else–branch and therefore the if–branch can be set.

Example 3.4 LISTMULT example.

listmult : Int ×Int → Int listmult(il, i) ≡

if il = hi then hi

else

h hd il ∗ ii b listmult(tl il, i) end

public s t a t i c RSLList<I n t e g e r> l i s t m u l t ( RSLList<I n t e g e r> i l , i n t i ) {

i f( i l . e q u a l s (new RSLListDefault<I n t e g e r>() ) ) { return new RSLListDefault<I n t e g e r>() ; }

e l s e {

return ( (new RSLListDefault<I n t e g e r>( i l . hd ( ) i ) ) . c o n c a t ( l i s t m u l t ( i l . t l ( ) , i ) ) ) ;

} }

Creating a Java AST From a Decorated RSL AST

The translation from an RSL AST to a Java AST is done by a number of functions working from the top of the RSL AST to the bottom. The functions rely on recursion for running through the lists in the RSL AST. The reason for using recursion rather than iteration is that it is possible to use recursion both in Java and in the subset of RSL translated.

The top level function for doing the translation takes an RSL AST as argument and returns a Java AST. The functions works by calling other functions based on, what is needed at the place in the Java construct. A Java AST consist of a collection of compilation units. Therefore, two meth-ods creating a number of compilation units from an RSL AST is called. The results of these two are joined and the Java AST is created. One of the compilation units is the translation of the scheme being translated. A com-pilation unit consists of a class declaration, which again for one part consists of a list of methods. The list of methods in the compilation unit is created by a method which runs through the declarations of the basic class expression of the scheme being translated and creates method declarations corresponding to the functions in the declarations.

The principle is that the structure of the components in the Java AST is known, and the functions create these structures based on the information

which may be found in the RSL AST. An example of this could be the translation of an explicit function definition. An explicit function definition is translated as a method declaration according to Section 2.4.2. A method declaration in Java consists of the following components:

1. A list of modifiers.

2. A name.

3. A return type.

4. A list of arguments

5. A block determining the output.

These fives items are needed to create a valid method declaration in Java.

The top–level method for translating an explicit function definition does this by creating a method declaration and letting a number of auxiliary methods create the parts needed. One method creates a name for the method from the id of the explicit function definition in RSL. A second method creates the list of arguments for the method based on the binding list and the type expression in RSL. A third method determines the return type for the method from the type expression of the explicit function definition. A fourth method creates a block from the value expression of the explicit function definition.

In document Translation of a Subset of RSL into Java (Sider 118-122)