BSD 4 release
[unix-history] / usr / src / cmd / pi / var.c
index 266e160..0287e9f 100644 (file)
@@ -1,14 +1,15 @@
 /* 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[] = "@(#)var.c 1.3 9/2/80";
+
+#include "whoami.h"
 #include "0.h"
 #include "0.h"
+#include "align.h"
+#ifdef PC
+#   include    "pc.h"
+#   include    "pcops.h"
+#   include    "iorec.h"
+#endif PC
 
 /*
  * Declare variables of a var part.  DPOFF1 is
 
 /*
  * Declare variables of a var part.  DPOFF1 is
 varbeg()
 {
 
 varbeg()
 {
 
+/* this allows for multiple declaration
+ * parts except when the "standard"
+ * option has been specified.
+ * If routine segment is being compiled,
+ * do level one processing.
+ */
+
 #ifndef PI1
 #ifndef PI1
-       if (parts & VPRT)
-               error("All variables must be declared in one var part");
-       parts |= VPRT;
-#endif
-#ifndef PI0
-       sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
+       if (!progseen)
+               level1();
+       if ( parts[ cbn ] & RPRT ) {
+           if ( opt( 's' ) ) {
+               standard();
+           } else {
+               warning();
+           }
+           error("Variable declarations should precede routine declarations");
+       }
+       if ( parts[ cbn ] & VPRT ) {
+           if ( opt( 's' ) ) {
+               standard();
+           } else {
+               warning();
+           }
+           error("All variables should be declared in one var part");
+       }
+       parts[ cbn ] |= VPRT;
 #endif
 #endif
+    /*
+     *  #ifndef PI0
+     *      sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
+     *  #endif
+     */
        forechain = NIL;
 #ifdef PI0
        send(REVVBEG);
        forechain = NIL;
 #ifdef PI0
        send(REVVBEG);
@@ -43,8 +69,9 @@ var(vline, vidl, vtype)
 
        np = gtype(vtype);
        line = vline;
 
        np = gtype(vtype);
        line = vline;
-       for (vl = vidl; vl != NIL; vl = vl[2])
-               enter(defnl(vl[1], VAR, np, 0));
+       for (vl = vidl; vl != NIL; vl = vl[2]) {
+               }
+       }
        send(REVVAR, vline, vidl, vtype);
 }
 #else
        send(REVVAR, vline, vidl, vtype);
 }
 #else
@@ -60,12 +87,46 @@ var(vline, vidl, vtype)
 
        np = gtype(vtype);
        line = vline;
 
        np = gtype(vtype);
        line = vline;
+           /*
+            * widths are evened out
+            */
        w = (lwidth(np) + 1) &~ 1;
        op = &sizes[cbn];
        for (; vidl != NIL; vidl = vidl[2]) {
        w = (lwidth(np) + 1) &~ 1;
        op = &sizes[cbn];
        for (; vidl != NIL; vidl = vidl[2]) {
-               op->om_off -= w;
-               o2 = op->om_off;
+#              ifdef OBJ
+                   op -> om_off = roundup( op -> om_off - w , align( np ) );
+                   o2 = op -> om_off;
+#              endif OBJ
+#              ifdef PC
+                   if ( cbn == 1 ) {
+                               /*
+                                * global variables are not accessed off the fp
+                                * but rather by their names.
+                                */
+                           o2 = 0;
+                   } else {
+                               /*
+                                * locals are aligned, too.
+                                */
+                           op -> om_off = roundup( op -> om_off - w
+                                                       , align( np ) );
+                           o2 = op -> om_off;
+                   }
+#              endif PC
                enter(defnl(vidl[1], VAR, np, o2));
                enter(defnl(vidl[1], VAR, np, o2));
+               if ( np -> nl_flags & NFILES ) {
+                   dfiles[ cbn ] = TRUE;
+               }
+#              ifdef PC
+                   if ( cbn == 1 ) {
+                       putprintf( "    .data" , 0 );
+                       putprintf( "    .comm   " , 1 );
+                       putprintf( EXTFORMAT , 1 , vidl[1] );
+                       putprintf( ",%d" , 0 , w );
+                       putprintf( "    .text" , 0 );
+                   }
+                   stabvar( vidl[1] , p2type( np ) , cbn , o2 , w , line );
+#              endif PC
        }
 #      ifdef PTREE
            {
        }
 #      ifdef PTREE
            {
@@ -113,7 +174,8 @@ width(np)
        return (lwidth(np));
 }
 
        return (lwidth(np));
 }
 
-long lwidth(np)
+long
+lwidth(np)
        struct nl *np;
 {
        register struct nl *p;
        struct nl *np;
 {
        register struct nl *p;
@@ -138,8 +200,15 @@ loop:
                case ARRAY:
                        return (aryconst(p, 0));
                case PTR:
                case ARRAY:
                        return (aryconst(p, 0));
                case PTR:
-               case FILET:
                        return ( sizeof ( int * ) );
                        return ( sizeof ( int * ) );
+               case FILET:
+#                      ifdef OBJ
+                           return ( sizeof ( int * ) );
+#                      endif OBJ
+#                      ifdef PC
+                           return ( sizeof(struct iorec)
+                                   + lwidth( p -> type ) );
+#                      endif PC
                case RANGE:
                        if (p->type == nl+TDOUBLE)
 #ifdef DEBUG
                case RANGE:
                        if (p->type == nl+TDOUBLE)
 #ifdef DEBUG
@@ -151,7 +220,7 @@ loop:
                        return (bytes(p->range[0], p->range[1]));
                case SET:
                        setran(p->type);
                        return (bytes(p->range[0], p->range[1]));
                case SET:
                        setran(p->type);
-                       return ( (set.uprbp>>3) + 1);
+                       return roundup( ( set.uprbp >> 3 ) + 1 , A_SET );
                case STR:
                case RECORD:
                        return ( p->value[NL_OFFS] );
                case STR:
                case RECORD:
                        return ( p->value[NL_OFFS] );
@@ -160,6 +229,112 @@ loop:
        }
 }
 
        }
 }
 
+    /*
+     * round up x to a multiple of y
+     * for computing offsets of aligned things.
+     * y had better be positive.
+     * rounding is in the direction of x.
+     */
+long
+roundup( x , y )
+    long               x;
+    register long      y;
+    {
+       
+       if ( y == 0 ) {
+           return 0;
+       }
+       if ( x >= 0 ) {
+               return ( ( ( x + ( y - 1 ) ) / y ) * y );
+       } else {
+               return ( ( ( x - ( y - 1 ) ) / y ) * y );
+       }
+    }
+
+    /*
+     * alignment of an object using the c alignment scheme
+     */
+int
+align( np )
+    struct nl  *np;
+    {
+       register struct nl *p;
+
+       p = np;
+       if ( p == NIL ) {
+           return 0;
+       }
+alignit:
+       switch ( p -> class ) {
+           case TYPE:
+                   switch ( nloff( p ) ) {
+                       case TNIL:
+                               return A_POINT;
+                       case TSTR:
+                               return A_CHAR;
+                       case TSET:
+                               return A_SET;
+                       default:
+                               p = p -> type;
+                               goto alignit;
+                   }
+           case ARRAY:
+                       /*
+                        * arrays are aligned as their component types
+                        */
+                   p = p -> type;
+                   goto alignit;
+           case PTR:
+                   return A_POINT;
+           case FILET:
+                   return A_FILET;
+           case RANGE:
+                   if ( p -> type == nl+TDOUBLE ) {
+                       return A_DOUBLE;
+                   }
+                   /* else, fall through */
+           case SCAL:
+                   switch ( bytes( p -> range[0] , p -> range[1] ) ) {
+                       case 4:
+                           return A_LONG;
+                       case 2:
+                           return A_SHORT;
+                       case 1:
+                           return A_CHAR;
+                       default:
+                           panic( "align: scal" );
+                   }
+           case SET:
+                   return A_SET;
+           case STR:
+                   return A_CHAR;
+           case RECORD:
+                       /*
+                        * follow chain through all fields in record,
+                        * taking max of alignments of types of fields.
+                        * short circuit out if i reach the maximum alignment.
+                        * this is pretty likely, as A_MAX is only 4.
+                        */
+                   {
+                       register long recalign;
+                       register long fieldalign;
+                       
+                       recalign = A_MIN;
+                       p = p -> chain;
+                       while ( ( p != NIL ) && ( recalign < A_MAX ) ) {
+                           fieldalign = align( p -> type );
+                           if ( fieldalign > recalign ) {
+                               recalign = fieldalign;
+                           }
+                           p = p -> chain;
+                       }
+                       return recalign;
+                   }
+           default:
+                   panic( "align" );
+       }
+    }
+
 /*
  * Return the width of an element
  * of a n time subscripted np.
 /*
  * Return the width of an element
  * of a n time subscripted np.
@@ -175,7 +350,7 @@ long aryconst(np, n)
                return (NIL);
        if (p->class != ARRAY)
                panic("ary");
                return (NIL);
        if (p->class != ARRAY)
                panic("ary");
-       s = width(p->type);
+       s = lwidth(p->type);
        /*
         * Arrays of anything but characters are word aligned.
         */
        /*
         * Arrays of anything but characters are word aligned.
         */