Stratego/XT JIRA  History | Log In     View a printable version of the current page. Get help!  
Issue Details (XML | Word)

Key: STR-321
Type: Task Task
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Eelco Visser
Reporter: Eelco Visser
Votes: 0
Watchers: 0
Operations

Clone this issue
Create sub-task
If you were logged in you would be able to see more operations.
Stratego/XT

List variables in concrete syntax and abstract syntax should have * suffix

Created: 2005-06-12 14:04   Updated: 2008-03-31 20:39
Component/s: None
Affects Version/s: 0.16 (Stratego Core Compiler)
Fix Version/s: 0.16 (Stratego Core Compiler)

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown


 Description  « Hide
When declaring a meta-variable for use in concrete syntax over a list-type it should have a * suffix, unless the variable is not used in abstract syntax.

The problem: take a meta-variable declaration of the form

variables
  "es" [0-9]* -> {Exp ","}*

and use this within a concrete syntax quote *and* within abstract syntax. For example,

Inline : |[ f(es) ]| -> |[ let xs := es in e ]|
            where <lt>(<length> es, 10)
                ; <definition> f => (xs, e)

The use of es between |[...]| gets the abstract syntax Var(ListVar("es")), while the
use of es in the condition becomes Var("es").

Upto Stratego 0.14 this was ignored by the compiler by identifying the two representations.
This came at a considerable cost, however. At numerous places in the compiler the identification
needed to be made.

Starting with Stratego 0.15 a uniform representation is used for list variables, which considerably reduces the impact this feature has on the compiler. However, code such as the above does not work anymore, but will lead to
a complaint that 'variable es is not bound in rule Inline'.

The only solution to this problem is to use proper list variable names for all list variables, i.e. identifiers with a * suffix. This requires a migration of programs using non-proper list variables.

1) Introduce an alternative meta-variable with a * suffix:

variables
  "es" [0-9]* -> {Exp ","}*
  "e" [0-9]* "*" -> {Exp ","}*

Leave the old definition present, otherwise this can lead to unpleasant surprises where meta-variables suddenly become object identifiers.

2) Replace the use of the old meta-variables 'es' with 'es*'

Inline : |[ f(e*) ]| -> |[ let x* := e* in e ]|
            where <lt>(<length> e*, 10)
                ; <definition> f => (x*, e)

In principle this only needs to be done in places where the compiler complains.

3) To force uniform migration the old-style variables can be 'reject'ed:

variables
  "es" [0-9]* -> {Exp ","}* {reject}
  "e" [0-9]* "*" -> {Exp ","}*

 All   Comments   Work Log   Change History      Sort Order:
Eelco Visser [2005-06-12 20:22]
An alternative solution could be to detect list variables without * suffix in concrete syntax fragments during assimilation (in meta-explode). That way these variables can be assimilated as ordinary variables. This works only if the variables are used in tail position of a list or as single variable matching a list.

Advantage: less restrictions on choice of variable names

Disadvantage: complicates assimilation with list-match desugaring

Eelco Visser [2005-06-19 21:23]
The alternative solution turns out to work fine, and makes the representation of list variables more uniform. The migration path suggested in this issue is therefore not necessary. Unless one wants to make use of list variables in the non-concrete syntax part.