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"
% Preserve comments in output
include "TILCommentOverrides.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>