BSD 4 release
[unix-history] / usr / src / cmd / pi / lab.c
index 6427abc..3fe3bae 100644 (file)
@@ -1,16 +1,16 @@
 /* Copyright (c) 1979 Regents of the University of California */
 /* Copyright (c) 1979 Regents of the University of California */
-#
-/*
- * pi - Pascal interpreter code translator
- *
- * Charles Haley, Bill Joy UCB
- * Version 1.2 November 1978
- */
 
 
-#include "whoami"
+static char sccsid[] = "@(#)lab.c 1.5 10/14/80";
+
+#include "whoami.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
+#include "objfmt.h"
+#ifdef PC
+#   include    "pc.h"
+#   include    "pcops.h"
+#endif PC
 
 /*
  * Label enters the definitions
 
 /*
  * Label enters the definitions
@@ -28,13 +28,28 @@ label(r, l)
 #else
        send(REVLAB, r);
 #endif
 #else
        send(REVLAB, r);
 #endif
+       if ( ! progseen ) {
+           level1();
+       }
        line = l;
 #ifndef PI1
        line = l;
 #ifndef PI1
-       if (parts & (CPRT|TPRT|VPRT))
-               error("Label declarations must precede const, type and var declarations");
-       if (parts & LPRT)
-               error("All labels must be declared in one label part");
-       parts |= LPRT;
+       if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){
+           if ( opt( 's' ) ) {
+               standard();
+           } else {
+               warning();
+           }
+           error("Label declarations should precede const, type, var and routine declarations");
+       }
+       if (parts[ cbn ] & LPRT) {
+           if ( opt( 's' ) ) {
+               standard();
+           } else {
+               warning();
+           }
+           error("All labels should be declared in one label part");
+       }
+       parts[ cbn ] |= LPRT;
 #endif
 #ifndef PI0
        for (ll = r; ll != NIL; ll = ll[2]) {
 #endif
 #ifndef PI0
        for (ll = r; ll != NIL; ll = ll[2]) {
@@ -49,14 +64,44 @@ label(r, l)
                p->value[NL_GOLEV] = NOTYET;
                p->entloc = l;
                lp = p;
                p->value[NL_GOLEV] = NOTYET;
                p->entloc = l;
                lp = p;
-               /*
-                * This operator is between
-                * the bodies of two procedures
-                * and provides a target for
-                * gotos for this label via TRA.
-                */
-               putlab(l);
-               put2(O_GOTO | cbn<<9, p->value[1]);
+#              ifdef OBJ
+                   /*
+                    * This operator is between
+                    * the bodies of two procedures
+                    * and provides a target for
+                    * gotos for this label via TRA.
+                    */
+                   putlab(l);
+                   put2(O_GOTO | cbn<<8+INDX, p->value[1]);
+#              endif OBJ
+#              ifdef PC
+                   /*
+                    *  labels have to be .globl otherwise /lib/c2 may
+                    *  throw them away if they aren't used in the function
+                    *  which defines them.
+                    */
+                   {
+                       char    extname[ BUFSIZ ];
+                       char    *starthere;
+                       int     i;
+
+                       starthere = &extname[0];
+                       for ( i = 1 ; i < cbn ; 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( "lab decl namelength" );
+                       }
+                       putprintf( "    .globl  " , 1 );
+                       putprintf( NAMEFORMAT , 0 , extname );
+                       if ( cbn == 1 ) {
+                           stabglabel( extname , line );
+                       }
+                   }
+#              endif PC
        }
        gotos[cbn] = lp;
 #      ifdef PTREE
        }
        gotos[cbn] = lp;
 #      ifdef PTREE
@@ -65,7 +110,7 @@ label(r, l)
 
                pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
            }
 
                pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
            }
-#      endif
+#      endif PTREE
 #endif
 }
 
 #endif
 }
 
@@ -84,7 +129,40 @@ gotoop(s)
        p = lookup(s);
        if (p == NIL)
                return (NIL);
        p = lookup(s);
        if (p == NIL)
                return (NIL);
-       put2(O_TRA4, p->entloc);
+#      ifdef OBJ
+           put2(O_TRA4, p->entloc);
+#      endif OBJ
+#      ifdef PC
+           if ( cbn != bn ) {
+                   /*
+                    *  call goto to unwind the stack to the destination level
+                    */
+               putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
+                       , "_GOTO" );
+               putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave )
+                       , P2PTR | P2INT );
+               putop( P2CALL , P2INT );
+               putdot( filename , line );
+           }
+           {
+               char    extname[ BUFSIZ ];
+               char    *starthere;
+               int     i;
+
+               starthere = &extname[0];
+               for ( i = 1 ; i < bn ; 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( "goto namelength" );
+               }
+               putprintf( "    jbr     " , 1 );
+               putprintf( NAMEFORMAT , 0 , extname );
+           }
+#      endif PC
        if (bn == cbn)
                if (p->nl_flags & NFORWD) {
                        if (p->value[NL_GOLEV] == NOTYET) {
        if (bn == cbn)
                if (p->nl_flags & NFORWD) {
                        if (p->value[NL_GOLEV] == NOTYET) {
@@ -122,7 +200,29 @@ labeled(s)
                return;
        }
        p->nl_flags &= ~NFORWD;
                return;
        }
        p->nl_flags &= ~NFORWD;
-       patch4(p->entloc);
+#      ifdef OBJ
+           patch4(p->entloc);
+#      endif OBJ
+#      ifdef PC
+           {
+               char    extname[ BUFSIZ ];
+               char    *starthere;
+               int     i;
+
+               starthere = &extname[0];
+               for ( i = 1 ; i < bn ; 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( "labeled namelength" );
+               }
+               putprintf( NAMEFORMAT , 1 , extname );
+               putprintf( ":" , 0 );
+           }
+#      endif PC
        if (p->value[NL_GOLEV] != NOTYET)
                if (p->value[NL_GOLEV] < level) {
                        recovered();
        if (p->value[NL_GOLEV] != NOTYET)
                if (p->value[NL_GOLEV] < level) {
                        recovered();