Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!dogie.macc.wisc.edu!uwvax!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Translating Pascal ==> C: nested procedures Message-ID: <17880@mimsy.UUCP> Date: 5 Jun 89 03:16:23 GMT References: <3276@cps3xx.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 99 In article <3276@cps3xx.UUCP> rang@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@mimsy.umd.edu Path: uunet!mimsy!chris