In Stratego, congruences destroy origin information. This is counter-intuitive, if you read a congruence as “apply strategies to subterms of the current term”. We rely on congruences in NaBL, where patterns in NaBL rules are translated into congruences and we need to wrap each congruence (i.e. each constructor occurring in an NaBL pattern), in a origin-track-forced call.

According to Vlad, the root cause is a desugaring of congruences into match-build sequences.

This is related to Spoofax/686.

Submitted by Guido Wachsmuth on 8 January 2014 at 21:14

On 1 January 2015 at 20:13 Daco Harkes commented:

More precisely, nested constructors lose origins, the outside ones do not. (Which makes sense with match-build sequences.)

edge-set-varname(|edge-var') = RHSEdge(RHSTsHelp(id, id, !RHSEdgeName(edge-var')), id)

RHSEdge keeps its origin, while RHSTsHelp loses it.


RHSEdgeName is built, so there one can modify the origins edge-set-varname(|edge-var') = RHSEdge(RHSTsHelp(id, id, !RHSEdgeName(edge-var');custom-origin(|edge-var')), id

To give everything origins edge-set-varname(|edge-var') = RHSEdge(RHSTsHelp(id, id, !RHSEdgeName(edge-var');custom-origin(|edge-var'));custom-origin(|edge-var'), id) but the RHSTsHelp then gets the wrong origin.

Better would be edge-set-varname(|edge-var') = RHSEdge(tsh@RHSTsHelp(id, id, !RHSEdgeName(edge-var');custom-origin(|edge-var'));custom-origin(|tsh), id), but @ is not supported in congruences.

Two congruences instead of one does not help (there is probably inlining going on in the compiler), so two congruences only work with origin-track-forced

edge-set-varname(|edge-var') = RHSEdge(origin-track-forced(edge-set-varname(|edge-var')), id)
edge-set-varname(|edge-var') = RHSTsHelp(id, id, !RHSEdgeName(edge-var');custom-origin(|edge-var'))

Inlining this gives the origin-track-forced solution, which is mildly short:

edge-set-varname(|edge-var') = RHSEdge(origin-track-forced(RHSTsHelp(id, id, !RHSEdgeName(edge-var');custom-origin(|edge-var'))), id)

Log in to post comments