| 1 | /* Copyright (c) 1980 Regents of the University of California */ |
| 2 | |
| 3 | static char sccsid[] = "@(#)flvalue.c 1.1 %G%"; |
| 4 | |
| 5 | #include "whoami.h" |
| 6 | #include "0.h" |
| 7 | #include "tree.h" |
| 8 | #include "opcode.h" |
| 9 | #include "objfmt.h" |
| 10 | #ifdef PC |
| 11 | # include "pc.h" |
| 12 | # include "pcops.h" |
| 13 | #endif PC |
| 14 | |
| 15 | /* |
| 16 | * flvalue generates the code to either pass on a formal routine, |
| 17 | * or construct the structure which is the environment for passing. |
| 18 | * it tells the difference by looking at the tree it's given. |
| 19 | */ |
| 20 | struct nl * |
| 21 | flvalue( r ) |
| 22 | int *r; |
| 23 | { |
| 24 | struct nl *p; |
| 25 | long tempoff; |
| 26 | |
| 27 | if ( r == NIL ) { |
| 28 | return NIL; |
| 29 | } |
| 30 | p = lookup(r[2]); |
| 31 | if (p == NIL) { |
| 32 | return NIL; |
| 33 | } |
| 34 | switch ( r[0] ) { |
| 35 | case T_FFUNC: |
| 36 | if ( r[3] != NIL ) { |
| 37 | error("Formal function %s cannot be qualified" , |
| 38 | p -> symbol ); |
| 39 | return NIL; |
| 40 | } |
| 41 | goto froutine; |
| 42 | case T_FPROC: |
| 43 | if ( r[3] != NIL ) { |
| 44 | error("Formal procedure %s cannot be qualified" , |
| 45 | p -> symbol ); |
| 46 | return NIL; |
| 47 | } |
| 48 | froutine: |
| 49 | # ifdef OBJ |
| 50 | put( 2 , PTR_RV | bn << 8+INDX , p -> value[NL_OFFS] ); |
| 51 | # endif OBJ |
| 52 | # ifdef PC |
| 53 | putRV( p -> symbol , bn , p -> value[ NL_OFFS ] , |
| 54 | p2type( p ) ); |
| 55 | # endif PC |
| 56 | return p -> type; |
| 57 | case T_FUNC: |
| 58 | if ( r[3] != NIL ) { |
| 59 | error("Function %s cannot be qualified" , p -> symbol ); |
| 60 | return NIL; |
| 61 | } |
| 62 | goto routine; |
| 63 | case T_PROC: |
| 64 | if ( r[3] != NIL ) { |
| 65 | error("Procedure %s cannot be qualified", p -> symbol ); |
| 66 | return NIL; |
| 67 | } |
| 68 | routine: |
| 69 | /* |
| 70 | * formal routine structure: |
| 71 | * |
| 72 | * struct formalrtn { |
| 73 | * long (*entryaddr)(); |
| 74 | * long cbn; |
| 75 | * struct dispsave disp[2*MAXLVL]; |
| 76 | * }; |
| 77 | */ |
| 78 | sizes[ cbn ].om_off -= sizeof (long (*())) |
| 79 | + sizeof (long) |
| 80 | + 2*bn*sizeof (struct dispsave); |
| 81 | tempoff = sizes[ cbn ].om_off; |
| 82 | if ( sizes[ cbn ].om_off < sizes[ cbn ].om_max ) { |
| 83 | sizes[ cbn ].om_max = tempoff; |
| 84 | } |
| 85 | # ifdef OBJ |
| 86 | put( 2 , PTR_LV | cbn << 8 + INDX , tempoff ); |
| 87 | put( 2 , O_FSAV | bn << 8 + INDX , p -> entloc ); |
| 88 | # endif OBJ |
| 89 | # ifdef PC |
| 90 | putlbracket( ftnno , -tempoff ); |
| 91 | putleaf( P2ICON , 0 , 0 , |
| 92 | ADDTYPE( P2PTR , ADDTYPE( P2FTN , P2PTR|P2STR ) ) , |
| 93 | "_FSAV" ); |
| 94 | { |
| 95 | char extname[ BUFSIZ ]; |
| 96 | char *starthere; |
| 97 | int i; |
| 98 | |
| 99 | starthere = &extname[0]; |
| 100 | for ( i = 1 ; i < bn ; i++ ) { |
| 101 | sprintf( starthere , EXTFORMAT , enclosing[ i ] ); |
| 102 | starthere += strlen( enclosing[ i ] ) + 1; |
| 103 | } |
| 104 | sprintf( starthere , EXTFORMAT , p -> symbol ); |
| 105 | starthere += strlen( p -> symbol ) + 1; |
| 106 | if ( starthere >= &extname[ BUFSIZ ] ) { |
| 107 | panic( "flvalue namelength" ); |
| 108 | } |
| 109 | putleaf( P2ICON , 0 , 0 , p2type( p ) , extname ); |
| 110 | } |
| 111 | putleaf( P2ICON , bn , 0 , P2INT , 0 ); |
| 112 | putop( P2LISTOP , P2INT ); |
| 113 | putLV( 0 , cbn , tempoff , P2STR ); |
| 114 | putop( P2LISTOP , P2INT ); |
| 115 | putop( P2CALL , P2PTR | P2STRTY ); |
| 116 | # endif PC |
| 117 | return p -> type; |
| 118 | default: |
| 119 | panic("flvalue"); |
| 120 | } |
| 121 | } |