home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / var.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  10.3 KB  |  501 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[] = "@(#)var.c    5.5 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include "0.h"
  40. #include "objfmt.h"
  41. #include "align.h"
  42. #include "iorec.h"
  43. #ifdef PC
  44. #   include    "pc.h"
  45. #endif PC
  46. #include "tmps.h"
  47. #include "tree_ty.h"
  48.  
  49. /*
  50.  * Declare variables of a var part.  DPOFF1 is
  51.  * the local variable storage for all prog/proc/func
  52.  * modules aside from the block mark.  The total size
  53.  * of all the local variables is entered into the
  54.  * size array.
  55.  */
  56. /*ARGSUSED*/
  57. varbeg( lineofyvar , r )
  58.     int    lineofyvar;
  59. {
  60.     static bool    var_order = FALSE;
  61.     static bool    var_seen = FALSE;
  62.  
  63. /* this allows for multiple declaration
  64.  * parts except when the "standard"
  65.  * option has been specified.
  66.  * If routine segment is being compiled,
  67.  * do level one processing.
  68.  */
  69.  
  70. #ifndef PI1
  71.     if (!progseen)
  72.         level1();
  73.     line = lineofyvar;
  74.     if ( parts[ cbn ] & RPRT ) {
  75.         if ( opt( 's' ) ) {
  76.         standard();
  77.         error("Variable declarations should precede routine declarations");
  78.         } else {
  79.         if ( !var_order ) {
  80.             var_order = TRUE;
  81.             warning();
  82.             error("Variable declarations should precede routine declarations");
  83.         }
  84.         }
  85.     }
  86.     if ( parts[ cbn ] & VPRT ) {
  87.         if ( opt( 's' ) ) {
  88.         standard();
  89.         error("All variables should be declared in one var part");
  90.         } else {
  91.         if ( !var_seen ) {
  92.             var_seen = TRUE;
  93.             warning();
  94.             error("All variables should be declared in one var part");
  95.         }
  96.         }
  97.     }
  98.     parts[ cbn ] |= VPRT;
  99. #endif
  100.     /*
  101.      *  #ifndef PI0
  102.      *      sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
  103.      *  #endif
  104.      */
  105.     forechain = NIL;
  106. #ifdef PI0
  107.     send(REVVBEG);
  108. #endif
  109. }
  110.  
  111. var(vline, vidl, vtype)
  112. #ifdef PI0
  113.     int vline;
  114.     struct tnode *vidl, *vtype;
  115. {
  116.     register struct nl *np;
  117.     register struct tnode *vl;
  118.  
  119.     np = gtype(vtype);
  120.     line = vline;
  121.     /* why is this here? */
  122.     for (vl = vidl; vl != TR_NIL; vl = vl->list_node.next) {
  123.         }
  124.     }
  125.     send(REVVAR, vline, vidl, vtype);
  126. }
  127. #else
  128.     int vline;
  129.     register struct tnode *vidl;
  130.     struct tnode *vtype;
  131. {
  132.     register struct nl *np;
  133.     register struct om *op;
  134.     long w;
  135.     int o2;
  136. #ifdef PC
  137.     struct nl    *vp;
  138. #endif
  139.  
  140.     np = gtype(vtype);
  141.     line = vline;
  142.     w = lwidth(np);
  143.     op = &sizes[cbn];
  144.     for (; vidl != TR_NIL; vidl = vidl->list_node.next) {
  145. #        ifdef OBJ
  146.             op->curtmps.om_off =
  147.             roundup((int)(op->curtmps.om_off-w), (long)align(np));
  148.             o2 = op -> curtmps.om_off;
  149. #        endif OBJ
  150. #        ifdef PC
  151.             if ( cbn == 1 ) {
  152.                 /*
  153.                  * global variables are not accessed off the fp
  154.                  * but rather by their names.
  155.                  */
  156.                 o2 = 0;
  157.             } else {
  158.                 /*
  159.                  * locals are aligned, too.
  160.                  */
  161.                 op->curtmps.om_off =
  162.                 roundup((int)(op->curtmps.om_off - w),
  163.                 (long)align(np));
  164.                 o2 = op -> curtmps.om_off;
  165.             }
  166. #        endif PC
  167. #        ifdef PC
  168.         vp = enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
  169. #        else
  170.         (void) enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
  171. #        endif
  172.         if ( np != NLNIL && (np -> nl_flags & NFILES) ) {
  173.             dfiles[ cbn ] = TRUE;
  174.         }
  175. #        ifdef PC
  176.             if ( cbn == 1 ) {
  177.             putprintf( "    .data" , 0 );
  178.             aligndot(align(np));
  179.             putprintf( "    .comm    " , 1 );
  180.             putprintf( EXTFORMAT , 1 , (int) vidl->list_node.list );
  181.             putprintf( ",%d" , 0 , (int) w );
  182.             putprintf( "    .text" , 0 );
  183.             stabgvar( vp , w , line );
  184.             vp -> extra_flags |= NGLOBAL;
  185.             } else {
  186.             vp -> extra_flags |= NLOCAL;
  187.             }
  188. #        endif PC
  189.     }
  190. #    ifdef PTREE
  191.         {
  192.         pPointer    *Vars;
  193.         pPointer    Var = VarDecl( ovidl , vtype );
  194.  
  195.         pSeize( PorFHeader[ nesting ] );
  196.         Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars );
  197.         *Vars = ListAppend( *Vars , Var );
  198.         pRelease( PorFHeader[ nesting ] );
  199.         }
  200. #    endif
  201. }
  202. #endif
  203.  
  204. varend()
  205. {
  206.  
  207.     foredecl();
  208. #ifndef PI0
  209.     sizes[cbn].om_max = sizes[cbn].curtmps.om_off;
  210. #else
  211.     send(REVVEND);
  212. #endif
  213. }
  214.  
  215. /*
  216.  * Find the width of a type in bytes.
  217.  */
  218. width(np)
  219.     struct nl *np;
  220. {
  221.  
  222.     return (lwidth(np));
  223. }
  224.  
  225. long
  226. lwidth(np)
  227.     struct nl *np;
  228. {
  229.     register struct nl *p;
  230.  
  231.     p = np;
  232.     if (p == NIL)
  233.         return (0);
  234. loop:
  235.     switch (p->class) {
  236.         default:
  237.             panic("wclass");
  238.         case TYPE:
  239.             switch (nloff(p)) {
  240.                 case TNIL:
  241.                     return (2);
  242.                 case TSTR:
  243.                 case TSET:
  244.                     panic("width");
  245.                 default:
  246.                     p = p->type;
  247.                     goto loop;
  248.             }
  249.         case ARRAY:
  250.             return (aryconst(p, 0));
  251.         case PTR:
  252.             return ( sizeof ( int * ) );
  253.         case FILET:
  254.             return ( sizeof(struct iorec) + lwidth( p -> type ) );
  255.         case CRANGE:
  256.             p = p->type;
  257.             goto loop;
  258.         case RANGE:
  259.             if (p->type == nl+TDOUBLE)
  260. #ifdef DEBUG
  261.                 return (hp21mx ? 4 : 8);
  262. #else
  263.                 return (8);
  264. #endif
  265.         case SCAL:
  266.             return (bytes(p->range[0], p->range[1]));
  267.         case SET:
  268.             setran(p->type);
  269.             /*
  270.              * Sets are some multiple of longs
  271.              */
  272.             return roundup((int)((set.uprbp >> 3) + 1),
  273.                 (long)(sizeof(long)));
  274.         case STR:
  275.         case RECORD:
  276.             return ( p->value[NL_OFFS] );
  277.     }
  278. }
  279.  
  280.     /*
  281.      *    round up x to a multiple of y
  282.      *    for computing offsets of aligned things.
  283.      *    y had better be positive.
  284.      *    rounding is in the direction of x.
  285.      */
  286. long
  287. roundup( x , y )
  288.     int            x;
  289.     register long    y;
  290.     {
  291.     
  292.     if ( y == 0 ) {
  293.         return x;
  294.     }
  295.     if ( x >= 0 ) {
  296.         return ( ( ( x + ( y - 1 ) ) / y ) * y );
  297.     } else {
  298.         return ( ( ( x - ( y - 1 ) ) / y ) * y );
  299.     }
  300.     }
  301.  
  302.     /*
  303.      *    alignment of an object using the c alignment scheme
  304.      */
  305. int
  306. align( np )
  307.     struct nl    *np;
  308.     {
  309.     register struct nl *p;
  310.     long elementalign;
  311.  
  312.     p = np;
  313.     if ( p == NIL ) {
  314.         return 0;
  315.     }
  316. alignit:
  317.     switch ( p -> class ) {
  318.         default:
  319.             panic( "align" );
  320.         case TYPE:
  321.             switch ( nloff( p ) ) {
  322.             case TNIL:
  323.                 return A_POINT;
  324.             case TSTR:
  325.                 return A_STRUCT;
  326.             case TSET:
  327.                 return A_SET;
  328.             default:
  329.                 p = p -> type;
  330.                 goto alignit;
  331.             }
  332.         case ARRAY:
  333.             /*
  334.              * arrays are structures, since they can get
  335.              * assigned form/to as structure assignments.
  336.              * preserve internal alignment if it is greater.
  337.              */
  338.             elementalign = align(p -> type);
  339.             return elementalign > A_STRUCT ? elementalign : A_STRUCT;
  340.         case PTR:
  341.             return A_POINT;
  342.         case FILET:
  343.             return A_FILET;
  344.         case CRANGE:
  345.         case RANGE:
  346.             if ( p -> type == nl+TDOUBLE ) {
  347.             return A_DOUBLE;
  348.             }
  349.             /* else, fall through */
  350.         case SCAL:
  351.             switch ( bytes( p -> range[0] , p -> range[1] ) ) {
  352.             case 4:
  353.                 return A_LONG;
  354.             case 2:
  355.                 return A_SHORT;
  356.             case 1:
  357.                 return A_CHAR;
  358.             default:
  359.                 panic( "align: scal" );
  360.             }
  361.         case SET:
  362.             return A_SET;
  363.         case STR:
  364.             /*
  365.              * arrays of chars are structs
  366.              */
  367.             return A_STRUCT;
  368.         case RECORD:
  369.             /*
  370.              * the alignment of a record is in its align_info field
  371.              * why don't we use this for the rest of the namelist?
  372.              */
  373.             return p -> align_info;
  374.     }
  375.     }
  376.  
  377. #ifdef PC
  378.     /*
  379.      *    output an alignment pseudo-op.
  380.      */
  381. aligndot(alignment)
  382.     int    alignment;
  383. #if defined(vax) || defined(tahoe)
  384. {
  385.     switch (alignment) {
  386.     case 1:
  387.         return;
  388.     case 2:
  389.         putprintf("    .align 1", 0);
  390.         return;
  391.     default:
  392.     case 4:
  393.         putprintf("    .align 2", 0);
  394.         return;
  395.     }
  396. }
  397. #endif vax || tahoe
  398. #ifdef mc68000
  399. {
  400.     switch (alignment) {
  401.     case 1:
  402.         return;
  403.     default:
  404.         putprintf("    .even", 0);
  405.         return;
  406.     }
  407. }
  408. #endif mc68000
  409. #endif PC
  410.     
  411. /*
  412.  * Return the width of an element
  413.  * of a n time subscripted np.
  414.  */
  415. long aryconst(np, n)
  416.     struct nl *np;
  417.     int n;
  418. {
  419.     register struct nl *p;
  420.     long s, d;
  421.  
  422.     if ((p = np) == NIL)
  423.         return (NIL);
  424.     if (p->class != ARRAY)
  425.         panic("ary");
  426.     /*
  427.      * If it is a conformant array, we cannot find the width from
  428.      * the type.
  429.      */
  430.     if (p->chain->class == CRANGE)
  431.         return (NIL);
  432.     s = lwidth(p->type);
  433.     /*
  434.      * Arrays of anything but characters are word aligned.
  435.      */
  436.     if (s & 1)
  437.         if (s != 1)
  438.             s++;
  439.     /*
  440.      * Skip the first n subscripts
  441.      */
  442.     while (n >= 0) {
  443.         p = p->chain;
  444.         n--;
  445.     }
  446.     /*
  447.      * Sum across remaining subscripts.
  448.      */
  449.     while (p != NIL) {
  450.         if (p->class != RANGE && p->class != SCAL)
  451.             panic("aryran");
  452.         d = p->range[1] - p->range[0] + 1;
  453.         s *= d;
  454.         p = p->chain;
  455.     }
  456.     return (s);
  457. }
  458.  
  459. /*
  460.  * Find the lower bound of a set, and also its size in bits.
  461.  */
  462. setran(q)
  463.     struct nl *q;
  464. {
  465.     register lb, ub;
  466.     register struct nl *p;
  467.  
  468.     p = q;
  469.     if (p == NIL)
  470.         return;
  471.     lb = p->range[0];
  472.     ub = p->range[1];
  473.     if (p->class != RANGE && p->class != SCAL)
  474.         panic("setran");
  475.     set.lwrb = lb;
  476.     /* set.(upperbound prime) = number of bits - 1; */
  477.     set.uprbp = ub-lb;
  478. }
  479.  
  480. /*
  481.  * Return the number of bytes required to hold an arithmetic quantity
  482.  */
  483. bytes(lb, ub)
  484.     long lb, ub;
  485. {
  486.  
  487. #ifndef DEBUG
  488.     if (lb < -32768 || ub > 32767)
  489.         return (4);
  490.     else if (lb < -128 || ub > 127)
  491.         return (2);
  492. #else
  493.     if (!hp21mx && (lb < -32768 || ub > 32767))
  494.         return (4);
  495.     if (lb < -128 || ub > 127)
  496.         return (2);
  497. #endif
  498.     else
  499.         return (1);
  500. }
  501.