BSD 4_4 release
[unix-history] / usr / src / usr.bin / pascal / src / case.c
index 4b5b77d..c934235 100644 (file)
@@ -1,11 +1,45 @@
-/* Copyright (c) 1979 Regents of the University of California */
+/*-
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 
-static char sccsid[] = "@(#)case.c 1.2 %G%";
+#ifndef lint
+static char sccsid[] = "@(#)case.c     8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
 
 #include "whoami.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
 
 #include "whoami.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
+#include "tree_ty.h"
 
 /*
  * The structure used to
 
 /*
  * The structure used to
@@ -22,19 +56,20 @@ struct ct {
  * Caseop generates the
  * pascal case statement code
  */
  * Caseop generates the
  * pascal case statement code
  */
-caseop(r)
-       int *r;
+caseop(rnode)
+       WHI_CAS *rnode;
 {
        register struct nl *p;
        register struct ct *ctab;
 {
        register struct nl *p;
        register struct ct *ctab;
-       register *cs;
-       int *cl;
+       register struct tnode *cs;
+       extern char *lc;
        double low, high;
        short *brtab;
        char *brtab0;
        char *csend;
        double low, high;
        short *brtab;
        char *brtab0;
        char *csend;
-       int w, i, j, m, n;
-       int nr, goc;
+       int w, j, m, n;
+       int goc;
+       bool nr;
 
        goc = gocnt;
        /*
 
        goc = gocnt;
        /*
@@ -44,17 +79,21 @@ caseop(r)
         *      low     lwb(p)
         *      high    upb(p)
         */
         *      low     lwb(p)
         *      high    upb(p)
         */
-       p = rvalue((int *) r[2], NLNIL , RREQ );
-       if (p != NIL) {
+       p = rvalue(rnode->expr, NLNIL , RREQ );
+
+       {
+           register struct nl  *cl;
+
+       if (p != NLNIL) {
                if (isnta(p, "bcsi")) {
                        error("Case selectors cannot be %ss", nameof(p));
                if (isnta(p, "bcsi")) {
                        error("Case selectors cannot be %ss", nameof(p));
-                       p = NIL;
+                       p = NLNIL;
                } else {
                        cl = p;
                } else {
                        cl = p;
-                       if (p->class != RANGE)
+                       if (p->class != (char) RANGE)
                                cl = p->type;
                                cl = p->type;
-                       if (cl == NIL)
-                               p = NIL;
+                       if (cl == NLNIL)
+                               p = NLNIL;
                        else {
                                w = width(p);
 #ifdef DEBUG
                        else {
                                w = width(p);
 #ifdef DEBUG
@@ -66,41 +105,55 @@ caseop(r)
                        }
                }
        }
                        }
                }
        }
+       } /* local declaration */
+       {
+           struct tnode        *cl;    /* list node */
        /*
         * Count # of cases
         */
        n = 0;
        /*
         * Count # of cases
         */
        n = 0;
-       for (cl = r[3]; cl != NIL; cl = cl[2]) {
-               cs = cl[1];
-               if (cs == NIL)
+       for (cl = rnode->stmnt_list; cl != TR_NIL;
+               cl = cl->list_node.next) {
+               cs = cl->list_node.list;;
+               if (cs == TR_NIL)
                        continue;
                        continue;
-               for (cs = cs[2]; cs != NIL; cs = cs[2])
+               for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
+                               cs = cs->list_node.next)
                        n++;
        }
                        n++;
        }
+       } /* local declaration */
        /*
         * Allocate case table space
         */
        /*
         * Allocate case table space
         */
-       ctab = i = malloc(n * sizeof *ctab);
+       {
+               char *i;
+       i = malloc((unsigned) n * sizeof *ctab);
        if (i == 0) {
                error("Ran out of memory (case)");
                pexit(DIED);
        }
        if (i == 0) {
                error("Ran out of memory (case)");
                pexit(DIED);
        }
+       ctab = (struct ct *) i;
+       }
        /*
         * Check the legality of the
         * labels and count the number
         * of good labels
         */
        /*
         * Check the legality of the
         * labels and count the number
         * of good labels
         */
+       {
+           register struct tnode *cl;
        m = 0;
        m = 0;
-       for (cl = r[3]; cl != NIL; cl = cl[2]) {
-               cs = cl[1];
-               if (cs == NIL)
+       for (cl = rnode->stmnt_list; cl != TR_NIL;
+               cl = cl->list_node.next) {
+               cs = cl->list_node.list;
+               if (cs == TR_NIL)
                        continue;
                        continue;
-               line = cs[1];
-               for (cs = cs[2]; cs != NIL; cs = cs[2]) {
-                       gconst(cs[1]);
-                       if (p == NIL || con.ctype == NIL)
+               line = cs->c_stmnt.line_no;
+               for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
+                               cs =  cs->list_node.next) {
+                       gconst(cs->list_node.list);
+                       if (p == NLNIL || con.ctype == NIL)
                                continue;
                                continue;
-                       if (incompat(con.ctype, p, NIL )) {
+                       if (incompat(con.ctype, p, TR_NIL )) {
                                cerror("Case label type clashed with case selector expression type");
                                continue;
                        }
                                cerror("Case label type clashed with case selector expression type");
                                continue;
                        }
@@ -113,7 +166,9 @@ caseop(r)
                        m++;
                }
        }
                        m++;
                }
        }
-
+       } /* decl of cl */
+       {
+               register int i;
        /*
         * Check for duplicate labels
         */
        /*
         * Check for duplicate labels
         */
@@ -124,29 +179,37 @@ caseop(r)
                                        continue;
                                if (j < i)
                                        break;
                                        continue;
                                if (j < i)
                                        break;
-                               error("Multiply defined label in case, lines %d and %d", ctab[i].cline, ctab[j].cline);
+                               error("Multiply defined label in case, lines %d and %d", (char *) ctab[i].cline, (char *) ctab[j].cline);
                        }
                        }
+       }
        /*
         * Put out case operator and
         * leave space for the
         * branch table
         */
        /*
         * Put out case operator and
         * leave space for the
         * branch table
         */
-       if (p != NIL) {
-               put(2, O_CASE1OP + (w >> 1), n);
-               brtab = brtab0 = lc;
+       if (p != NLNIL) {
+               (void) put(2, O_CASE1OP + (w >> 1), n);
+               brtab0 = lc;
+               brtab = ((short *) brtab0);
                putspace(n * 2);
                putspace(n * 2);
-               put(1, O_CASEBEG);
+               (void) put(1, O_CASEBEG);
+               {
+                   int i;
                for (i=0; i<m; i++)
                for (i=0; i<m; i++)
-                       put( 2 , O_CASE1 + (w >> 1), ctab[i].clong);
-               put(1, O_CASEEND);
+                       if (w <= 2)
+                               (void) put(2 ,O_CASE1 + (w >> 1), (int)ctab[i].clong);
+                       else
+                               (void) put(2 ,O_CASE4, ctab[i].clong);
+               }
+               (void) put(1, O_CASEEND);
        }
        csend = getlab();
        }
        csend = getlab();
-       put(2, O_TRA, csend);
+       (void) put(2, O_TRA, csend);
        /*
         * Free the case
         * table space.
         */
        /*
         * Free the case
         * table space.
         */
-       free(ctab);
+       free((char *) ctab);
        /*
         * Generate code for each
         * statement. Patch branch
        /*
         * Generate code for each
         * statement. Patch branch
@@ -155,31 +218,49 @@ caseop(r)
         * statement with a branch back
         * to the TRA above.
         */
         * statement with a branch back
         * to the TRA above.
         */
-       nr = 1;
-       for (cl = r[3]; cl != NIL; cl = cl[2]) {
-               cs = cl[1];
-               if (cs == NIL)
+       {
+           register struct tnode *cl;
+       nr = TRUE;
+       for (cl = rnode->stmnt_list; cl != TR_NIL;
+                       cl = cl->list_node.next) {
+               cs = cl->list_node.list;
+               if (cs == TR_NIL)
                        continue;
                        continue;
-               if (p != NIL)
-                       for (cs = cs[2]; cs != NIL; cs = cs[2]) {
-                               patchfil(brtab - 1, lc - brtab0, 1);
+               if (p != NLNIL)
+                       for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
+                               cs =  cs->list_node.next) {
+#ifdef ADDR16
+                               patchfil(((char *) (brtab - 1)),
+                                       (long)(lc - brtab0), 1);
+#endif ADDR16
+#ifdef ADDR32
+                               
+                               patchfil( ((unsigned long) (brtab - 1)),
+                                       (long)(lc - brtab0), 1);
+#endif ADDR32
                                brtab++;
                        }
                                brtab++;
                        }
-               cs = cl[1];
+               cs = cl->list_node.list;
                putcnt();
                level++;
                putcnt();
                level++;
-               statement(cs[3]);
-               nr &= noreach;
-               noreach = 0;
-               put(2, O_TRA, csend);
+               statement(cs->c_stmnt.stmnt);
+               nr = (bool)(noreach && nr);
+               noreach = FALSE;
+               (void) put(2, O_TRA, csend);
                level--;
                if (gotos[cbn])
                        ungoto();
        }
                level--;
                if (gotos[cbn])
                        ungoto();
        }
+       } /* decl of cl */
        /*
         * Patch the termination branch
         */
        /*
         * Patch the termination branch
         */
-       patch(csend);
+#ifdef ADDR16
+       patch((char *) csend);
+#endif ADDR16
+#ifdef ADDR32
+       patch((unsigned long) csend);
+#endif ADDR32
        noreach = nr;
        if (goc != gocnt)
                putcnt();
        noreach = nr;
        if (goc != gocnt)
                putcnt();