WebSnap gives templates to Pascal

By: Ivan Babikov

Abstract: The script engine of WebSnap can generate not only HTML but something else as well, including source code.

WebSnap gives templates to Pascal

WebSnap gives templates to Pascal.

 

Since there is no templates feature in most programming languages except C++, the only way of creating similar routines for different data types is only copying of code from one routine to all others for each required data type. For example, if we need to make Swap routines for Integer and String fields, we will have to create several almost identical procedures like these ones:


procedure Swap(var x,y: String); overload;
var z: String;
begin
 z:= x; x:= y; y:= z;
end;

procedure Swap(var x,y: Integer); overload;
var z: Integer;
begin
 z:= x; x:= y; y:= z;
end;

If the code is quite changeable, one day we can forget to propagate our changes to all necessary places. Obviously, that is not what we want. To avoid it and automate the process we need to create a kind of code generator.

Actually, there is nothing new in the "code generator" term. There are some development tools (e.g. Clarion) which have been using code generation for years.

It is pretty understandable, how to create source code by concatenating string constants and putting the result to output file inside a typical Pascal program. But the resulting program won't be flexible, since all the necessary for generation logic is incorporated inside the resulting binary code (certainly, we can place some data in external files but it's still incomplete solution). What we really need is a type enumeration logic embedded into the serialized source code.

There are some well-known technologies (e.g. ASP, JSP or PHP) which can generate HTML files from HTML template files, consisting of HTML core code and embeddings made using these languages. The problem is that these technologies are supposed to work under certain web servers and write their output into HTTP responses.

Fortunately, a similar technology called WebSnap appeared in Borland Delphi6 and Kylix2 which gives us possibility of creating autonomous CGI application with JScript facility.

So, now we can create a template file, then run our CGI executable and have functions for all necessary data types generated. And the template will look like this:


<%
DataTypes= new Array('String','Integer','Real') // Definitions of required data types to be supported by Swap
for (i=0; i<DataTypes.length; i++) // Enumeration through all data types
{ %>
procedure Swap(var x,y: <%=DataTypes[i]%>); overload;
var z: <%=DataTypes[i]%>;
begin
 z:= x; x:= y; y:= z;
end;
<% } %>

Now you can compare it with an equivalent C++ code:


template <class T> void swap( T &x, T &y)
{ T z;
z= x; x= y; y= z;
}

You may see, that the amount of code in our example is twice bigger. In fact, this is because the code of our Swap procedure is rather small. If it grows, the relational weight of JScript embeddings in template will be reduced.

The full example of Swap procedure is in PascalExample/Template.asp file. I gave *.asp extension to this file just because some text editors can do suitable syntax highlighting for WebSnap template files having this extension. To start generation based on this template, compile TemplateGen.dpr with Delphi and run generate.bat in PascalExample directory.

I created this example by means of WebSnap Application Wizard, choosing the "CGI Stand-alone executable" option in the "Server type section" in "New WebSnap application" dialog. Then I changed the HTMLFile property of PageProducer1 to "template.asp" and, for accuracy, changed the name of PageProducer1 to TempleteHandler. Finally, I created the code for OnDispatchage event of the main project form:

procedure TMain.WebAppPageModuleBeforeDispatchPage(Sender: TObject;
  const PageName: String; var Handled: Boolean);
begin
 // Starting processing the templete file
 Response.Content:= TemplateHandler.Content;
 Handled:= true;
end;

And that is all the work required for creating a generator based on WebSnap. You may also build it with Kylix2 and run under Linux.

Then, having created the following template file Templete.asp


unit SwapProc;

interface
<%
 DataTypes= new Array('String','Integer','Real')
 for (i=0; i<DataTypes.length; i++)
 { %>
procedure Swap(var x,y: <%=DataTypes[i]%>); overload;<%
} %>

implementation

<%
 for (i=0; i<DataTypes.length; i++)
 { %>
procedure Swap(var x,y: <%=DataTypes[i]%>); overload;
var z: <%=DataTypes[i]%>;
begin
 z:= x; x:= y; y:= z;
end;
<% } %>
end.

we can catch the following Pascal code as the standard output of CGI program and redirect it to the following SwapProc.pas file:


unit SwapProc;

interface

procedure Swap(var x,y: String); overload;
procedure Swap(var x,y: Integer); overload;
procedure Swap(var x,y: Real); overload;

implementation


procedure Swap(var x,y: String); overload;
var z: String;
begin
 z:= x; x:= y; y:= z;
end;

procedure Swap(var x,y: Integer); overload;
var z: Integer;
begin
 z:= x; x:= y; y:= z;
end;

procedure Swap(var x,y: Real); overload;
var z: Real;
begin
 z:= x; x:= y; y:= z;
end;

end.
 

Conclusion:

Code generators are mentioned quite often these days. You may also use this technique for generating template objects, persistent business objects from a database structure, stubs and skeletons for them. In the last case you will need to add a database structure accessing facility into your templates by means of WebSnap adapters.


Full source code is available at http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=17577

 


Server Response from: ETNASC04