;#; Basic 101: How to LARA | JavaScript in LARA → ;#;
This first tutorial explains the basics of the LARA language, more importantly the three most important statements in the LARA language: select, apply and condition. Here we explain:
In this tutorial we are using part of the target language specification used in MANET to exemplify the join point selection, attributes access and to perform actions. The following graph shows part of the join point model available in MANET. Some important notes:
<imgcaption jmpMANET|Part of the join point model hierarchy of MANET.> </imgcaption>
The join points depicted in the graph are able to retrieve the following attributes:
Join Point | Attribute | Type | Description |
---|---|---|---|
file | name | string | the name of the file |
function | name | string | the name of the function |
return_type | string | the return type | |
body | num_lines | int | number of lines of the body |
num_statements | int | number of statements | |
num_loops | int | number of loops | |
var | name | string | the name of the variable |
type | string | the type of the variable | |
reference | 'read', 'write' or 'decl' | the type of reference to the variable | |
loop | type | 'for', 'while' or 'do-while' | the type of the loop |
rank | string | the rank of the loop inside its function | |
nested_level | int | the nesting level of the loop | |
control_var | string | the name of the control variable | |
interchange_legal | bool | see if two loops are interchangeable ( requires a loop as argument) | |
expression | num_oper | int | number of operations in the expression |
num_calls | int | number of function calls in the expression | |
num_array_refs | int | number of array references in the expression | |
assingment | operator | string | the operator used in the assignment (= ,+= ,… ) |
statement | line | int | the line number of the statement |
Some of the actions available in MANET (besides insert and def) are:
Action | Parameters | Target Join Point | Description | ||
---|---|---|---|---|---|
Name | Type | Default | |||
Clone | newName | string | - | function | clones the target method and assigns the clone with a new name |
Interchange | otherLoop | loop | - | loop | interchange the current loop with another, nested, loop |
Unroll | factor | int | 0 | unroll a loop with a given factor | |
Tile | block_size | int | - | perform a loop tiling with the given block size |
<imgcaption larasections|> </imgcaption> LARA is a domain-specific language centered on an aspect-oriented programming approach, being the current approach mainly focused on offline changes (static weaving) to the application. LARA includes both declarative and imperative semantics. The semantic of pointcut expressions and associated advices is fully declarative, whereas the semantic of the code implemented inside functions and advice sections is governed by an imperative model. Moreover, LARA is intended to describe strategies that affect design flows by conveying to the design stages of such flows, specific code transformations, compiler optimizations, or even target system properties.
<imgref larasections> llustrates the structure of a LARA aspect. In brief, Aspects can be decomposed in different aspectdef blocks for better modularity and aspects can recursively invoke other aspects. Each aspectdef comprises a set of optional preliminary statements, such as input and output parameters, static fields, and conditional checks to test if an aspect can run with the given inputs. For the main scope, LARA uses the JavaScript syntactic and semantic elements for the common code statements such as assignments, loops, conditional statements, among others (explained in the next tutorial); and weaving statements to select pointcuts and advise over the join points. The weaving statements, depicted in the white code block, comprise select, apply and condition statements, the essential statements in LARA to define strategies.
An aspectdef is the modularity unit of LARA. Hence, all the aspects have to be defined inside an aspectdef. The aspectdef contains an unique identifier.
<sxh lara; toolbar: false; > aspectdef MyFirstAspect
// aspect code
end </sxh>
A LARA file, which uses the *.lara extension, may contain multiple aspects. The first aspect is considered as the main aspect and it is not required to be called as main.
<sxh lara; toolbar: false;> aspectdef MyFirstAspect This is the aspect that is executed aspect code end
aspectdef MySecondAspect Only executes if called by the main aspect/recursive call aspect code end
aspectdef UtilityAspect Yet another callable aspect aspect code end </sxh>
An aspect can call other aspects by using the statement call. An aspect may be called directly by its name if no state is required to maintain for the called aspect. On the other hand, when we require to maintain the aspect state (for instance to retrieve the output result of the aspect execution) one may instantiate the aspect (similar to an object instantation) before calling it.
<sxh lara; toolbar: false; > aspectdef main
//Normal call to an aspect. No state is maintained call SayHello; //Instantiation and call of an aspect. Has state var hello = new SayHello(); call hello(); //Same as above, but with less code! call hello: SayHello();
end
aspectdef SayHello
println('Hello World');
end
</sxh>
This example will output:
Hello World Hello World Hello World
An aspect may contain input and output parameters, allowing passing multiple arguments when calling an aspect and then use the outputs of the call for posterior use. The inputs may be initialized with a default value, while the outputs have to be assigned in the aspect body. The following code shows some examples of calling aspects using input and output arguments. The input arguments also maintains their state between calls, i.e., if we use the same instance of an aspect in multiple calls, if no new inputs are given, the inputs maintain their old values. On the other hande, the output arguments do not maintain state between calls.
<sxh lara; toolbar: false; > aspectdef main
// The arguments may be given similar to a function call call PrintMsg('Hello', 'World'); // Output: 'Hello World' // Or by using 'named arguments'. The called aspect uses a default value for 'a' call PrintMsgWithDefaultA( b: 'World'); // Output: 'Hello World' // Or when we instantiate an aspect or we assign the input before the call var msg = new PrintMsg('Hello'); // Defines 'a' with 'Hello' msg.b = 'World'; // Defines 'b' with 'World' call msg(); // Output: 'Hello World' call msg(b: 'Universe'); // Output: 'Hello Universe' call msg(); // Output: 'Hello Universe' // Here we call an aspect with a single output 'c' call result: Concat('Bye', 'World'); println(result.c); // Output: 'Bye World'
end
aspectdef PrintMsg
input a,b end //no default values for 'a' and 'b' println(a + ' ' + b);
end
aspectdef PrintMsgWithDefaultA Same as above, but with a default value for a input a = 'Hello', b no default value for 'b'
end println(a + ' ' + b);
end
aspectdef Concat
input a,b end output c end c = a + ' ' + b;
end
</sxh>
Executing this code will output:
Hello World Hello World Hello World Hello Universe Hello Universe Bye World
The select statement defines the join point selection over the source code, i.e., selection of points of interest in the target code. The select statement contains a unique identifier to be used by apply statements, and a pointcut expression to define the join points to be captured. The pointcut expression contains the information relevant for the capture of a specific group of join points. It is expressed by the declaration of join points combined with logical expressions and attribute limitation.
The following example shows some select statements
<sxh lara; toolbar: false; > aspectdef MyFirstSelect
select program end; // Select the root join point
end </sxh>
<sxh lara; toolbar: false; >
apply end
</sxh>
;#; Basic 101: How to LARA | JavaScript in LARA → ;#;