Pennington / Example

XTRAN Demonstration:  Translating PL/I PROCEDURE Parameters/Arguments as "By Value"

PL/I normally passes arguments to PROCEDUREs "by reference"; that is, what is passed is the address of the argument.  However, if a calling argument is a constant or an expression, PL/I passes it "by copy":  The PL/I compiler generates code to create a local copy of the constant or expression value and passes the copy's address as the argument.

When XTRAN translates PL/I to C/C++, it reflects this behavior:  It normally generates code to pass an argument's address, but if the argument is a constant or expression, it generates code to declare a local copy and pass its address.

However, the chances are that if PL/I code passes a constant or expression as an argument, then the called PROCEDURE doesn't modify the corresponding parameter.  Even if it does, it modifies only the copy whose address was passed to it.  Therefore, in the translated C/C++ we can safely pass the parameter by value.  In fact, XTRAN extends the PL/I language by adding a new declaration attribute, XTR_BYVAL, which tells XTRAN to translate the PROCEDURE parameter and all corresponding calling arguments as "pass by value".

The knowledge of which PROCEDURE parameters actually have matching arguments that are constants or expressions is scattered throughout all of the PL/I modules to be translated.

XTRAN's powerful PL/I analysis capability comes to the rescue.  Click here for an XTRAN analysis example that, using a set of XTRAN rules ("meta-language"), examines all arguments of all PROCEDURE calls in the code it is given, creates a database of constant and expression argument occurrences, and reports those occurrences.

After running that analysis on the code below; we used the resulting report to modify the appropriate PROCEDURE parameter declarations, adding XTR_BYVAL to them.

The following input to, and output from, XTRAN, is untouched.



* Input to XTRAN:

DCL extprc1 ENTRY (FIXED (15) BIN XTR_BYVAL, FLOAT (5) BIN XTR_BYVAL,
          FIXED (31) BIN) EXT;
        DCL extprc2 ENTRY (CHAR (*) XTR_BYVAL, FIXED (31) DEC XTR_BYVAL,
          FIXED (15) BIN) EXT;

%       DCL (ppint1, ppint2) FIXED;
%       ppint1 = 1;
%       ppint2 = 2;
%       DCL (ppchr1, ppchr2) CHAR;
%       ppchr1 = '''abc''';
%       ppchr2 = '''xy''';
%       DCL ppexpr FIXED;
%       ppexpr = ppint1 + 1;

prc:    PROCEDURE;
        DCL (int1, int2) FIXED (31) BIN;
        DCL (flt1, flt2) FLOAT (5) DEC;
        DCL (chr1, chr2) CHAR (5);

nstprc: PROCEDURE (arg1, arg2);                 /*nstprc: PROCEDURE...;*/
            DCL arg1 FIXED (31) BIN XTR_BYVAL;
            DCL (arg2, i) FIXED (31) BIN;
            i = extprc1(1, 2.0, i);             /*const args 1 & 2*/
            END nstprc;
        extprc1(int1, flt1, i);                 /*no const args*/
        extprc1(1, flt1, int1);                 /*const arg 1*/
        extprc1(int1 + 1, flt1, int1);          /*expr arg 1*/
        extprc1(ppexpr, flt1, int1);            /*expr arg 1*/
        extprc1(int1, 1.0, int1);               /*const arg 2*/
        extprc1(ppint1, flt2, int1);            /*const arg 1*/
        extprc2(chr1, int2, int1);              /*no const args*/
        extprc2('abc', int2, int1);             /*const arg 1*/
        extprc2(chr1, 2, int1);                 /*const arg 2*/
        extprc2('a' | 'bc', 2, int1);           /*expr arg 1, const arg 2*/
        extprc2(ppchr1, chr2, int1);            /*const arg 1*/
        extprc2('abc', ppchr2, int1);           /*const arg numbers 1,2*/
        nstprc(int1, int2);                     /*no const args*/
        nstprc(1, int2);                        /*const arg 1*/
        end prc;


* Output from XTRAN:

        extern void extprc1(short, double, long *);
        extern void extprc2(char [], long, short *);

#define PPINT1 1
#define PPINT2 2
#define PPCHR1 "abc"
#define PPCHR2 "xy"
#define PPEXPR (PPINT1 + 1)

static void nstprc(long arg1, long *arg2)       /*nstprc: PROCEDURE...;*/
{
        long i;
        i = extprc1(1, 2., &i);                 /*const args 1 & 2*/
        return;
}
void prc(void)
{
        long int1, int2;
        double flt1, flt2;
        char chr1[5], chr2[5];

        short i;
        extprc1(int1, flt1, &i);                /*no const args*/
        extprc1(1, flt1, &int1);                /*const arg 1*/
        extprc1(int1 + 1, flt1, &int1);         /*expr arg 1*/
        extprc1(PPEXPR, flt1, &int1);           /*expr arg 1*/
        extprc1(int1, 1., &int1);               /*const arg 2*/
        extprc1(PPINT1, flt2, &int1);           /*const arg 1*/
        extprc2(chr1, int2, &int1);             /*no const args*/
        extprc2("abc", int2, &int1);            /*const arg 1*/
        extprc2(chr1, 2, &int1);                /*const arg 2*/
        extprc2("a" || "bc", 2, &int1);         /*expr arg 1, const arg 2*/
        extprc2(PPCHR1, chr2, &int1);           /*const arg 1*/
        extprc2("abc", PPCHR2, &int1);          /*const arg numbers 1,2*/
        nstprc(int1, &int2);                    /*no const args*/
        nstprc(1, &int2);                       /*const arg 1*/
        return;
}


COPYRIGHT 2008; reproduction prohibited without permission.  Revised 2006-11-27

XTRAN is a trademark of Pennington Systems Incorporated.

Pennington Systems Incorporated
8655 East Via de Ventura, Suite G200
Scottsdale, Arizona 85258-3321

Phone:  +1(480)626-5503
Fax:  +1(480)626-7618
Email:  Info@Pennington.com
Web:  http://WWW.Pennington.com

[home] Home