newer version
authorceriel <none@none>
Tue, 17 Jun 1986 12:04:05 +0000 (12:04 +0000)
committerceriel <none@none>
Tue, 17 Jun 1986 12:04:05 +0000 (12:04 +0000)
21 files changed:
lang/m2/comp/LLlex.c
lang/m2/comp/Makefile
lang/m2/comp/chk_expr.c
lang/m2/comp/chk_expr.h [new file with mode: 0644]
lang/m2/comp/code.c
lang/m2/comp/declar.g
lang/m2/comp/def.H
lang/m2/comp/def.c
lang/m2/comp/desig.c
lang/m2/comp/desig.h
lang/m2/comp/enter.c
lang/m2/comp/expression.g
lang/m2/comp/lookup.c
lang/m2/comp/misc.c
lang/m2/comp/node.H
lang/m2/comp/node.c
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/statement.g
lang/m2/comp/type.c
lang/m2/comp/walk.c

index 5f4c8b4..20d08b3 100644 (file)
@@ -33,7 +33,7 @@ int idfsize = IDFSIZE;
 extern int     cntlines;
 #endif
 
-static
+STATIC
 SkipComment()
 {
        /*      Skip Modula-2 comments (* ... *).
@@ -50,16 +50,12 @@ SkipComment()
                        cntlines++;
 #endif
                }
-               else
-               if (ch == '(') {
+               else if (ch == '(') {
                        LoadChar(ch);
-                       if (ch == '*') {
-                               ++NestLevel;
-                       }
+                       if (ch == '*') ++NestLevel;
                        else    continue;
                }
-               else
-               if (ch == '*') {
+               else if (ch == '*') {
                        LoadChar(ch);
                        if (ch == ')') {
                                if (NestLevel-- == 0) return;
@@ -70,7 +66,7 @@ SkipComment()
        }
 }
 
-static
+STATIC
 GetString(upto)
 {
        /*      Read a Modula-2 string, delimited by the character "upto".
@@ -118,11 +114,13 @@ LLlex()
        register int ch, nch;
 
        toktype = error_type;
+
        if (ASIDE)      {       /* a token is put aside         */
                *tk = aside;
                ASIDE = 0;
                return tk->tk_symb;
        }
+
        tk->tk_lineno = LineNumber;
 
 again:
@@ -216,8 +214,7 @@ again:
                        LoadChar(ch);
                } while(in_idf(ch));
 
-               if (ch != EOI)
-                       PushBack(ch);
+               if (ch != EOI) PushBack(ch);
                *tg++ = '\0';
 
                tk->TOK_IDF = id = str2idf(buf, 1);
@@ -396,6 +393,7 @@ Sreal:
                                lexerror("floating constant too long");
                        }
                        else    tk->TOK_REL = Salloc(buf, np - buf) + 1;
+                       toktype = real_type;
                        return tk->tk_symb = REAL;
 
                default:
index a295f17..48df7b4 100644 (file)
@@ -9,10 +9,11 @@ INCLUDES = -I$(HDIR) -I/usr/em/h -I$(PKGDIR) -I/user1/erikb/em/h
 
 LSRC = tokenfile.g program.g declar.g expression.g statement.g
 CC =   cc
-GEN =  LLgen
-GENOPTIONS =
-PROFILE = 
-CFLAGS = $(PROFILE) $(INCLUDES)
+GEN =  /usr/em/util/LLgen/src/LLgen
+GENOPTIONS = -d
+PROFILE = -p
+CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
+LINTFLAGS = -DSTATIC= -DNORCSID
 LFLAGS = $(PROFILE)
 LOBJ = tokenfile.o program.o declar.o expression.o statement.o
 COBJ = LLlex.o LLmessage.o char.o error.o main.o \
@@ -46,7 +47,7 @@ clean:
        rm -f $(OBJ) $(GENFILES) LLfiles 
 
 lint:  LLfiles hfiles
-       lint $(INCLUDES) -DNORCSID `sources $(OBJ)`
+       lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)`
 
 tokenfile.g:   tokenname.c make.tokfile
        make.tokfile <tokenname.c >tokenfile.g
@@ -98,16 +99,17 @@ defmodule.o: LLlex.h debug.h def.h f_info.h idf.h input.h inputtype.h main.h sco
 typequiv.o: LLlex.h def.h node.h type.h
 node.o: LLlex.h debug.h def.h node.h type.h
 cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h
-chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
+chk_expr.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
 options.o: idfsize.h main.h ndir.h type.h
-walk.o: LLlex.h Lpars.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h
+walk.o: LLlex.h Lpars.h chk_expr.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h
 casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h
 desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h
 code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h
 tmpvar.o: debug.h def.h scope.h type.h
+lookup.o: LLlex.h debug.h def.h idf.h node.h scope.h
 tokenfile.o: Lpars.h
 program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
 declar.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h
-expression.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h type.h
+expression.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h type.h
 statement.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.h
 Lpars.o: Lpars.h
index 82f3288..ea1b0a2 100644 (file)
@@ -23,158 +23,72 @@ static char *RcsId = "$Header$";
 #include       "scope.h"
 #include       "const.h"
 #include       "standards.h"
+#include       "chk_expr.h"
 
 extern char *symbol2str();
 
-int
-chk_expr(expp)
-       register struct node *expp;
+STATIC int
+chk_arr(expp)
+       struct node *expp;
 {
-       /*      Check the expression indicated by expp for semantic errors,
-               identify identifiers used in it, replace constants by
-               their value, and try to evaluate the expression.
-       */
-
-       switch(expp->nd_class) {
-       case Arrsel:
-               return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED);
-
-       case Oper:
-               return  chk_oper(expp);
-
-       case Arrow:
-               return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED);
-
-       case Uoper:
-               return  chk_uoper(expp);
-
-       case Value:
-               switch(expp->nd_symb) {
-               case REAL:
-               case STRING:
-               case INTEGER:
-                       return 1;
-
-               default:
-                       crash("(chk_expr(Value))");
-               }
-               break;
-
-       case Xset:
-               return chk_set(expp);
-
-       case Link:
-       case Name:
-               if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) {
-                       if (expp->nd_class == Def &&
-                           expp->nd_def->df_kind == D_PROCEDURE) {
-                               /* Check that this procedure is one that we
-                                  may take the address from.
-                               */
-                               if (expp->nd_def->df_type == std_type) {
-                                       /* Standard procedure. Illegal */
-node_error(expp, "address of standard procedure taken");
-                                       return 0;
-                               }
-                               if (expp->nd_def->df_scope->sc_level > 0) {
-                                       /* Address of nested procedure taken.
-                                          Illegal.
-                                       */
-node_error(expp, "address of a procedure local to another one taken");
-                                       return 0;
-                               }
-                       }
-                       return 1;
-               }
-               return 0;
+       return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED);
+}
 
-       case Call:
-               return chk_call(expp);
+STATIC int
+chk_value(expp)
+       struct node *expp;
+{
+       switch(expp->nd_symb) {
+       case REAL:
+       case STRING:
+       case INTEGER:
+               return 1;
 
        default:
-               crash("(chk_expr)");
+               crash("(chk_value)");
        }
        /*NOTREACHED*/
 }
 
-int
-chk_set(expp)
+STATIC int
+chk_linkorname(expp)
        register struct node *expp;
 {
-       /*      Check the legality of a SET aggregate, and try to evaluate it
-               compile time. Unfortunately this is all rather complicated.
-       */
-       register struct type *tp;
-       register struct node *nd;
-       register struct def *df;
-       arith *set;
-       unsigned size;
-
-       assert(expp->nd_symb == SET);
-
-       /* First determine the type of the set
-       */
-       if (nd = expp->nd_left) {
-               /* A type was given. Check it out
-               */
-               if (! chk_designator(nd, 0, D_USED)) return 0;
-
-               assert(nd->nd_class == Def);
-               df = nd->nd_def;
-
-               if (!(df->df_kind & (D_TYPE|D_ERROR)) ||
-                   (df->df_type->tp_fund != T_SET)) {
-node_error(expp, "specifier does not represent a set type");
-                       return 0;
+       if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) {
+               if (expp->nd_class == Def &&
+                   expp->nd_def->df_kind == D_PROCEDURE) {
+                       /* Check that this procedure is one that we
+                          may take the address from.
+                       */
+                       if (expp->nd_def->df_type == std_type ||
+                           expp->nd_def->df_scope->sc_level > 0) {
+                               /* Address of standard or nested procedure
+                                  taken.
+                               */
+node_error(expp, "it is illegal to take the address of a standard or local procedure");
+                               return 0;
+                       }
                }
-               tp = df->df_type;
-               FreeNode(expp->nd_left);
-               expp->nd_left = 0;
-       }
-       else    tp = bitset_type;
-       expp->nd_type = tp;
-
-       nd = expp->nd_right;
-
-       /* Now check the elements given, and try to compute a constant set.
-          First allocate room for the set, but only if it is'nt empty.
-       */
-       if (! nd) {
-               /* The resulting set IS empty, so we just return
-               */
-               expp->nd_class = Set;
-               expp->nd_set = 0;
                return 1;
        }
-       size = tp->tp_size * (sizeof(arith) / word_size);
-       set = (arith *) Malloc(size);
-       clear((char *) set, size);
+       return 0;
+}
 
-       /* Now check the elements, one by one
+STATIC int
+RemoveSet(set)
+       arith **set;
+{
+       /*      This routine is only used for error exits of chk_el.
+               It frees the set indicated by "set", and returns 0.
        */
-       while (nd) {
-               assert(nd->nd_class == Link && nd->nd_symb == ',');
-
-               if (!chk_el(nd->nd_left, tp->next, &set)) return 0;
-               nd = nd->nd_right;
-       }
-
-       if (set) {
-               /* Yes, it was a constant set, and we managed to compute it!
-                  Notice that at the moment there is no such thing as
-                  partial evaluation. Either we evaluate the set, or we
-                  don't (at all). Improvement not neccesary. (???)
-               */
-               expp->nd_class = Set;
-               expp->nd_set = set;
-               FreeNode(expp->nd_right);
-               expp->nd_right = 0;
+       if (*set) {
+               free((char *) *set);
+               *set = 0;
        }
-
-       return 1;
+       return 0;
 }
 
-int
+STATIC int
 chk_el(expp, tp, set)
        register struct node *expp;
        register struct type *tp;
@@ -203,7 +117,7 @@ chk_el(expp, tp, set)
 
                        if (left->nd_INT > right->nd_INT) {
 node_error(expp, "lower bound exceeds upper bound in range");
-                               return rem_set(set);
+                               return RemoveSet(set);
                        }
 
                        if (*set) {
@@ -223,12 +137,12 @@ node_error(expp, "lower bound exceeds upper bound in range");
        /* Here, a single element is checked
        */
        if (!chk_expr(expp)) {
-               return rem_set(set);
+               return RemoveSet(set);
        }
 
        if (!TstCompat(tp, expp->nd_type)) {
                node_error(expp, "set element has incompatible type");
-               return rem_set(set);
+               return RemoveSet(set);
        }
 
        if (expp->nd_class == Value) {
@@ -243,7 +157,7 @@ node_error(expp, "lower bound exceeds upper bound in range");
                     (i < 0 || i > tp->enm_ncst))
                   ) {
                        node_error(expp, "set element out of range");
-                       return rem_set(set);
+                       return RemoveSet(set);
                }
 
                if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits));
@@ -252,48 +166,126 @@ node_error(expp, "lower bound exceeds upper bound in range");
        return 1;
 }
 
-int
-rem_set(set)
-       arith **set;
+STATIC int
+chk_set(expp)
+       register struct node *expp;
 {
-       /*      This routine is only used for error exits of chk_el.
-               It frees the set indicated by "set", and returns 0.
+       /*      Check the legality of a SET aggregate, and try to evaluate it
+               compile time. Unfortunately this is all rather complicated.
        */
-       if (*set) {
-               free((char *) *set);
-               *set = 0;
+       register struct type *tp;
+       register struct node *nd;
+       register struct def *df;
+       arith *set;
+       unsigned size;
+
+       assert(expp->nd_symb == SET);
+
+       /* First determine the type of the set
+       */
+       if (nd = expp->nd_left) {
+               /* A type was given. Check it out
+               */
+               if (! chk_designator(nd, 0, D_USED)) return 0;
+
+               assert(nd->nd_class == Def);
+               df = nd->nd_def;
+
+               if (!(df->df_kind & (D_TYPE|D_ERROR)) ||
+                   (df->df_type->tp_fund != T_SET)) {
+node_error(expp, "specifier does not represent a set type");
+                       return 0;
+               }
+               tp = df->df_type;
+               FreeNode(expp->nd_left);
+               expp->nd_left = 0;
        }
-       return 0;
+       else    tp = bitset_type;
+       expp->nd_type = tp;
+
+       nd = expp->nd_right;
+
+       /* Now check the elements given, and try to compute a constant set.
+          First allocate room for the set, but only if it is'nt empty.
+       */
+       if (! nd) {
+               /* The resulting set IS empty, so we just return
+               */
+               expp->nd_class = Set;
+               expp->nd_set = 0;
+               return 1;
+       }
+       size = tp->tp_size * (sizeof(arith) / word_size);
+       set = (arith *) Malloc(size);
+       clear((char *) set, size);
+
+       /* Now check the elements, one by one
+       */
+       while (nd) {
+               assert(nd->nd_class == Link && nd->nd_symb == ',');
+
+               if (!chk_el(nd->nd_left, tp->next, &set)) return 0;
+               nd = nd->nd_right;
+       }
+
+       if (set) {
+               /* Yes, it was a constant set, and we managed to compute it!
+                  Notice that at the moment there is no such thing as
+                  partial evaluation. Either we evaluate the set, or we
+                  don't (at all). Improvement not neccesary. (???)
+               */
+               expp->nd_class = Set;
+               expp->nd_set = set;
+               FreeNode(expp->nd_right);
+               expp->nd_right = 0;
+       }
+
+       return 1;
 }
 
-struct node *
+STATIC struct node *
 getarg(argp, bases, designator)
        struct node **argp;
 {
+       /*      This routine is used to fetch the next argument from an
+               argument list. The argument list is indicated by "argp".
+               The parameter "bases" is a bitset indicating which types
+               are allowed at this point, and "designator" is a flag
+               indicating that the address from this argument is taken, so
+               that it must be a designator and may not be a register
+               variable.
+       */
        struct type *tp;
        register struct node *arg = *argp;
+       register struct node *left;
 
-       if (!arg->nd_right) {
+       if (! arg->nd_right) {
                node_error(arg, "too few arguments supplied");
                return 0;
        }
+
        arg = arg->nd_right;
-       if ((!designator && !chk_expr(arg->nd_left)) ||
-           (designator && !chk_designator(arg->nd_left, DESIGNATOR, D_REFERRED))) {
+       left = arg->nd_left;
+
+       if ((!designator && !chk_expr(left)) ||
+           (designator &&
+            !chk_designator(left, DESIGNATOR|VARIABLE, D_USED|D_NOREG))) {
                return 0;
        }
-       tp = arg->nd_left->nd_type;
+
+       tp = left->nd_type;
        if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
+
        if (bases && !(tp->tp_fund & bases)) {
                node_error(arg, "unexpected type");
                return 0;
        }
 
        *argp = arg;
-       return arg->nd_left;
+       return left;
 }
 
-struct node *
+STATIC struct node *
 getname(argp, kinds)
        struct node **argp;
 {
@@ -303,10 +295,11 @@ getname(argp, kinds)
                node_error(arg, "too few arguments supplied");
                return 0;
        }
+
        arg = arg->nd_right;
        if (! chk_designator(arg->nd_left, 0, D_REFERRED)) return 0;
 
-       assert(arg->nd_left->nd_class == Def);
+       if (arg->nd_left->nd_class != Def);
 
        if (!(arg->nd_left->nd_def->df_kind & kinds)) {
                node_error(arg, "unexpected type");
@@ -317,6 +310,42 @@ getname(argp, kinds)
        return arg->nd_left;
 }
 
+STATIC int
+chk_proccall(expp)
+       register struct node *expp;
+{
+       /*      Check a procedure call
+       */
+       register struct node *left;
+       struct node *arg;
+       register struct paramlist *param;
+
+       left = expp->nd_left;
+       arg = expp;
+       expp->nd_type = left->nd_type->next;
+
+       for (param = left->nd_type->prc_params; param; param = param->next) {
+               if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
+               if (left->nd_symb == STRING) {
+                       TryToString(left, TypeOfParam(param));
+               }
+               if (! TstParCompat(TypeOfParam(param),
+                                  left->nd_type,
+                                  IsVarParam(param),
+                                  left)) {
+node_error(left, "type incompatibility in parameter");
+                       return 0;
+               }
+       }
+
+       if (arg->nd_right) {
+               node_error(arg->nd_right, "too many parameters supplied");
+               return 0;
+       }
+
+       return 1;
+}
+
 int
 chk_call(expp)
        register struct node *expp;
@@ -358,58 +387,7 @@ chk_call(expp)
        return 0;
 }
 
-chk_proccall(expp)
-       register struct node *expp;
-{
-       /*      Check a procedure call
-       */
-       register struct node *left;
-       struct node *arg;
-       register struct paramlist *param;
-
-       left = 0;
-       arg = expp->nd_right;
-       /* First, reverse the order in the argument list */
-       while (arg) {
-               expp->nd_right = arg;
-               arg = arg->nd_right;
-               expp->nd_right->nd_right = left;
-               left = expp->nd_right;
-       }
-
-       left = expp->nd_left;
-       arg = expp;
-       expp->nd_type = left->nd_type->next;
-       param = left->nd_type->prc_params;
-
-       while (param) {
-               if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
-               if (left->nd_symb == STRING) {
-                       TryToString(left, TypeOfParam(param));
-               }
-               if (! TstParCompat(TypeOfParam(param),
-                                  left->nd_type,
-                                  IsVarParam(param),
-                                  left)) {
-node_error(left, "type incompatibility in parameter");
-                       return 0;
-               }
-               if (IsVarParam(param) && left->nd_class == Def) {
-                       left->nd_def->df_flags |= D_NOREG;
-               }
-
-               param = param->next;
-       }
-
-       if (arg->nd_right) {
-               node_error(arg->nd_right, "too many parameters supplied");
-               return 0;
-       }
-
-       return 1;
-}
-
-static int
+STATIC int
 FlagCheck(expp, df, flag)
        struct node *expp;
        struct def *df;
@@ -461,7 +439,6 @@ chk_designator(expp, flag, dflags)
        */
        register struct def *df;
        register struct type *tp;
-       struct def *lookfor();
 
        expp->nd_type = error_type;
 
@@ -469,23 +446,20 @@ chk_designator(expp, flag, dflags)
                expp->nd_def = lookfor(expp, CurrVis, 1);
                expp->nd_class = Def;
                expp->nd_type = expp->nd_def->df_type;
-               if (expp->nd_type == error_type) return 0;
        }
+       else if (expp->nd_class == Link) {
+               register struct node *left = expp->nd_left;
 
-       if (expp->nd_class == Link) {
                assert(expp->nd_symb == '.');
 
-               if (! chk_designator(expp->nd_left,
-                                    flag|HASSELECTORS,
-                                    dflags|D_NOREG)) return 0;
-
-               tp = expp->nd_left->nd_type;
+               if (! chk_designator(left,
+                                    (flag&DESIGNATOR)|HASSELECTORS,
+                                    dflags)) return 0;
 
+               tp = left->nd_type;
                assert(tp->tp_fund == T_RECORD);
 
-               df = lookup(expp->nd_IDF, tp->rec_scope);
-
-               if (!df) {
+               if (!(df = lookup(expp->nd_IDF, tp->rec_scope))) {
                        id_not_declared(expp);
                        return 0;
                }
@@ -493,17 +467,19 @@ chk_designator(expp, flag, dflags)
                        expp->nd_def = df;
                        expp->nd_type = df->df_type;
                        if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
+                               /* Fields of a record are always D_QEXPORTED,
+                                  so ...
+                               */
 node_error(expp, "identifier \"%s\" not exported from qualifying module",
 df->df_idf->id_text);
                                return 0;
                        }
                }
 
-               if (expp->nd_left->nd_class == Def &&
-                   expp->nd_left->nd_def->df_kind == D_MODULE) {
+               if (left->nd_class == Def &&
+                   left->nd_def->df_kind == D_MODULE) {
                        expp->nd_class = Def;
-                       expp->nd_def = df;
-                       FreeNode(expp->nd_left);
+                       FreeNode(left);
                        expp->nd_left = 0;
                }
                else {
@@ -548,12 +524,12 @@ df->df_idf->id_text);
                assert(expp->nd_symb == '[');
 
                if ( 
-                       !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags|D_NOREG)
+                    !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags)
                   ||
-                       !chk_expr(expp->nd_right)
+                    !chk_expr(expp->nd_right)
                   ||
-                       expp->nd_left->nd_type == error_type
-                  ) return 0;
+                    expp->nd_left->nd_type == error_type
+                  )    return 0;
 
                tpr = expp->nd_right->nd_type;
                tpl = expp->nd_left->nd_type;
@@ -598,7 +574,7 @@ symbol2str(expp->nd_symb));
        return 0;
 }
 
-struct type *
+STATIC struct type *
 ResultOfOperation(operator, tp)
        struct type *tp;
 {
@@ -616,13 +592,13 @@ ResultOfOperation(operator, tp)
        return tp;
 }
 
-int
+STATIC int
 Boolean(operator)
 {
        return operator == OR || operator == AND || operator == '&';
 }
 
-int
+STATIC int
 AllowedTypes(operator)
 {
        switch(operator) {
@@ -654,7 +630,23 @@ AllowedTypes(operator)
        /*NOTREACHED*/
 }
 
-int
+STATIC int
+chk_address(tpl, tpr)
+       register struct type *tpl, *tpr;
+{
+       
+       if (tpl == address_type) {
+               return tpr == address_type || tpr->tp_fund != T_POINTER;
+       }
+
+       if (tpr == address_type) {
+               return tpl->tp_fund != T_POINTER;
+       }
+
+       return 0;
+}
+
+STATIC int
 chk_oper(expp)
        register struct node *expp;
 {
@@ -741,23 +733,7 @@ node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_
        return 1;
 }
 
-int
-chk_address(tpl, tpr)
-       register struct type *tpl, *tpr;
-{
-       
-       if (tpl == address_type) {
-               return tpr == address_type || tpr->tp_fund != T_POINTER;
-       }
-
-       if (tpr == address_type) {
-               return tpl->tp_fund != T_POINTER;
-       }
-
-       return 0;
-}
-
-int
+STATIC int
 chk_uoper(expp)
        register struct node *expp;
 {
@@ -826,7 +802,7 @@ chk_uoper(expp)
        return 0;
 }
 
-struct node *
+STATIC struct node *
 getvariable(argp)
        struct node **argp;
 {
@@ -916,7 +892,11 @@ DO_DEBUG(3,debug("standard name \"%s\", %d",left->nd_def->df_idf->id_text,std));
 
        case S_MAX:
        case S_MIN:
-               if (!(left = getarg(&arg, T_DISCRETE, 0))) return 0;
+               if (!(left = getname(&arg, D_ISTYPE))) return 0;
+               if (!(left->nd_type->tp_fund & (T_DISCRETE))) {
+                       node_error(left, "illegal type in MIN or MAX");
+                       return 0;
+               }
                expp->nd_type = left->nd_type;
                cstcall(expp,std);
                break;
@@ -1072,7 +1052,8 @@ TryToString(nd, tp)
        struct node *nd;
        struct type *tp;
 {
-       /*      Try a coercion from character constant to string */
+       /*      Try a coercion from character constant to string.
+       */
        if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) {
                int ch = nd->nd_INT;
 
@@ -1084,3 +1065,20 @@ TryToString(nd, tp)
                nd->nd_SLE = 1;
        }
 }
+
+extern int     NodeCrash();
+
+int (*ChkTable[])() = {
+       chk_value,
+       chk_arr,
+       chk_oper,
+       chk_uoper,
+       chk_arr,
+       chk_call,
+       chk_linkorname,
+       NodeCrash,
+       chk_set,
+       NodeCrash,
+       NodeCrash,
+       chk_linkorname
+};
diff --git a/lang/m2/comp/chk_expr.h b/lang/m2/comp/chk_expr.h
new file mode 100644 (file)
index 0000000..6b4422b
--- /dev/null
@@ -0,0 +1,9 @@
+/* E X P R E S S I O N   C H E C K I N G */
+
+/* $Header$ */
+
+extern int     (*ChkTable[])();        /* table of expression checking
+                                          functions, indexed by node class
+                                       */
+
+#define        chk_expr(expp)  ((*ChkTable[(expp)->nd_class])(expp))
index 48c55d2..9c81eb7 100644 (file)
@@ -129,7 +129,6 @@ CodeExpr(nd, ds, true_label, false_label)
                break;
 
        case Uoper:
-               CodePExpr(nd->nd_right);
                CodeUoper(nd);
                ds->dsg_kind = DSG_LOADED;
                break;
@@ -194,9 +193,9 @@ CodeCoercion(t1, t2)
 {
        register int fund1, fund2;
 
-       if (t1 == t2) return;
        if (t1->tp_fund == T_SUBRANGE) t1 = t1->next;
        if (t2->tp_fund == T_SUBRANGE) t2 = t2->next;
+       if (t1 == t2) return;
        if ((fund1 = t1->tp_fund) == T_WORD) fund1 = T_INTEGER;
        if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER;
        switch(fund1) {
@@ -291,9 +290,6 @@ CodeCall(nd)
                and result is already done.
        */
        register struct node *left = nd->nd_left;
-       register struct node *arg = nd;
-       register struct paramlist *param;
-       struct type *tp;
 
        if (left->nd_type == std_type) {
                CodeStd(nd);
@@ -311,49 +307,10 @@ CodeCall(nd)
 
        assert(IsProcCall(left));
 
-       for (param = left->nd_type->prc_params; param; param = param->next) {
-               tp = TypeOfParam(param);
-               arg = arg->nd_right;
-               assert(arg != 0);
-               left = arg->nd_left;
-               if (IsConformantArray(tp)) {
-                       C_loc(tp->arr_elsize);
-                       if (IsConformantArray(left->nd_type)) {
-                               DoHIGH(left);
-                       }
-                       else if (left->nd_symb == STRING) {
-                               C_loc(left->nd_SLE);
-                       }
-                       else if (tp->arr_elem == word_type) {
-                               C_loc(left->nd_type->tp_size / word_size - 1);
-                       }
-                       else {
-                               tp = left->nd_type->next;
-                               if (tp->tp_fund == T_SUBRANGE) {
-                                       C_loc(tp->sub_ub - tp->sub_lb);
-                               }
-                               else    C_loc((arith) (tp->enm_ncst - 1));
-                       }
-                       C_loc((arith) 0);
-                       if (left->nd_symb == STRING) {
-                               CodeString(left);
-                       }
-                       else    CodeDAddress(left);
-               }
-               else if (IsVarParam(param)) {
-                       CodeDAddress(left);
-               }
-               else {
-                       if (left->nd_type->tp_fund == T_STRING) {
-                               CodePadString(left, tp->tp_size);
-                       }
-                       else CodePExpr(left);
-                       CheckAssign(left->nd_type, tp);
-               }
+       if (nd->nd_right) {
+               CodeParameters(left->nd_type->prc_params, nd->nd_right);
        }
 
-       left = nd->nd_left;
-
        if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) {
                if (left->nd_def->df_scope->sc_level > 0) {
                        C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level);
@@ -373,6 +330,63 @@ CodeCall(nd)
        }
 }
 
+CodeParameters(param, arg)
+       struct paramlist *param;
+       struct node *arg;
+{
+       register struct type *tp;
+       register struct node *left;
+       
+       assert(param != 0 && arg != 0);
+
+       if (param->next) {
+               CodeParameters(param->next, arg->nd_right);
+       }
+
+       tp = TypeOfParam(param);
+       left = arg->nd_left;
+       if (IsConformantArray(tp)) {
+               C_loc(tp->arr_elsize);
+               if (IsConformantArray(left->nd_type)) {
+                       DoHIGH(left);
+                       if (tp->arr_elem->tp_size != left->nd_type->arr_elem->tp_size) {
+                               /* This can only happen if the formal type is
+                                  ARRAY OF WORD
+                               */
+                               /* ??? */
+                       }
+               }
+               else if (left->nd_symb == STRING) {
+                       C_loc(left->nd_SLE);
+               }
+               else if (tp->arr_elem == word_type) {
+                       C_loc(left->nd_type->tp_size / word_size - 1);
+               }
+               else {
+                       tp = left->nd_type->next;
+                       if (tp->tp_fund == T_SUBRANGE) {
+                               C_loc(tp->sub_ub - tp->sub_lb);
+                       }
+                       else    C_loc((arith) (tp->enm_ncst - 1));
+               }
+               C_loc((arith) 0);
+               if (left->nd_symb == STRING) {
+                       CodeString(left);
+               }
+               else    CodeDAddress(left);
+       }
+       else if (IsVarParam(param)) {
+               CodeDAddress(left);
+       }
+       else {
+               if (left->nd_type->tp_fund == T_STRING) {
+                       CodePadString(left, tp->tp_size);
+               }
+               else CodePExpr(left);
+               CheckAssign(left->nd_type, tp);
+       }
+}
+
 CodeStd(nd)
        struct node *nd;
 {
@@ -387,7 +401,6 @@ CodeStd(nd)
                if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
                arg = arg->nd_right;
        }
-       Desig = InitDesig;
 
        switch(std = nd->nd_left->nd_def->df_value.df_stdname) {
        case S_ABS:
@@ -546,14 +559,12 @@ CheckAssign(tpl, tpr)
        */
 
        arith llo, lhi, rlo, rhi;
-       label l = 0;
-       extern label getrck();
 
        if (bounded(tpl)) {
                /* in this case we might need a range check */
                if (!bounded(tpr)) {
                        /* yes, we need one */
-                       l = getrck(tpl);
+                       genrck(tpl);
                }
                else {
                        /* both types are restricted. check the bounds
@@ -562,14 +573,9 @@ CheckAssign(tpl, tpr)
                        getbounds(tpl, &llo, &lhi);
                        getbounds(tpr, &rlo, &rhi);
                        if (llo > rlo || lhi < rhi) {
-                               l = getrck(tpl);
+                               genrck(tpl);
                        }
                }
-
-               if (l) {
-                       C_lae_dlb(l, (arith) 0);
-                       C_rck(word_size);
-               }
        }
 }
 
@@ -916,6 +922,7 @@ CodeUoper(nd)
 {
        register struct type *tp = nd->nd_type;
 
+       CodePExpr(nd->nd_right);
        switch(nd->nd_symb) {
        case '~':
        case NOT:
index 9bad30c..63c0e3c 100644 (file)
@@ -461,7 +461,6 @@ PointerType(struct type **ptp;)
 {
        struct type *tp;
        struct def *df;
-       struct def *lookfor();
        struct node *nd;
 } :
        POINTER TO
index bdf9088..e87d3ac 100644 (file)
@@ -117,7 +117,11 @@ struct def {               /* list of definitions for a name */
 
 extern struct def
        *define(),
-       *lookup(),
+       *DefineLocalModule(),
+       *MkDef(),
        *ill_df;
 
+extern struct def
+       *lookup(),
+       *lookfor();
 #define NULLDEF ((struct def *) 0)
index 1b703ff..91f4402 100644 (file)
@@ -203,7 +203,7 @@ DeclProc(type)
                df->for_node = MkLeaf(Name, &dot);
                sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text);
                df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1));
-               C_exp(df->for_name);
+               if (CurrVis == Defined->mod_vis) C_exp(df->for_name);
                open_scope(OPENSCOPE);
        }
        else {
@@ -292,6 +292,51 @@ DefInFront(df)
        }
 }
 
+struct def *
+DefineLocalModule(id)
+       struct idf *id;
+{
+       /*      Create a definition for a local module. Also give it
+               a name to be used for code generation.
+       */
+       register struct def *df = define(id, CurrentScope, D_MODULE);
+       register struct type *tp;
+       register struct scope *sc;
+       static int modulecount = 0;
+       char buf[256];
+       extern char *sprint();
+       extern int proclevel;
+
+       sprint(buf, "_%d%s", ++modulecount, id->id_text);
+
+       if (!df->mod_vis) {     
+               /* We never saw the name of this module before. Create a
+                  scope for it.
+               */
+               open_scope(CLOSEDSCOPE);
+               df->mod_vis = CurrVis;
+       }
+
+       CurrVis = df->mod_vis;
+
+       sc = CurrentScope;
+       sc->sc_level = proclevel;
+       sc->sc_definedby = df;
+       sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
+
+       /* Create a type for it
+       */
+       df->df_type = tp = standard_type(T_RECORD, 0, (arith) 0);
+       tp->rec_scope = sc;
+
+       /* Generate code that indicates that the initialization procedure
+          for this module is local.
+       */
+       C_inp(buf);
+
+       return df;
+}
+
 #ifdef DEBUG
 PrDef(df)
        register struct def *df;
index 3cde10d..1a325fb 100644 (file)
@@ -25,7 +25,6 @@ static char *RcsId = "$Header$";
 #include       "node.h"
 
 extern int     proclevel;
-struct desig   Desig;
 struct desig   InitDesig = {DSG_INIT, 0, 0};
 
 CodeValue(ds, size)
@@ -225,6 +224,7 @@ CodeVarDesig(df, ds)
        */
        assert(ds->dsg_kind == DSG_INIT);
 
+       df->df_flags |= D_USED;
        if (df->var_addrgiven) {
                /* the programmer specified an address in the declaration of
                   the variable. Generate code to push the address.
@@ -232,7 +232,6 @@ CodeVarDesig(df, ds)
                CodeConst(df->var_off, pointer_size);
                ds->dsg_kind = DSG_PLOADED;
                ds->dsg_offset = 0;
-               df->df_flags |= D_NOREG;
                return;
        }
 
@@ -243,7 +242,6 @@ CodeVarDesig(df, ds)
                ds->dsg_name = df->var_name;
                ds->dsg_offset = 0;
                ds->dsg_kind = DSG_FIXED;
-               df->df_flags |= D_NOREG;
                return;
        }
 
@@ -251,6 +249,8 @@ CodeVarDesig(df, ds)
                /* the variable is local to a statically enclosing procedure.
                */
                assert(proclevel > sc->sc_level);
+
+               df->df_flags |= D_NOREG;
                if (df->df_flags & (D_VARPAR|D_VALPAR)) {
                        /* value or var parameter
                        */
@@ -269,7 +269,6 @@ CodeVarDesig(df, ds)
                else    C_lxl((arith) (proclevel - sc->sc_level));
                ds->dsg_kind = DSG_PLOADED;
                ds->dsg_offset = df->var_off;
-               df->df_flags |= D_NOREG;
                return;
        }
 
index ac2f376..a7c1c73 100644 (file)
@@ -50,6 +50,6 @@ struct withdesig {
 };
 
 extern struct withdesig        *WithDesigs;
-extern struct desig    Desig, InitDesig;
+extern struct desig    InitDesig;
 
 #define NO_LABEL       ((label) 0)
index 6184d23..04d4dda 100644 (file)
@@ -116,6 +116,7 @@ EnterVarList(Idlist, type, local)
                        /* An address was supplied
                        */
                        df->var_addrgiven = 1;
+                       df->df_flags |= D_NOREG;
                        if (idlist->nd_left->nd_type != card_type) {
 node_error(idlist->nd_left,"Illegal type for address");
                        }
@@ -137,9 +138,12 @@ node_error(idlist->nd_left,"Illegal type for address");
                        sprint(buf,"%s_%s", sc->sc_scope->sc_name,
                                            df->df_idf->id_text);
                        df->var_name = Salloc(buf, (unsigned)(strlen(buf)+1));
+                       df->df_flags |= D_NOREG;
 
                        if (DefinitionModule) {
-                               C_exa_dnam(df->var_name);
+                               if (sc == Defined->mod_vis) {
+                                       C_exa_dnam(df->var_name);
+                               }
                        }
                        else {
                                C_ina_dnam(df->var_name);
@@ -163,11 +167,16 @@ EnterParamList(ppr, Idlist, type, VARp, off)
        register struct paramlist *pr;
        register struct def *df;
        register struct node *idlist = Idlist;
+       static struct paramlist *last;
 
        for ( ; idlist; idlist = idlist->next) {
                pr = new_paramlist();
-               pr->next = *ppr;
-               *ppr = pr;
+               pr->next = 0;
+               if (!*ppr) {
+                       *ppr = pr;
+               }
+               else    last->next = pr;
+               last = pr;
                df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
                pr->par_def = df;
                df->df_type = type;
@@ -188,7 +197,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
        FreeNode(Idlist);
 }
 
-static
+STATIC
 DoImport(df, scope)
        register struct def *df;
        struct scope *scope;
@@ -222,7 +231,7 @@ DoImport(df, scope)
        }
 }
 
-static struct scopelist *
+STATIC struct scopelist *
 ForwModule(df, idn)
        register struct def *df;
        struct node *idn;
@@ -248,7 +257,7 @@ ForwModule(df, idn)
        return vis;
 }
 
-static struct def *
+STATIC struct def *
 ForwDef(ids, scope)
        register struct node *ids;
        struct scope *scope;
@@ -351,7 +360,7 @@ EnterFromImportList(Idlist, Fromid, local)
        register struct def *df;
        struct scopelist *vis = enclosing(CurrVis);
        int forwflag = 0;
-       extern struct def *lookfor(), *GetDefinitionModule();
+       extern struct def *GetDefinitionModule();
 
        if (local) {
                df = lookfor(Fromid, vis, 0);
@@ -412,7 +421,7 @@ EnterImportList(Idlist, local)
        register struct node *idlist = Idlist;
        register struct def *df;
        struct scopelist *vis = enclosing(CurrVis);
-       extern struct def *lookfor(), *GetDefinitionModule();
+       extern struct def *GetDefinitionModule();
 
        for (; idlist; idlist = idlist->next) {
                if (local) df = ForwDef(idlist, vis->sc_scope);
index bfdfe42..3adfc16 100644 (file)
@@ -18,19 +18,17 @@ static char *RcsId = "$Header$";
 #include       "node.h"
 #include       "const.h"
 #include       "type.h"
+#include       "chk_expr.h"
 }
 
-number(struct node **p;)
-{
-       struct type *tp;
-} :
+number(struct node **p;) :
 [
        %default
-       INTEGER         { tp = toktype; }
+       INTEGER
 |
-       REAL            { tp = real_type; }
+       REAL
 ]                      { *p = MkLeaf(Value, &dot);
-                         (*p)->nd_type = tp;
+                         (*p)->nd_type = toktype;
                        }
 ;
 
index a150d79..12775cb 100644 (file)
@@ -16,8 +16,6 @@ static char *RcsId = "$Header$";
 #include       "LLlex.h"
 #include       "node.h"
 
-extern struct def      *MkDef();
-
 struct def *
 lookup(id, scope)
        register struct idf *id;
index d28f4ef..d3f00ba 100644 (file)
@@ -15,7 +15,7 @@ static char *RcsId = "$Header$";
 #include       "node.h"
 
 match_id(id1, id2)
-       struct idf *id1, *id2;
+       register struct idf *id1, *id2;
 {
        /*      Check that identifiers id1 and id2 are equal. If they
                are not, check that we did'nt generate them in the
@@ -45,7 +45,7 @@ gen_anon_idf()
 }
 
 id_not_declared(id)
-       struct node *id;
+       register struct node *id;
 {
        /*      The identifier "id" is not declared. If it is not generated,
                give an error message
index ca2bf22..a5e8386 100644 (file)
@@ -19,6 +19,7 @@ struct node {
 #define Def    9               /* an identified name */
 #define Stat   10              /* a statement */
 #define Link   11
+                               /* do NOT change the order or the numbers!!! */
        struct type *nd_type;   /* type of this node */
        struct token nd_token;
 #define nd_set         nd_token.tk_data.tk_set
index c940e42..f8ea57b 100644 (file)
@@ -64,11 +64,17 @@ FreeNode(nd)
        free_node(nd);
 }
 
+NodeCrash(expp)
+       struct node *expp;
+{
+       crash("Illegal node %d", expp->nd_class);
+}
+
 #ifdef DEBUG
 
 extern char *symbol2str();
 
-static
+STATIC
 printnode(nd)
        register struct node *nd;
 {
index 32cba66..9ee7cec 100644 (file)
@@ -42,36 +42,13 @@ static  char *RcsId = "$Header$";
 ModuleDeclaration
 {
        struct idf *id;
-       register struct def *df;
-       extern int proclevel;
-       static int modulecount = 0;
-       char buf[256];
+       struct def *df;
        struct node *nd;
        struct node *exportlist = 0;
        int qualified;
-       extern char *sprint();
 } :
-       MODULE IDENT    {
-                         id = dot.TOK_IDF;
-                         df = define(id, CurrentScope, D_MODULE);
-
-                         if (!df->mod_vis) {   
-                               open_scope(CLOSEDSCOPE);
-                               df->mod_vis = CurrVis;
-                         }
-                         else {
-                               CurrVis = df->mod_vis;
-                               CurrentScope->sc_level = proclevel;
-                         }
-                         CurrentScope->sc_definedby = df;
-
-                         df->df_type = standard_type(T_RECORD, 0, (arith) 0);
-                         df->df_type->rec_scope = df->mod_vis->sc_scope;
-                         sprint(buf, "_%d%s", ++modulecount, id->id_text);
-                         CurrentScope->sc_name =
-                               Salloc(buf, (unsigned) (strlen(buf) + 1));
-                         if (! proclevel) C_ina_dnam(&buf[1]);
-                         C_inp(buf);
+       MODULE IDENT    { id = dot.TOK_IDF;
+                         df = DefineLocalModule(id);
                        }
        priority(&(df->mod_priority))?
        ';'
@@ -92,7 +69,7 @@ priority(arith *pprio;)
        struct node *nd;
 } :
        '[' ConstExpression(&nd) ']'
-                       { if (!(nd->nd_type->tp_fund & T_INTORCARD)) {
+                       { if (!(nd->nd_type->tp_fund & T_CARDINAL)) {
                                node_error(nd, "Illegal priority");
                          }
                          *pprio = nd->nd_INT;
@@ -141,13 +118,12 @@ DefinitionModule
        int dummy;
 } :
        DEFINITION
-       MODULE IDENT    { 
-                         id = dot.TOK_IDF;
+       MODULE IDENT    { id = dot.TOK_IDF;
                          df = define(id, GlobalScope, D_MODULE);
-                         if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
                          if (!Defined) Defined = df;
-                         df->mod_vis = CurrVis;
+                         if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
                          CurrentScope->sc_name = id->id_text;
+                         df->mod_vis = CurrVis;
                          df->df_type = standard_type(T_RECORD, 0, (arith) 0);
                          df->df_type->rec_scope = df->mod_vis->sc_scope;
                          DefinitionModule++;
@@ -222,8 +198,7 @@ ProgramModule
        struct node *nd;
 } :
        MODULE
-       IDENT   { 
-                 id = dot.TOK_IDF;
+       IDENT   { id = dot.TOK_IDF;
                  if (state == IMPLEMENTATION) {
                        df = GetDefinitionModule(id);
                        CurrVis = df->mod_vis;
@@ -232,11 +207,11 @@ ProgramModule
                  }
                  else {
                        df = define(id, CurrentScope, D_MODULE);
-                       Defined = df;
                        open_scope(CLOSEDSCOPE);
                        df->mod_vis = CurrVis;
                        CurrentScope->sc_name = id->id_text;
                  }
+                 Defined = df;
                  CurrentScope->sc_definedby = df;
                }
        priority(&(df->mod_priority))?
index f1731fb..2cd6d34 100644 (file)
@@ -90,7 +90,7 @@ Forward(tk, ptp)
        CurrentScope->sc_forw = f;
 }
 
-static
+STATIC
 chk_proc(df)
        register struct def *df;
 {
@@ -108,7 +108,7 @@ node_error(df->for_node, "procedure \"%s\" not defined", df->df_idf->id_text);
        }
 }
 
-static
+STATIC
 chk_forw(pdf)
        register struct def **pdf;
 {
@@ -153,7 +153,7 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared",
        }
 }
 
-static
+STATIC
 rem_forwards(fo)
        struct forwards *fo;
 {
@@ -161,7 +161,6 @@ rem_forwards(fo)
        */
        register struct forwards *f;
        register struct def *df;
-       struct def *lookfor();
 
        while (f = fo) {
                df = lookfor(&(f->fo_tok), CurrVis, 1);
@@ -181,11 +180,10 @@ Reverse(pdf)
        /*      Reverse the order in the list of definitions in a scope.
                This is neccesary because this list is built in reverse.
                Also, while we're at it, remove uninteresting definitions
-               from this list. The only interesting definitions are:
-               D_MODULE, D_PROCEDURE, and D_PROCHEAD.
+               from this list.
        */
        register struct def *df, *df1;
-#define INTERESTING D_MODULE|D_PROCEDURE|D_PROCHEAD
+#define INTERESTING D_MODULE|D_PROCEDURE|D_PROCHEAD|D_VARIABLE
 
        df = 0;
        df1 = *pdf;
@@ -217,7 +215,6 @@ close_scope(flag)
        register struct scope *sc = CurrentScope;
 
        assert(sc != 0);
-       DO_DEBUG(1, debug("Closing a scope"));
 
        if (flag) {
                if (sc->sc_forw) rem_forwards(sc->sc_forw);
index aef6e22..62fd0a9 100644 (file)
@@ -83,13 +83,17 @@ ProcedureCall:
 
 StatementSequence(register struct node **pnd;)
 {
+       struct node *nd;
 } :
        statement(pnd)
        [
-               ';'     { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
-                         pnd = &((*pnd)->nd_right);
+               ';' statement(&nd)
+                       { if (nd) {
+                               *pnd = MkNode(Link, *pnd, nd, &dot);
+                               (*pnd)->nd_symb = ';';
+                               pnd = &((*pnd)->nd_right);
+                         }
                        }
-               statement(pnd)
        ]*
 ;
 
index ae272a6..98595b1 100644 (file)
@@ -21,9 +21,6 @@ static char *RcsId = "$Header$";
 #include       "const.h"
 #include       "scope.h"
 
-/*     To be created dynamically in main() from defaults or from command
-       line parameters.
-*/
 int
        word_align = AL_WORD,
        int_align = AL_INT,
@@ -96,38 +93,34 @@ construct_type(fund, tp)
 
        switch (fund)   {
        case T_PROCEDURE:
+               if (tp && !returntype(tp)) {
+                       error("illegal procedure result type");
+               }
+               /* Fall through */
        case T_POINTER:
        case T_HIDDEN:
                dtp->tp_align = pointer_align;
                dtp->tp_size = pointer_size;
-               dtp->next = tp;
-               if (fund == T_PROCEDURE && tp) {
-                       if (! returntype(tp)) {
-                               error("illegal procedure result type");
-                       }
-               }
                break;
 
        case T_SET:
                dtp->tp_align = word_align;
-               dtp->next = tp;
                break;
 
        case T_ARRAY:
                dtp->tp_align = tp->tp_align;
-               dtp->next = tp;
                break;
 
        case T_SUBRANGE:
                dtp->tp_align = tp->tp_align;
                dtp->tp_size = tp->tp_size;
-               dtp->next = tp;
                break;
 
        default:
                crash("funny type constructor");
        }
 
+       dtp->next = tp;
        return dtp;
 }
 
@@ -206,8 +199,11 @@ InitTypes()
        address_type = construct_type(T_POINTER, word_type);
 
        /* create BITSET type
+          TYPE BITSET = SET OF [0..W-1];
+          The subrange is a subrange of type cardinal, because the lower bound
+          is a non-negative integer (See Rep. 6.3)
        */
-       tp = construct_type(T_SUBRANGE, int_type);
+       tp = construct_type(T_SUBRANGE, card_type);
        tp->sub_lb = 0;
        tp->sub_ub = word_size * 8 - 1;
        bitset_type = set_type(tp);
@@ -229,7 +225,7 @@ chk_basesubrange(tp, base)
 
        if (base->tp_fund == T_SUBRANGE) {
                /* Check that the bounds of "tp" fall within the range
-                  of "base"
+                  of "base".
                */
                if (base->sub_lb > tp->sub_lb || base->sub_ub < tp->sub_ub) {
                        error("Base type has insufficient range");
@@ -246,7 +242,7 @@ chk_basesubrange(tp, base)
                error("Illegal base for a subrange");
        }
        else if (base == int_type && tp->next == card_type &&
-                (tp->sub_ub > max_int || tp->sub_ub)) {
+                (tp->sub_ub > max_int || tp->sub_ub < 0)) {
                error("Upperbound to large for type INTEGER");
        }
        else if (base != tp->next && base != int_type) {
@@ -269,7 +265,7 @@ subr_type(lb, ub)
        register struct type *tp = lb->nd_type, *res;
 
        if (!TstCompat(lb->nd_type, ub->nd_type)) {
-               node_error(ub, "Types of subrange bounds not compatible");
+               node_error(ub, "Types of subrange bounds not equal");
                return error_type;
        }
 
@@ -306,32 +302,33 @@ subr_type(lb, ub)
        return res;
 }
 
-label
-getrck(tp)
+genrck(tp)
        register struct type *tp;
 {
        /*      generate a range check descriptor for type "tp" when
-               neccessary. Return its label
+               neccessary. Return its label.
        */
+       arith lb, ub;
+       label ol, l;
 
-       assert(bounded(tp));
+       getbounds(tp, &lb, &ub);
 
        if (tp->tp_fund == T_SUBRANGE) {
-               if (tp->sub_rck == (label) 0) {
-                       tp->sub_rck = data_label();
-                       C_df_dlb(tp->sub_rck);
-                       C_rom_cst(tp->sub_lb);
-                       C_rom_cst(tp->sub_ub);
+               if (!(ol = tp->sub_rck)) {
+                       tp->sub_rck = l = data_label();
                }
-               return tp->sub_rck;
        }
-       if (tp->enm_rck == (label) 0) {
-               tp->enm_rck = data_label();
-               C_df_dlb(tp->enm_rck);
-               C_rom_cst((arith) 0);
-               C_rom_cst((arith) (tp->enm_ncst - 1));
+       else if (!(ol = tp->enm_rck)) {
+               tp->enm_rck = l = data_label();
+       }
+       if (!ol) {
+               ol = l;
+               C_df_dlb(ol);
+               C_rom_cst(lb);
+               C_rom_cst(ub);
        }
-       return tp->enm_rck;
+       C_lae_dlb(ol, (arith) 0);
+       C_rck(word_size);
 }
 
 getbounds(tp, plo, phi)
@@ -352,6 +349,7 @@ getbounds(tp, plo, phi)
                *phi = tp->enm_ncst - 1;
        }
 }
+
 struct type *
 set_type(tp)
        register struct type *tp;
@@ -361,26 +359,20 @@ set_type(tp)
        */
        arith lb, ub;
 
-       if (tp->tp_fund == T_SUBRANGE) {
-               if ((lb = tp->sub_lb) < 0 || (ub = tp->sub_ub) > MAXSET - 1) {
-                       error("Set type limits exceeded");
-                       return error_type;
-               }
-       }
-       else if (tp->tp_fund == T_ENUMERATION || tp == char_type) {
-               lb = 0;
-               if ((ub = tp->enm_ncst - 1) > MAXSET - 1) {
-                       error("Set type limits exceeded");
-                       return error_type;
-               }
-       }
-       else {
+       if (! bounded(tp)) {
                error("illegal base type for set");
                return error_type;
        }
 
+       getbounds(tp, &lb, &ub);
+
+       if (lb < 0 || ub > MAXSET-1) {
+               error("Set type limits exceeded");
+               return error_type;
+       }
+
        tp = construct_type(T_SET, tp);
-       tp->tp_size = WA(((ub - lb) + 7)/8);
+       tp->tp_size = WA(((ub - lb) + 8)/8);
        return tp;
 }
 
@@ -412,47 +404,30 @@ ArraySizes(tp)
        */
        register struct type *index_type = tp->next;
        register struct type *elem_type = tp->arr_elem;
+       arith lo, hi;
 
        tp->arr_elsize = ArrayElSize(elem_type);
        tp->tp_align = elem_type->tp_align;
 
        /* check index type
        */
-       if (! (index_type->tp_fund & T_INDEX)) {
+       if (! bounded(index_type)) {
                error("Illegal index type");
                tp->tp_size = 0;
                return;
        }
 
-       /* find out HIGH, LOW and size of ARRAY
+       getbounds(index_type, &lo, &hi);
+
+       tp->tp_size = WA((hi - lo + 1) * tp->arr_elsize);
+
+       /* generate descriptor and remember label.
        */
        tp->arr_descr = data_label();
        C_df_dlb(tp->arr_descr);
-
-       switch(index_type->tp_fund) {
-       case T_SUBRANGE:
-               tp->tp_size = tp->arr_elsize *
-                       (index_type->sub_ub - index_type->sub_lb + 1);
-               C_rom_cst(index_type->sub_lb);
-               C_rom_cst(index_type->sub_ub - index_type->sub_lb);
-               break;
-
-       case T_CHAR:
-       case T_ENUMERATION:
-               tp->tp_size = tp->arr_elsize * index_type->enm_ncst;
-               C_rom_cst((arith) 0);
-               C_rom_cst((arith) (index_type->enm_ncst - 1));
-               break;
-
-       default:
-               crash("Funny index type");
-       }
-
+       C_rom_cst(lo);
+       C_rom_cst(hi - lo);
        C_rom_cst(tp->arr_elsize);
-       tp->tp_size = WA(tp->tp_size);
-
-       /* ??? overflow checking ???
-       */
 }
 
 FreeType(tp)
index a68f48f..ae214d5 100644 (file)
@@ -12,6 +12,7 @@ static char *RcsId = "$Header$";
 
 #include       <em_arith.h>
 #include       <em_label.h>
+#include       <em_reg.h>
 #include       <assert.h>
 
 #include       "def.h"
@@ -24,6 +25,7 @@ static char *RcsId = "$Header$";
 #include       "desig.h"
 #include       "f_info.h"
 #include       "idf.h"
+#include       "chk_expr.h"
 
 extern arith   NewPtr();
 extern arith   NewInt();
@@ -49,7 +51,7 @@ data_label()
        return ++datalabel;
 }
 
-static
+STATIC
 DoProfil()
 {
        static label    filename_label = 0;
@@ -119,16 +121,14 @@ WalkModule(module)
                struct node *nd;
 
                if (state == IMPLEMENTATION) {
-                       label l1 = data_label(), l2 = text_label();
+                       label l1 = data_label();
                        /* we don't actually prevent recursive calls,
                           but do nothing if called recursively
                        */
                        C_df_dlb(l1);
                        C_bss_cst(word_size, (arith) 0, 1);
                        C_loe_dlb(l1, (arith) 0);
-                       C_zeq(l2);
-                       C_ret((arith) 0);
-                       C_df_ilb(l2);
+                       C_zne((label) 1);
                        C_loc((arith) 1);
                        C_ste_dlb(l1, (arith) 0);
                }
@@ -159,7 +159,8 @@ WalkProcedure(procedure)
        */
        struct scopelist *vis = CurrVis;
        register struct scope *sc;
-       register struct type *res_type;
+       register struct type *tp;
+       register struct paramlist *param;
 
        proclevel++;
        CurrVis = procedure->prc_vis;
@@ -177,19 +178,20 @@ WalkProcedure(procedure)
        MkCalls(sc->sc_def);
        return_expr_occurred = 0;
        instructionlabel = 2;
-       func_type = res_type = procedure->df_type->next;
-       if (! returntype(res_type)) {
+       func_type = tp = procedure->df_type->next;
+       if (! returntype(tp)) {
                node_error(procedure->prc_body, "illegal result type");
        }
        WalkNode(procedure->prc_body, (label) 0);
        C_df_ilb((label) 1);
-       if (res_type) {
+       if (tp) {
                if (! return_expr_occurred) {
 node_error(procedure->prc_body,"function procedure does not return a value");
                }
-               C_ret(WA(res_type->tp_size));
+               C_ret(WA(tp->tp_size));
        }
        else    C_ret((arith) 0);
+       RegisterMessages(sc->sc_def);
        C_end(-sc->sc_off);
        TmpClose();
        CurrVis = vis;
@@ -257,7 +259,6 @@ WalkStat(nd, lab)
        */
        register struct node *left = nd->nd_left;
        register struct node *right = nd->nd_right;
-       register struct desig *pds = &Desig;
 
        if (!nd) {
                /* Empty statement
@@ -385,9 +386,10 @@ WalkStat(nd, lab)
                {
                        struct scopelist link;
                        struct withdesig wds;
+                       struct desig ds;
                        arith tmp = 0;
 
-                       WalkDesignator(left);
+                       WalkDesignator(left, &ds);
                        if (left->nd_type->tp_fund != T_RECORD) {
                                node_error(left, "record variable expected");
                                break;
@@ -396,19 +398,21 @@ WalkStat(nd, lab)
                        wds.w_next = WithDesigs;
                        WithDesigs = &wds;
                        wds.w_scope = left->nd_type->rec_scope;
-                       if (pds->dsg_kind != DSG_PFIXED) {
+                       if (ds.dsg_kind != DSG_PFIXED) {
                                /* In this case, we use a temporary variable
                                */
-                               CodeAddress(pds);
-                               pds->dsg_kind = DSG_FIXED;
-                               /* Only for the store ... */
-                               pds->dsg_offset = tmp = NewPtr();
-                               pds->dsg_name = 0;
-                               CodeStore(pds, pointer_size);
-                               pds->dsg_kind = DSG_PFIXED;
+                               CodeAddress(&ds);
+                               ds.dsg_kind = DSG_FIXED;
+                               /* Create a designator structure for the
+                                  temporary.
+                               */
+                               ds.dsg_offset = tmp = NewPtr();
+                               ds.dsg_name = 0;
+                               CodeStore(&ds, pointer_size);
+                               ds.dsg_kind = DSG_PFIXED;
                                /* the record is indirectly available */
                        }
-                       wds.w_desig = *pds;
+                       wds.w_desig = ds;
                        link.sc_scope = wds.w_scope;
                        link.next = CurrVis;
                        CurrVis = &link;
@@ -439,7 +443,7 @@ node_error(right, "type incompatibility in RETURN statement");
                break;
 
        default:
-               assert(0);
+               crash("(WalkStat)");
        }
 }
 
@@ -450,6 +454,7 @@ ExpectBool(nd, true_label, false_label)
        /*      "nd" must indicate a boolean expression. Check this and
                generate code to evaluate the expression.
        */
+       struct desig ds;
 
        if (!chk_expr(nd)) return;
 
@@ -457,8 +462,8 @@ ExpectBool(nd, true_label, false_label)
                node_error(nd, "boolean expression expected");
        }
 
-       Desig = InitDesig;
-       CodeExpr(nd, &Desig,  true_label, false_label);
+       ds = InitDesig;
+       CodeExpr(nd, &ds,  true_label, false_label);
 }
 
 WalkExpr(nd)
@@ -474,8 +479,9 @@ WalkExpr(nd)
        CodePExpr(nd);
 }
 
-WalkDesignator(nd)
+WalkDesignator(nd, ds)
        struct node *nd;
+       struct desig *ds;
 {
        /*      Check designator and generate code for it
        */
@@ -484,8 +490,8 @@ WalkDesignator(nd)
 
        if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return;
 
-       Desig = InitDesig;
-       CodeDesig(nd, &Desig);
+       *ds = InitDesig;
+       CodeDesig(nd, ds);
 }
 
 DoForInit(nd, left)
@@ -527,13 +533,13 @@ DoAssign(nd, left, right)
        register struct node *left, *right;
 {
        /* May we do it in this order (expression first) ??? */
-       struct desig ds;
+       struct desig dsl, dsr;
 
        if (!chk_expr(right)) return;
        if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return;
        TryToString(right, left->nd_type);
-       Desig = InitDesig;
-       CodeExpr(right, &Desig, NO_LABEL, NO_LABEL);
+       dsr = InitDesig;
+       CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);
 
        if (! TstAssCompat(left->nd_type, right->nd_type)) {
                node_error(nd, "type incompatibility in assignment");
@@ -541,17 +547,44 @@ DoAssign(nd, left, right)
        }
 
        if (complex(right->nd_type)) {
-               CodeAddress(&Desig);
+               CodeAddress(&dsr);
        }
        else {
-               CodeValue(&Desig, right->nd_type->tp_size);
+               CodeValue(&dsr, right->nd_type->tp_size);
                CheckAssign(left->nd_type, right->nd_type);
        }
-       ds = Desig;
-       Desig = InitDesig;
-       CodeDesig(left, &Desig);
+       dsl = InitDesig;
+       CodeDesig(left, &dsl);
+
+       CodeAssign(nd, &dsr, &dsl);
+}
+
+RegisterMessages(df)
+       register struct def *df;
+{
+       struct type *tp;
 
-       CodeAssign(nd, &ds, &Desig);
+       for (; df; df = df->df_nextinscope) {
+               if (df->df_kind == D_VARIABLE && !(df->df_flags & D_NOREG)) {
+                       /* Examine type and size
+                       */
+                       tp = df->df_type;
+                       if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
+                       if ((tp->tp_fund & T_NUMERIC) &&
+                            tp->tp_size <= dword_size) {
+                               C_ms_reg(df->var_off,
+                                        tp->tp_size,
+                                        tp->tp_fund == T_REAL ?
+                                           reg_float : reg_any,
+                                        0);
+                       }
+                       else if ((df->df_flags & D_VARPAR) ||
+                                tp->tp_fund == T_POINTER) {
+                               C_ms_reg(df->var_off, pointer_size,
+                                        reg_pointer, 0);
+                       }
+               }
+       }
 }
 
 #ifdef DEBUG