/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)call.c 1.3 10/2/80";
* Call generates code for calls to
* user defined procedures and functions
* and is called by proc and funccod.
* P is the result of the lookup
* of the procedure/function symbol,
* and porf is PROC or FUNC.
* Psbn is the block number of p.
call(p
, argv
, porf
, psbn
)
register struct nl
*p1
, *q
;
if (p
->class == FFUNC
|| p
->class == FPROC
)
put(2, PTR_RV
| cbn
<< 8+INDX
, p
->value
[NL_OFFS
]);
* for the function return type
put2(O_PUSH
, even(-width(p
->type
)));
switch( classify( p
-> type
) ) {
temp
= sizes
[ cbn
].om_off
-= width( p
-> type
);
putlbracket( ftnno
, -sizes
[cbn
].om_off
);
if (sizes
[cbn
].om_off
< sizes
[cbn
].om_max
) {
sizes
[cbn
].om_max
= sizes
[cbn
].om_off
;
putRV( 0 , cbn
, temp
, P2STRTY
);
funcbn
= p
-> nl_block
& 037;
for ( i
= 1 ; i
< funcbn
; i
++ ) {
sprintf( starthere
, EXTFORMAT
, enclosing
[ i
] );
starthere
+= strlen( enclosing
[ i
] ) + 1;
sprintf( starthere
, EXTFORMAT
, p
-> symbol
);
starthere
+= strlen( p
-> symbol
) + 1;
if ( starthere
>= &extname
[ BUFSIZ
] ) {
panic( "call namelength" );
putleaf( P2ICON
, 0 , 0 , p2type( p
) , extname
);
* FRTN( frtn , ( *FCALL( frtn ) )(...args...) )
putleaf( P2ICON
, 0 , 0 , p2type( p
) , "_FRTN" );
putRV( 0 , cbn
, p
-> value
[NL_OFFS
] , P2PTR
|P2STRTY
);
, ADDTYPE( P2PTR
, ADDTYPE( P2FTN
, p2type( p
) ) )
putRV( 0 , cbn
, p
-> value
[NL_OFFS
] , P2PTR
|P2STRTY
);
putop( P2CALL
, p2type( p
) );
* Loop and process each of
* arguments to the proc/func.
if ( p
-> class == FUNC
|| p
-> class == PROC
) {
for (p1
= p
->chain
; p1
!= NIL
; p1
= p1
->chain
) {
error("Not enough arguments to %s", p
->symbol
);
if (r
!= NIL
&& r
[0] != T_VAR
) {
error("Expression given (variable required) for var parameter %s of %s", p1
->symbol
, p
->symbol
);
q
= lvalue( (int *) argv
[1], MOD
, LREQ
);
error("Parameter type not identical to type of var parameter %s of %s", p1
->symbol
, p
->symbol
);
q
= rvalue(argv
[1], p1
->type
, RREQ
);
* structure arguments require lvalues,
switch( classify( p1
-> type
) ) {
q
= rvalue( argv
[1] , p1
-> type
, LREQ
);
precheck( p1
-> type
, "_RANG4" , "_RSNG4" );
q
= rvalue( argv
[1] , p1
-> type
, RREQ
);
q
= rvalue( argv
[1] , p1
-> type
, RREQ
);
if ( isa( p1
-> type
, "d" )
putop( P2SCONV
, P2DOUBLE
);
if (incompat(q
, p1
->type
, argv
[1])) {
cerror("Expression type clashed with type of value parameter %s of %s", p1
->symbol
, p
->symbol
);
if (isa(p1
->type
, "bcsi"))
switch( classify( p1
-> type
) ) {
q
= flvalue( (int *) argv
[1] , FFUNC
);
error("Function type not identical to type of function parameter %s of %s", p1
->symbol
, p
->symbol
);
q
= flvalue( (int *) argv
[1] , FPROC
);
error("Procedure parameter %s of %s cannot have a type", p1
->symbol
, p
->symbol
);
* if this is the nth (>1) argument,
* hang it on the left linear list of arguments
putop( P2LISTOP
, P2INT
);
error("Too many arguments to %s", p
->symbol
);
} else if ( p
-> class == FFUNC
|| p
-> class == FPROC
) {
* formal routines can only have by-value parameters.
* this will lose for integer actuals passed to real
* formals, and strings which people want blank padded.
for ( ; argv
!= NIL
; argv
= argv
[2] ) {
q
= rvalue(argv
[1], NIL
, RREQ
);
* structure arguments require lvalues,
p1
= rvalue( argv
[1] , NIL
, RREQ
);
switch( classify( p1
) ) {
if ( p1
-> class == STR
&& slenflag
== 0 ) {
error("Implementation can't construct equal length strings");
q
= rvalue( argv
[1] , p1
, LREQ
);
error("Implementation can't coerice integer to real");
q
= rvalue( argv
[1] , p1
, RREQ
);
switch( classify( p1
) ) {
putstrop( P2STARG
, p2type( p1
) ,
lwidth( p1
) , align( p1
) );
* if this is the nth (>1) argument,
* hang it on the left linear list of arguments
putop( P2LISTOP
, P2INT
);
if ( p
-> class == FFUNC
|| p
-> class == FPROC
) {
put(2, PTR_RV
| cbn
<< 8+INDX
, p
->value
[NL_OFFS
]);
put(2, O_FRTN
, even(lwidth(p
->type
)));
put2(O_CALL
| psbn
<< 8+INDX
, p
->entloc
);
rettype
= p2type( p
-> type
);
switch ( classify( p
-> type
) ) {
putop( P2UNARY P2CALL
, rettype
);
putop( P2CALL
, rettype
);
if (p
-> class == FFUNC
|| p
-> class == FPROC
) {
putop( P2LISTOP
, P2INT
);
putop( P2CALL
, rettype
);
putstrop( P2UNARY P2STCALL
, ADDTYPE( rettype
, P2PTR
)
, ADDTYPE( rettype
, P2PTR
)
if (p
-> class == FFUNC
|| p
-> class == FPROC
) {
putop( P2LISTOP
, P2INT
);
putop( P2CALL
, ADDTYPE( rettype
, P2PTR
) );
putstrop( P2STASG
, rettype
, lwidth( p
-> type
)
putLV( 0 , cbn
, temp
, rettype
);
putop( P2COMOP
, P2INT
);
putop( P2UNARY P2CALL
, P2INT
);
if (p
-> class == FFUNC
|| p
-> class == FPROC
) {
putop( P2LISTOP
, P2INT
);
putdot( filename
, line
);
for (; al
!= NIL
; al
= al
[2])
rvalue( (int *) al
[1], NLNIL
, RREQ
);