For-to-WhileUsingTXL

Software Transformation Systems
TXL solution to TIL Chairmarks #2.2, transform all "for" statements to their equivalent "while" statement form.

-- JamesCordy - 10 Oct 2005

File "TILfortowhile.Txl"

% Convert Tiny Imperative Language "for" statements to "while" form
% Jim Cordy, August 2005

% This program converts all "for" statements in a TIL program to
% their equivalent "while" form

% Some details assumed:
%
% - It is not clear whether TIL is scoped or not.  We assume not
%   since there is no explicit scoping statement in the language.
%
% - The "for" statement of TIL is a "declaring for".
%   We assume this means it automatically declares its control variable.
%
% These assumptions can be trivially changed here if TIL changes.

% Based on the TIL grammar
include "TIL.grm"

% Rule to convert every "for" statement
rule main
    % Capture each "for" statement, in its statement sequence context
    % so that we can replace it with multiple statements
    replace [statement*]
        'for Id [id] := Expn1 [expression] 'to Expn2 [expression] 'do
            Statements [statement*]
        'end
        MoreStatements [statement*]

    % Need a unique new identifier for the upper bound
    construct UpperId [id]
        Id [_ 'Upper] [!]

    % Construct the iterator
    construct IterateStatement [statement]
        Id := Id + 1;

    % Replace the whole thing
    by
        'var Id;
        Id := Expn1;
        'var UpperId;
        UpperId := (Expn2) + 1;
        'while Id - UpperId 'do
            Statements [. IterateStatement]
        'end
        MoreStatements
end rule

Example run:

<linux> cat multiples.til
// Test of declaring for loop in TIL
// Output first 10 multiples of numbers 1 through 9
for i := 1 to 9 do
for j := 1 to 10 do
    write i*j;
end end
<linux> txl multiples.til TILfortowhile.Txl
TXL v10.4a (15.6.05) (c)1988-2005 Queen's University at Kingston
Compiling TILfortowhile.Txl ... 
Parsing multiples.til ...
Transforming ...
// Test of declaring for loop in TIL
// Output first 10 multiples of numbers 1 through 9
var i;
i := 1;
var i_Upper1;
i_Upper1 := (9) + 1;
while i - i_Upper1 do
    var j;
    j := 1;
    var j_Upper1;
    j_Upper1 := (10) + 1;
    while j - j_Upper1 do
        write i * j;
        j := j + 1;
    end
    i := i + 1;
end
<linux>