Re: Converting Pascal to C++, C# or VB

George Neuner <>
8 Apr 2006 17:06:00 -0400

          From comp.compilers

Related articles
Converting Pascal to C++, C# or VB (Steve) (2006-04-03)
Re: Converting Pascal to C++, C# or VB (Marco van de Voort) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (2006-04-08)
Re: Converting Pascal to C++, C# or VB (John O'Harrow) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (Hans-Peter Diettrich) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (Eric) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (George Neuner) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (Martin Ward) (2006-04-08)
Re: Converting Pascal to C++, C# or VB (Neelakantan Krishnaswami) (2006-04-08)
Re: Converting Pascal to C++, C# or VB ( (2006-04-08)
Re: Converting Pascal to C++, C# or VB (Marco van de Voort) (2006-04-09)
Re: Converting Pascal to C++, C# or VB (Marco van de Voort) (2006-04-09)
Re: Converting Pascal to C++, C# or VB (Marco van de Voort) (2006-04-09)
[5 later articles]
| List of all articles for this month |

From: George Neuner <>
Newsgroups: comp.compilers
Date: 8 Apr 2006 17:06:00 -0400
Organization: Compilers Central
References: 06-04-017
Keywords: Pascal, translator
Posted-Date: 08 Apr 2006 17:06:00 EDT

On 3 Apr 2006 01:39:03 -0400, "Steve" <> wrote:

>I currently have a translator that converts [ISO std Pascal] to Delphi.
>I plan to extend this translator to generate the new language too. The
>translator creates an AST for all the source, and keeps track of
>publics/externs. Several passes are then made over the AST to generate the
>Delphi units. It's a complicated process, especially for the structured
>So the question is which language to use? I know C++ a little, but the other
>two are new to me.

Hopefully someone will have already done such a translator - it is not
something you want to tackle without having a thorough understanding
of both the source and target languages. If you _really_ do want/have
to do this, here are a few things to chew on.

As you have already surmised, you can't directly translate Pascal into
any of those languages. The simplest to work with would be C++ ...
the others have some intrinsic features [such as GC] that can further
complicate a straight forward translation. The difficulty level
depends on how many of Pascal's incompatible features you want to
handle and how closely you wish the generated code to visually match
the original Pascal source.

Nested Routines:
Simulating nested routines is fairly simple - you turn the top level
function or procedure into a C++ "function" object - that is an object
that overloads the call operator "()". You convert the shared local
variables and top level parameters to member variables and any nested
routines into member functions [or recursively, into member function
objects]. See example below.

You can use and pass references(pointers) to function objects to
simulate procedure variables and parameters. C++ allows taking the
address of a function and passing it to another function, but because
all C++ functions are top-level, that won't help with nested scoping
issues so it is best to use function objects and references

The type of a Pascal array includes shape information [dimension,
size] as well as element type. Additionally, in Pascal any array may
have a displaced origin, ie. negative indices.

In C++, arrays have a single dimension and indexing is zero based -
period. Code using negative indices must be rewritten to use zero
based indexing.

Additionally, C++ arrays do not retain their shape information as they
are passed around - all that is passed is a pointer to the first
[zeroth] element. If the shape of an array is known at compile time,
a formal array parameter of that shape can be specified in the
function prototype, but otherwise you must somehow pass the shape
information along with the array.

You can create an "array" object which remembers the shape and element
type, allocates/deallocates the element memory, maps negative indices
appropriately and overloads the index operator "[]" to access the
elements. You can choose to create a separate class for each order
[1d,2d,etc.] of array used, or just recursively use a 1d array class
for "array of array" style. The first is more efficient for higher
order arrays, the second slower but more flexible. In either case,
the array class(es) should be created as templates so that the base
element type is variable. See the "vector" class in the STL or the
"CArray" class in MFC for examples of array templates.

Simple records can be mapped irectly to structs or public classes.
Variant records can be simulated using tagged unions or with a class
heirarchy depending on your needs.

Keep in mind that C++ has no equivalent of "WITH <blah> DO" - all
struct/class member accesses must be unambiguous or fully qualified so
you need to decide how to handle that.

I forget whether ISO allows files in records. An object based
implementation will be easier as GET/PUT will have do the right thing
for all your record types.

I/O in C++ is nothing like Pascal [even forgetting about files in
records]. C++ I/O is stream based while Pascal is record oriented.
You can easily simulate GET/PUT behavior for simple types and for
arrays/structs based on simple types, but you cannot simply write or
read objects.

Your equivalents of PUT will need to recognize an object and store the
object type and data in a way that allows the object to be
reconstructed on the fly when GET reads it back. This is called
"serialization" and in C++ it requires "run time type information"
[RTTI] and some fairly advanced coding techniques.

FOR Loops:
Pascal specifies that the number of iterations of a FOR loop cannot be
modified by the body of the loop [GOTO and . Implementations handle
that variously by disallowing assignment to the loop index variable or
by using a hidden loop index counter.

The "for" construct in C++ does not have this property - it is simply
syntactic sugar for the equivalent "while" loop. All uses of FOR in
the Pascal program must be checked and rewritten if necessary to
ensure the iteration count is accurately maintained.

It's been too long since I did any serious coding in Pascal so there
are probably a hundred other nit-picking things that will plague you
in translation that I can't think of just now. Good luck.


ex: function objects

procedure foo( x: integer; y: var integer );
var z;
        procedure in_foo( w: integer );
                y := w+z;
        z := 2;
        in_foo( x );

can become something like:

class _foo
      int* yref;
      int z;
      void in_foo( int w );
      void operator()( int x, int &y );
void _foo::operator()( int x, int& y )
      yref = &y;
      z = 2;
      in_foo( x );
void _foo::in_foo( int w )
      *yref = w + z;

which is used like so:

main( ... )
_foo foo;
int y;

      foo( 1, y ); // y := 3

Overloading the "()" operator allows you syntactically to use the name
of the object variable directly as a function name. For an automatic
translation tool it would be easiest to put all of the top level
parameters and all of the local variables into the object instead of
picking and choosing as I did here.

The example can be extended recursively to handle the case where
in_foo had further nested routines - just make an _in_foo class and
declare object "_in_foo in_foo" as a member of class _foo.
etc., ad nauseam.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.