New implementations of IFMATCH and FILL

[Home] [Publications] [Software] [G.K. Chesterton] [GKC books] [GKC pictures]

I have finally got round to implementing the proposed new implementations for IFMATCH and FILL in WSL.

The old versions had two serious problems:

  1. There was an ambiguity in IFMATCH: does ~?foo mean "match an item and store the result in foo" or "match against the current value of foo". Currently, IFMATCH takes the former interpretation if the variable is the empty sequence < >. For global variables, the result of an IFMATCH depends on whether the variable is bound or not in some procedure further up the (dynamic) call path. In practice, this means that if you want to match against any binary IF statement, for example, then you need to surround the IFMATCH by a local variable structure:
    VAR < B := < >, S1 ;= < >, S2 := < > >:
    IFMATCH Statement IF ~?B THEN ~*S1 ELSE ~*S2 FI
  2. There used to be no way to interpolate the value of an expression (eg @I^2) in a FILL: the value must be stored in a variable first.

The new syntax is as follows:

  1. New types for interpolation: ~?(expn), ~*(expn), ~?=var and ~*=var. The first two have a single component of type T_Expression. The expression is evaluated *before* the match or fill begins and is then interpolated into the item. The ~?=var and ~*=var matches can only appear *after* a corresponding ~?var, ~*var or ~+var. They match against the previously matched value: they can *only* appear in an IFMATCH, not in a FILL.

    Types are: @One_Pattern_Type?, @Many_Pattern_Type?, @Any_Pattern_Type?, @One_Int_Type?, @Any_Int_Type?, @One_Var_Type?, @Any_Var_Type?


    S := FILL Statement v := ~?(e) ENDFILL

    Names for the types are T_Cond_Int_One and T_Cond_Val_One ie: T_{Stat,Expn,Cond,Defn,Lvalue,Assign,Guarded,Action}_{Int,Val}_{One,Any} plus T_Name_Int_One and T_Name_Val_One

  2. Thanks to the new interpolation syntax, within an IFMATCH the patterns ~?name, ~*name and ~+name will *always* match against any current item (or list of items) and store the resulting match in a new local variable. Any global value of the variable is ignored. Also, there can be only one occurrence of ~?name, ~*name or ~+name for each name: any "backreference" to something previously matched in the pattern should use the new syntax ~?=name or ~*=name. For example:
    IFMATCH Statement DO ~*S; ~*=S OD

    will match against any DO loop whose body consists of a duplicated sequence of statements, eg:

    DO x := x + 1;
       IF x > 3 THEN EXIT(1) FI; 
       x := x + 1; 
       IF x > 3 THEN EXIT(1) FI OD
  3. The interpolation types are used in IFMATCH to match against the value of an expression. The variables in the expression are always global variables, for example:
    IFMATCH Statement IF ~?B THEN ~*S ELSE ~*(S) FI
    THEN ...

    will match any binary IF statement whose ELSE body is given in the global variable S, while:

    IFMATCH Statement IF ~?B THEN ~*S ELSE ~*=S FI
    THEN ...

    will match any IF statement whose ELSE body is the same as the THEN body.

    Note: matches are "loose" with respect to Lvalues and Expressions, so that we can match an Lvalue against an Expression etc.

    For example: IFMATCH Statement ~?v := ~?=v THEN ... ENDMATCH will match when the current statement is an assign or assignment statement whose LHS and RHS are the same.

[Home] Back to my home page.
Last modified: 23rd July 2009
Martin Ward, De Montfort University, Leicester.