Translating Pascal ==> C: nested procedures

Chris Torek chris at mimsy.UUCP
Mon Jun 5 13:16:23 AEST 1989


In article <3276 at cps3xx.UUCP> rang at cpsin3.cps.msu.edu (Anton Rang) writes:
>... I've heard of several "Pascal to C" translators.  How do they handle
>nested procedures?

Chances are that they do not.

>For instance, suppose I have:
>
>		procedure insert_in_symtab(what : node);

[Underscores are not legal in Pascal; perhaps you mean

		procedure insertinsymtab(what : node);

:-) (actually, it should be all uppercase as well, but that goes *too* far)]

>		  function conflict(n1, n2 : node) : boolean;
>		  ...
>		  function check_if_full : boolean;
>		  ...
>		...
>
>		procedure insert_in_strtab(what : string);
>		  function check_if_full : boolean;
>		    { this code uses "what" }
>		  ...
>		...
>
>Do they just rename the nested procedures to unique names and make
>them "static"?  If so, how do they handle accesses to variables which
>are declared in enclosing blocks?

The most efficient way to handle this is generally to expand the argument
lists to intermediate routines as necessary.  For instance, one could
change

	procedure addstr(what : string);
	    function isfull : boolean;
	    begin isfull := false ... end;
	begin ... if isfull then ... end

to

	int addstr_isfull(string_t *what) {	/* pANS syntax */
		int _ret;
		ret = 0; ...
	}

	void addstr(string_t what) {
		...
		if (addstr_isfull(&what)) ...
	}

This gets a bit unwieldy if variables must be passed through several
intermediate procedures or functions:

	procedure foo;
	var a, b, c, d, e, f : int;
	    procedure bar;
		procedure baz;
		    procedure raz;
		    begin ... a := b; c := d; e := f ... end;
		begin ... end; { without using a, b, c, d, e, f }
	    begin ... end;
	begin ... end

which becomes something like

	void foo_bar_baz_raz(a, b, c, d, e, f)
		int *a, *b, *c, *d, *e, *f;	/* K&R 1 syntax */
	{
		...
		*a = *b;
		*c = *d;
		*e = *f;
		...
	}

	void foo_bar_baz(a, b, c, d, e, f)
		int *a, *b, *c, *d, *e, *f;
	{
		...	/* a, b, c, d, e, f unused except to pass to raz() */
	}

	void foo_bar(a, b, c, d, e, f)
		/* and so on */

In practise, however, such sequences are rare.  (Just how rare I cannot
say, but those who have done the analysis prefer static links over
displays, and this is the sort of case where static links might be
slower.)

If the Pascal code uses procedure pointers, translation gets harder.
The most straightforward approach is to pass static links about.  (At
this point you are no longer doing a `translation'; you are compiling,
using C as an assembler.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list