The following NaBL2 constraint rule:

[[ _ ^ (_) : s ]] := new s.

generates the following Stratego code:

  nabl2--generate-constraint-default-rule(|nabl2_source, nabl2_args):
    nabl2_term@_ -> nabl2_constraint
    with(ParamsAndType(nabl2_params@(_), nabl2_type@s) := nabl2_args
         <+ fatal-err(
            | <concat-strings> [ "Cannot match expected "
                               , "^ (_) : s"
                               , " with actual "
                               , <nabl2--pp-flat-args> nabl2_args
                               , " when matching "
                               , "_"
                               , " with "
                               , <pp-NaBL2-Term> nabl2_term
                               , "."
                               ]
            ))
    with(if nabl2-debug-constraint-generation-hook then
           <(concat-strings ; debug)> [ "default"
                                      , " [[ "
                                      , <pp-NaBL2-Term> nabl2_term
                                      , " ^ "
                                      , <pp-NaBL2-CTerm> nabl2_params
                                      , " : "
                                      , <pp-NaBL2-Type> nabl2_type
                                      , " ]]"
                                      ]
         end)
    with(id)
    with(s := <nabl2--new-scope(|nabl2_source)> "s" ; id)
    with(nabl2_index := <nabl2--get-ast-index> nabl2_term
         ; nabl2_metadata := [ CAstProperty(nabl2_index, Params(), nabl2_params)
                             , CAstProperty(nabl2_index, Type(), nabl2_type)
                             ])
    with(nabl2_constraint := <conc ; nabl2--flatten-list> (nabl2_metadata, []))

but this will always cause a failure, because the variable s is being bound twice:

  • In line 3 from the top: nabl2_type@s
  • In line 6 from the bottom: with(s := <nabl2--new-scope(|nabl2_source)> "s" ; id)

A workaround is to wrap the scope in a constructor:

[[ _ ^ (_) : ScopeType(s) ]] := new s.

which then changes line 3 to:

with(ParamsAndType(nabl2_params@(_), nabl2_type@nabl2_type) := nabl2_args

preventing the double bind (although nabl2_type@nabl2_type is also a weird binding!)

Submitted by Gabriƫl Konat on 23 January 2017 at 10:16

On 30 January 2017 at 17:29 Hendrik van Antwerpen commented:

Problem is that using s in the type causes it to match against the passed arguments. Using new results in imperatively creating a new scope. Using both in the same rule causes a clash during traversal. This could be resolved by adding an equality constraint, instead of doing the match against the variable directly.


On 22 March 2017 at 16:15 Hendrik van Antwerpen commented:

this is fixed in recent builds.


On 22 March 2017 at 16:15 Hendrik van Antwerpen closed this issue.

Log in to post comments