====== Basic 101: How to LARA ====== ;#; Basic 101: How to LARA | [[lara:tutorial:js| 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: - The definition of an aspect; - How to use the select, apply and condition statements; - How to call other aspects and use input/output arguments. In this tutorial we are using part of the target language specification used in [[lara:documentation#manet|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: * The arrows between join points (e.g. **body** → **loop**) means that the source join point is able to select the target join point; * A label in an arrow depicts a selection of the target join point but with a different **alias**, sometimes considering just part of the types of the target join point (such as only the first statement, **first_stmt**, from a **body**). * The **body** join point selected by **loop** and **if** is the same as the one above, it is presented as a different node just for readability purposes. This means that after selecting **body** from **loop** or **if**, we are able to select the same join points in the first **body**. {{ :lara:tutorial:basic101graph.png?nolink&800 |}} 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 | ===== Aspect Structure ===== {{ :lara:img:larastructure.png?nolink&300|}} 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. 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 [[lara:tutorial:js|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. ==== aspectdef ==== 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. aspectdef MyFirstAspect // aspect code end 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//. 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 ==== call ==== 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. 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 This example will output: Hello World Hello World Hello World ==== input/output ==== 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. 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 Executing this code will output: Hello World Hello World Hello World Hello Universe Hello Universe Bye World ===== Select ===== 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 aspectdef MyFirstSelect select program end; // Select the root join point end ===== Apply ===== apply end ==== Condition ==== ==== Actions ==== ==== Iterating ==== ===== Actions ===== ;#; Basic 101: How to LARA | [[lara:tutorial:js| JavaScript in LARA → ]] ;#;