home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / lab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  8.9 KB  |  323 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)lab.c    5.3 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include "0.h"
  40. #include "tree.h"
  41. #include "opcode.h"
  42. #include "objfmt.h"
  43. #ifdef PC
  44. #   include    "pc.h"
  45. #   include    <pcc.h>
  46. #endif PC
  47. #include "tree_ty.h"
  48.  
  49. /*
  50.  * Label enters the definitions
  51.  * of the label declaration part
  52.  * into the namelist.
  53.  */
  54. label(r, l)
  55.     struct tnode *r;
  56.     int l;
  57. {
  58.     static bool    label_order = FALSE;
  59.     static bool    label_seen = FALSE;
  60. #ifdef PC
  61.     char    extname[ BUFSIZ ];
  62. #endif PC
  63. #ifndef PI0
  64.     register struct tnode *ll;
  65.     register struct nl *p, *lp;
  66.  
  67.     lp = NIL;
  68. #else
  69.     send(REVLAB, r);
  70. #endif
  71.     if ( ! progseen ) {
  72.         level1();
  73.     }
  74.     line = l;
  75. #ifndef PI1
  76.     if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){
  77.         if ( opt( 's' ) ) {
  78.         standard();
  79.         error("Label declarations should precede const, type, var and routine declarations");
  80.         } else {
  81.         if ( !label_order ) {
  82.             label_order = TRUE;
  83.             warning();
  84.             error("Label declarations should precede const, type, var and routine declarations");
  85.         }
  86.         }
  87.     }
  88.     if (parts[ cbn ] & LPRT) {
  89.         if ( opt( 's' ) ) {
  90.         standard();
  91.         error("All labels should be declared in one label part");
  92.         } else {
  93.         if ( !label_seen ) {
  94.             label_seen = TRUE;
  95.             warning();
  96.             error("All labels should be declared in one label part");
  97.         }
  98.         }
  99.     }
  100.     parts[ cbn ] |= LPRT;
  101. #endif
  102. #ifndef PI0
  103.     for (ll = r; ll != TR_NIL; ll = ll->list_node.next) {
  104.         l = (int) getlab();
  105.         p = enter(defnl((char *) ll->list_node.list, LABEL, NLNIL,
  106.                 (int) l));
  107.         /*
  108.          * Get the label for the eventual target
  109.          */
  110.         p->value[1] = (int) getlab();
  111.         p->chain = lp;
  112.         p->nl_flags |= (NFORWD|NMOD);
  113.         p->value[NL_GOLEV] = NOTYET;
  114.         p->value[NL_ENTLOC] = l;
  115.         lp = p;
  116. #        ifdef OBJ
  117.             /*
  118.              * This operator is between
  119.              * the bodies of two procedures
  120.              * and provides a target for
  121.              * gotos for this label via TRA.
  122.              */
  123.             (void) putlab((char *) l);
  124.             (void) put(2, O_GOTO | cbn<<8, (long)p->value[1]);
  125. #        endif OBJ
  126. #        ifdef PC
  127.             /*
  128.              *    labels have to be .globl otherwise /lib/c2 may
  129.              *    throw them away if they aren't used in the function
  130.              *    which defines them.
  131.              */
  132.             extlabname( extname , p -> symbol , cbn );
  133.             putprintf("    .globl    %s", 0, (int) extname);
  134.             if ( cbn == 1 ) {
  135.             stabglabel( extname , line );
  136.             }
  137. #        endif PC
  138.     }
  139.     gotos[cbn] = lp;
  140. #    ifdef PTREE
  141.         {
  142.         pPointer    Labels = LabelDCopy( r );
  143.  
  144.         pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
  145.         }
  146. #    endif PTREE
  147. #endif
  148. }
  149.  
  150. #ifndef PI0
  151. /*
  152.  * Gotoop is called when
  153.  * we get a statement "goto label"
  154.  * and generates the needed tra.
  155.  */
  156. gotoop(s)
  157.     char *s;
  158. {
  159.     register struct nl *p;
  160. #ifdef PC
  161.     char    extname[ BUFSIZ ];
  162. #endif PC
  163.  
  164.     gocnt++;
  165.     p = lookup(s);
  166.     if (p == NIL)
  167.         return;
  168. #    ifdef OBJ
  169.         (void) put(2, O_TRA4, (long)p->value[NL_ENTLOC]);
  170. #    endif OBJ
  171. #    ifdef PC
  172.         if ( cbn == bn ) {
  173.             /*
  174.              *    local goto.
  175.              */
  176.         extlabname( extname , p -> symbol , bn );
  177.             /*
  178.              * this is a funny jump because it's to a label that
  179.              * has been declared global.
  180.              * Although this branch is within this module
  181.              * the assembler will complain that the destination
  182.              * is a global symbol.
  183.              * The complaint arises because the assembler
  184.              * doesn't change relative jumps into absolute jumps.
  185.              * and this  may cause a branch displacement overflow
  186.              * when the module is subsequently linked with
  187.              * the rest of the program.
  188.              */
  189. #        if defined(vax) || defined(tahoe)
  190.             putprintf("    jmp    %s", 0, (int) extname);
  191. #        endif vax || tahoe
  192. #        ifdef mc68000
  193.             putprintf("    jra    %s", 0, (int) extname);
  194. #        endif mc68000
  195.         } else {
  196.             /*
  197.              *    Non-local goto.
  198.              *
  199.              *  Close all active files between top of stack and
  200.              *  frame at the destination level.    Then call longjmp
  201.              *    to unwind the stack to the destination level.
  202.              *
  203.              *    For nested routines the end of the frame
  204.              *    is calculated as:
  205.              *        __disply[bn].fp + sizeof(local frame)
  206.              *    (adjusted by (sizeof int) to get just past the end).
  207.              *    The size of the local frame is dumped out by
  208.              *    the second pass as an assembler constant.
  209.              *    The main routine may not be compiled in this
  210.              *    module, so its size may not be available.
  211.              *     However all of its variables will be globally
  212.              *    declared, so only the known runtime temporaries
  213.              *    will be in its stack frame.
  214.              */
  215.         parts[ bn ] |= NONLOCALGOTO;
  216.         putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
  217.             , "_PCLOSE" );
  218.         if ( bn > 1 ) {
  219.             p = lookup( enclosing[ bn - 1 ] );
  220.             sprintf( extname, "%s%d+%d",
  221.             FRAME_SIZE_LABEL, p -> value[NL_ENTLOC], sizeof(int));
  222.             p = lookup(s);
  223.             putLV( extname , bn , 0 , NNLOCAL , PCCTM_PTR | PCCT_CHAR );
  224.         } else {
  225.             putLV((char *) 0 , bn , -( DPOFF1 + sizeof( int ) ) , LOCALVAR ,
  226.             PCCTM_PTR | PCCT_CHAR );
  227.         }
  228.         putop( PCC_CALL , PCCT_INT );
  229.         putdot( filename , line );
  230.         putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
  231.             , "_longjmp" );
  232.         putLV((char *) 0 , bn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
  233.         extlabname( extname , p -> symbol , bn );
  234.         putLV( extname , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY );
  235.         putop( PCC_CM , PCCT_INT );
  236.         putop( PCC_CALL , PCCT_INT );
  237.         putdot( filename , line );
  238.         }
  239. #    endif PC
  240.     if (bn == cbn)
  241.         if (p->nl_flags & NFORWD) {
  242.             if (p->value[NL_GOLEV] == NOTYET) {
  243.                 p->value[NL_GOLEV] = level;
  244.                 p->value[NL_GOLINE] = line;
  245.             }
  246.         } else
  247.             if (p->value[NL_GOLEV] == DEAD) {
  248.                 recovered();
  249.                 error("Goto %s is into a structured statement", p->symbol);
  250.             }
  251. }
  252.  
  253. /*
  254.  * Labeled is called when a label
  255.  * definition is encountered, and
  256.  * marks that it has been found and
  257.  * patches the associated GOTO generated
  258.  * by gotoop.
  259.  */
  260. labeled(s)
  261.     char *s;
  262. {
  263.     register struct nl *p;
  264. #ifdef PC
  265.     char    extname[ BUFSIZ ];
  266. #endif PC
  267.  
  268.     p = lookup(s);
  269.     if (p == NIL)
  270.         return;
  271.     if (bn != cbn) {
  272.         error("Label %s not defined in correct block", s);
  273.         return;
  274.     }
  275.     if ((p->nl_flags & NFORWD) == 0) {
  276.         error("Label %s redefined", s);
  277.         return;
  278.     }
  279.     p->nl_flags &= ~NFORWD;
  280. #    ifdef OBJ
  281.         patch4((PTR_DCL) p->value[NL_ENTLOC]);
  282. #    endif OBJ
  283. #    ifdef PC
  284.         extlabname( extname , p -> symbol , bn );
  285.         putprintf( "%s:" , 0 , (int) extname );
  286. #    endif PC
  287.     if (p->value[NL_GOLEV] != NOTYET)
  288.         if (p->value[NL_GOLEV] < level) {
  289.             recovered();
  290.             error("Goto %s from line %d is into a structured statement", s, (char *) p->value[NL_GOLINE]);
  291.         }
  292.     p->value[NL_GOLEV] = level;
  293. }
  294. #endif
  295.  
  296. #ifdef PC
  297.     /*
  298.      *    construct the long name of a label based on it's static nesting.
  299.      *    into a caller-supplied buffer (that should be about BUFSIZ big).
  300.      */
  301. extlabname( buffer , name , level )
  302.     char    buffer[];
  303.     char    *name;
  304.     int        level;
  305. {
  306.     char    *starthere;
  307.     int        i;
  308.  
  309.     starthere = &buffer[0];
  310.     for ( i = 1 ; i < level ; i++ ) {
  311.     sprintf( starthere , EXTFORMAT , enclosing[ i ] );
  312.     starthere += strlen( enclosing[ i ] ) + 1;
  313.     }
  314.     sprintf( starthere , EXTFORMAT , "" );
  315.     starthere += 1;
  316.     sprintf( starthere , LABELFORMAT , name );
  317.     starthere += strlen( name ) + 1;
  318.     if ( starthere >= &buffer[ BUFSIZ ] ) {
  319.     panic( "extlabname" );
  320.     }
  321. }
  322. #endif PC
  323.