Influence on order of macro-execution within one single template fragment?

Hi,

i have a template fragment of InstanceMethodDeclaration as its root. Within that i have several macros where one in StatementList is depending on the preceding execution of the macro around ParameterDeclaration. But the execution order of the macros is (deterministic) not as i want it. It is as follows:

1.) name-Attribute (used for method name)

2.) returnType (Type)

3.) body (StatementList) -> Statements within that list in a consecutive way

4.) parameter (ParameterDeclaration)

2 Questions:

  1. Is there a declarative way to change that order in any way (i want to switch 3. and 4.)? Or may i force execution of 4. while executing macro of 3.?
  2. How is the logic that calculates the order for macro-execution? (Attributes before children? Children seem to be ordered by cardinality -> "1" before "0..n"?)

I know that i may do what i want via the post-processing-script but not that easy and understandable as i could do when the order changes.

Thanks,

Mirko

3 comments
Comment actions Permalink

Hi,

MPS doesn't guarantee the order in which reduction rules are applied.

Normally, there shouldn't be cross-dependency between them (keeping in mind that any concept can be extended or reused).

Your questions:

1. Nope. The lists (children, properties, references etc.) are kept unsorted in your input model. The order can change when you edit it.

2. Properties are processed before children. References are restored in the end of a generation micro-step when we have built an output tree.

Each generation micro-step consists of several stages.

1. We are building up the resulting tree, trying to apply reduction rules (or just copying nodes from the input model). (executed macros are: $COPY_SRC$, $LOOP$, $IF$, $[property macro], etc.)

1a. Applying weaving rules.

2. Processing postponed adjustments ($MAP_SRC$).

3. Restoring references. Some of them are restored automatically. Others are provided by ->$[ ] macro. (->$[reference macro])

If I understand correctly, you need to refer parameters. Use reference macro, or refer them directly in the template (if parameters are defined there).

Example:

<TF void process(int $[iii]) {

    int q = iii; // Note: iii will be replaced with the name generated for the parameter

} TF>

Regards,

Evgeny

Docs on macros and template language: http://confluence.jetbrains.net/display/MPS/Generator+Language

0
Comment actions Permalink

Hi Evgeny,

thanks for your answer.

Evgeny.Gryaznov schrieb:

[...]

If I understand correctly, you need to refer parameters. Use reference macro, or refer them directly in the template (if parameters are defined there).

Example:

<TF void process(int $[iii]) {

    int q = iii; // Note: iii will be replaced with the name generated for the parameter

} TF>

[...]

no, actually i have a dynamic count of parameters being generated in a $COPY_SRCL$-MACRO. Within the same template-method i have count-time calls to setter-methods ($LOOP$-MACRO within the same MethodDeclaration-template and so within the same micro-step too) and i want to create parameter-reference-nodes for those setter-param. As the param-reference-nodes within the setter-methods are being created BEFORE the parameter-nodes i can't reach them and would have to do some workaround, f.e. rather complex code in the post-script :-(. Any idea for a better approach?

Regards,

Mirko

0
Comment actions Permalink

Hi Mirko,
Not sure it’s your case but if you have same input nodes (use the same procedure to compute them) in your $COPY-SRCL$ and $LOOP$ macros, then the following will  work fine again:

<TF void method($COPY-SRCL$[ int $[p] ]) {
   $LOOP$[ setter( p ) ]   // all parameter references will be resolved automatically
} TF>

Regards, Igor.

0

Please sign in to leave a comment.