BSD 4 release
[unix-history] / usr / src / cmd / pi / lval.c
index 4f4f490..827bf7d 100644 (file)
@@ -1,26 +1,29 @@
 /* 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[] = "@(#)lval.c 1.1 8/27/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
 
 extern int flagwas;
 /*
  * Lvalue computes the address
  * of a qualified name and
  * leaves it on the stack.
 
 extern int flagwas;
 /*
  * Lvalue computes the address
  * of a qualified name and
  * leaves it on the stack.
+ * for pc, it can be asked for either an lvalue or an rvalue.
+ * the semantics are the same, only the code is different.
  */
 struct nl *
  */
 struct nl *
-lvalue(r, modflag)
+lvalue(r, modflag , required )
        int *r, modflag;
        int *r, modflag;
+       int     required;
 {
        register struct nl *p;
        struct nl *firstp, *lastp;
 {
        register struct nl *p;
        struct nl *firstp, *lastp;
@@ -33,22 +36,33 @@ lvalue(r, modflag)
         */
        int tr[2], trp[3];
 
         */
        int tr[2], trp[3];
 
-       if (r == NIL)
+       if (r == NIL) {
                return (NIL);
                return (NIL);
-       if (nowexp(r))
+       }
+       if (nowexp(r)) {
                return (NIL);
                return (NIL);
+       }
        if (r[0] != T_VAR) {
                error("Variable required");     /* Pass mesgs down from pt of call ? */
                return (NIL);
        }
        if (r[0] != T_VAR) {
                error("Variable required");     /* Pass mesgs down from pt of call ? */
                return (NIL);
        }
+#      ifdef PC
+               /*
+                *      pc requires a whole different control flow
+                */
+           return pclvalue( r , modflag , required );
+#      endif PC
        firstp = p = lookup(r[2]);
        firstp = p = lookup(r[2]);
-       if (p == NIL)
+       if (p == NIL) {
                return (NIL);
                return (NIL);
+       }
        c = r[3];
        c = r[3];
-       if ((modflag & NOUSE) && !lptr(c))
+       if ((modflag & NOUSE) && !lptr(c)) {
                p->nl_flags = flagwas;
                p->nl_flags = flagwas;
-       if (modflag & MOD)
+       }
+       if (modflag & MOD) {
                p->nl_flags |= NMOD;
                p->nl_flags |= NMOD;
+       }
        /*
         * Only possibilities for p->class here
         * are the named classes, i.e. CONST, TYPE
        /*
         * Only possibilities for p->class here
         * are the named classes, i.e. CONST, TYPE
@@ -80,12 +94,7 @@ lvalue(r, modflag)
                         * of the WITHPTR or REF
                         * as the base of our lvalue
                         */
                         * of the WITHPTR or REF
                         * as the base of our lvalue
                         */
-#                      ifdef VAX
-                           put2 ( O_RV4 | bn << 9 , p->value[0] );
-#                      endif
-#                      ifdef PDP11
-                           put2(O_RV2 | bn << 9, p->value[0]);
-#                      endif
+                       put(2, PTR_RV | bn << 8+INDX , p->value[0] );
                        f = 0;          /* have an lv on stack */
                        o = 0;
                        break;
                        f = 0;          /* have an lv on stack */
                        o = 0;
                        break;
@@ -107,12 +116,14 @@ lvalue(r, modflag)
        }
        for (; c != NIL; c = c[2]) {
                co = c[1];
        }
        for (; c != NIL; c = c[2]) {
                co = c[1];
-               if (co == NIL)
+               if (co == NIL) {
                        return (NIL);
                        return (NIL);
+               }
                lastp = p;
                p = p->type;
                lastp = p;
                p = p->type;
-               if (p == NIL)
+               if (p == NIL) {
                        return (NIL);
                        return (NIL);
+               }
                switch (co[0]) {
                        case T_PTR:
                                /*
                switch (co[0]) {
                        case T_PTR:
                                /*
@@ -123,22 +134,13 @@ lvalue(r, modflag)
                                        error("^ allowed only on files and pointers, not on %ss", nameof(p));
                                        goto bad;
                                }
                                        error("^ allowed only on files and pointers, not on %ss", nameof(p));
                                        goto bad;
                                }
-                               if (f)
-#                                      ifdef VAX
-                                           put2 ( O_RV4 | bn << 9 , o );
-#                                      endif
-#                                      ifdef PDP11
-                                           put2(O_RV2 | bn<<9, o);
-#                                      endif
-                               else {
-                                       if (o)
-                                               put2(O_OFF, o);
-#                                      ifdef VAX
-                                           put1 ( O_IND4 );
-#                                      endif
-#                                      ifdef PDP11
-                                           put1(O_IND2);
-#                                      endif
+                               if (f) {
+                                   put(2, PTR_RV | bn <<8+INDX , o );
+                               } else {
+                                       if (o) {
+                                           put2(O_OFF, o);
+                                       }
+                                       put(1, PTR_IND);
                                }
                                /*
                                 * Pointer cannot be
                                }
                                /*
                                 * Pointer cannot be
@@ -150,10 +152,11 @@ lvalue(r, modflag)
                                continue;
                        case T_ARGL:
                                if (p->class != ARRAY) {
                                continue;
                        case T_ARGL:
                                if (p->class != ARRAY) {
-                                       if (lastp == firstp)
+                                       if (lastp == firstp) {
                                                error("%s is a %s, not a function", r[2], classes[firstp->class]);
                                                error("%s is a %s, not a function", r[2], classes[firstp->class]);
-                                       else
+                                       } else {
                                                error("Illegal function qualificiation");
                                                error("Illegal function qualificiation");
+                                       }
                                        return (NIL);
                                }
                                recovered();
                                        return (NIL);
                                }
                                recovered();
@@ -163,10 +166,13 @@ lvalue(r, modflag)
                                        error("Subscripting allowed only on arrays, not on %ss", nameof(p));
                                        goto bad;
                                }
                                        error("Subscripting allowed only on arrays, not on %ss", nameof(p));
                                        goto bad;
                                }
-                               if (f)
-                                       put2(O_LV | bn<<9, o);
-                               else if (o)
-                                       put2(O_OFF, o);
+                               if (f) {
+                                       put2(O_LV | bn<<8+INDX, o);
+                               } else {
+                                       if (o) {
+                                           put2(O_OFF, o);
+                                       }
+                               }
                                switch (arycod(p, co[1])) {
                                        case 0:
                                                return (NIL);
                                switch (arycod(p, co[1])) {
                                        case 0:
                                                return (NIL);
@@ -185,8 +191,9 @@ lvalue(r, modflag)
                                        error(". allowed only on records, not on %ss", nameof(p));
                                        goto bad;
                                }
                                        error(". allowed only on records, not on %ss", nameof(p));
                                        goto bad;
                                }
-                               if (co[1] == NIL)
+                               if (co[1] == NIL) {
                                        return (NIL);
                                        return (NIL);
+                               }
                                p = reclook(p, co[1]);
                                if (p == NIL) {
                                        error("%s is not a field in this record", co[1]);
                                p = reclook(p, co[1]);
                                if (p == NIL) {
                                        error("%s is not a field in this record", co[1]);
@@ -199,20 +206,25 @@ lvalue(r, modflag)
                                     */
                                    co[3] = p;
 #                              endif
                                     */
                                    co[3] = p;
 #                              endif
-                               if (modflag & MOD)
+                               if (modflag & MOD) {
                                        p->nl_flags |= NMOD;
                                        p->nl_flags |= NMOD;
-                               if ((modflag & NOUSE) == 0 || lptr(c[2]))
+                               }
+                               if ((modflag & NOUSE) == 0 || lptr(c[2])) {
                                        p->nl_flags |= NUSED;
                                        p->nl_flags |= NUSED;
+                               }
                                o += p->value[0];
                                continue;
                        default:
                                panic("lval2");
                }
        }
                                o += p->value[0];
                                continue;
                        default:
                                panic("lval2");
                }
        }
-       if (f)
-               put2(O_LV | bn<<9, o);
-       else if (o)
-               put2(O_OFF, o);
+       if (f) {
+               put2(O_LV | bn<<8+INDX, o);
+       } else {
+               if (o) {
+                   put2(O_OFF, o);
+               }
+       }
        return (p->type);
 bad:
        cerror("Error occurred on qualification of %s", r[2]);
        return (p->type);
 bad:
        cerror("Error occurred on qualification of %s", r[2]);
@@ -226,8 +238,9 @@ lptr(c)
 
        for (; c != NIL; c = c[2]) {
                co = c[1];
 
        for (; c != NIL; c = c[2]) {
                co = c[1];
-               if (co == NIL)
+               if (co == NIL) {
                        return (NIL);
                        return (NIL);
+               }
                switch (co[0]) {
 
                case T_PTR:
                switch (co[0]) {
 
                case T_PTR:
@@ -258,8 +271,9 @@ arycod(np, el)
        int w;
 
        p = np;
        int w;
 
        p = np;
-       if (el == NIL)
+       if (el == NIL) {
                return (0);
                return (0);
+       }
        d = p->value[0];
        /*
         * Check each subscript
        d = p->value[0];
        /*
         * Check each subscript
@@ -270,29 +284,60 @@ arycod(np, el)
                        return (-1);
                }
                p = p->chain;
                        return (-1);
                }
                p = p->chain;
-               ap = rvalue(el[1], NLNIL);
-               if (ap == NIL)
+#              ifdef PC
+                   precheck( p , "_SUBSC" , "_SUBSCZ" );
+#              endif PC
+               ap = rvalue(el[1], NLNIL , RREQ );
+               if (ap == NIL) {
                        return (0);
                        return (0);
+               }
+#              ifdef PC
+                   postcheck( p );
+#              endif PC
                if (incompat(ap, p->type, el[1])) {
                        cerror("Array index type incompatible with declared index type");
                if (incompat(ap, p->type, el[1])) {
                        cerror("Array index type incompatible with declared index type");
-                       if (d != 1)
+                       if (d != 1) {
                                cerror("Error occurred on index number %d", i);
                                cerror("Error occurred on index number %d", i);
+                       }
                        return (-1);
                }
                w = aryconst(np, i);
                        return (-1);
                }
                w = aryconst(np, i);
-               if (opt('t') == 0)
-                       switch (w) {
-                       case 8:
-                               w = 6;
-                       case 4:
-                       case 2:
-                       case 1:
-                               put2((width(ap) != 4 ? O_INX2P2 : O_INX4P2) | (w & ~1) << 7, ( short ) p->range[0]);
-                               el = el[2];
-                               continue;
-                       }
-               put(4, width(ap) != 4 ? O_INX2 : O_INX4,w,( short ) p->range[0],
-                      ( short ) ( p->range[1] - p->range[0] ) );
+#              ifdef OBJ
+                   if (opt('t') == 0) {
+                           switch (w) {
+                           case 8:
+                                   w = 6;
+                           case 4:
+                           case 2:
+                           case 1:
+                                   put2((width(ap) != 4 ? O_INX2P2 : O_INX4P2) | (w & ~1) << 7, ( short ) p->range[0]);
+                                   el = el[2];
+                                   continue;
+                           }
+                   }
+                   put(4, width(ap) != 4 ? O_INX2 : O_INX4,w,( short ) p->range[0],
+                          ( short ) ( p->range[1] - p->range[0] ) );
+#              endif OBJ
+#              ifdef PC
+                       /*
+                        *      subtract off the lower bound
+                        */
+                   if ( p -> range[ 0 ] != 0 ) {
+                       putleaf( P2ICON , p -> range[0] , 0 , P2INT , 0 );
+                       putop( P2MINUS , P2INT );
+                   }
+                       /*
+                        *      multiply by the width of the elements
+                        */
+                   if ( w != 1 ) {
+                       putleaf( P2ICON , w , 0 , P2INT , 0 );
+                       putop( P2MUL , P2INT );
+                   }
+                       /*
+                        *      and add it to the base address
+                        */
+                   putop( P2PLUS , ADDTYPE( p2type( np -> type ) , P2PTR ) );
+#              endif PC
                el = el[2];
        }
        if (el != NIL) {
                el = el[2];
        }
        if (el != NIL) {