newer version with bug fixes
authorceriel <none@none>
Tue, 26 Aug 1986 14:33:24 +0000 (14:33 +0000)
committerceriel <none@none>
Tue, 26 Aug 1986 14:33:24 +0000 (14:33 +0000)
14 files changed:
lang/m2/comp/Makefile
lang/m2/comp/Parameters
lang/m2/comp/chk_expr.c
lang/m2/comp/code.c
lang/m2/comp/cstoper.c
lang/m2/comp/declar.g
lang/m2/comp/def.c
lang/m2/comp/defmodule.c
lang/m2/comp/enter.c
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/type.c
lang/m2/comp/typequiv.c
lang/m2/comp/walk.c

index dda87c5..2540736 100644 (file)
@@ -1,16 +1,16 @@
 # make modula-2 "compiler"
 # $Header$
-EMDIR =                /usr/em
+EMDIR =                /usr/ceriel/em
 MHDIR =                $(EMDIR)/modules/h
 PKGDIR =       $(EMDIR)/modules/pkg
 LIBDIR =       $(EMDIR)/modules/lib
-LLGEN =                $(EMDIR)/util/LLgen/src/LLgen
+LLGEN =                $(EMDIR)/bin/LLgen
 
 INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR)
 
 LSRC = tokenfile.g program.g declar.g expression.g statement.g
 CC =   cc
-LLGENOPTIONS = -d
+LLGENOPTIONS =
 PROFILE = 
 CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
 LINTFLAGS = -DSTATIC= -DNORCSID
@@ -23,7 +23,7 @@ COBJ =        LLlex.o LLmessage.o char.o error.o main.o \
        code.o tmpvar.o lookup.o
 OBJ =  $(COBJ) $(LOBJ) Lpars.o
 
-# Keep the next three entries up to date!
+# Keep the next entries up to date!
 GENCFILES=     tokenfile.c \
        program.c declar.c expression.c statement.c \
        symbol2str.c char.c Lpars.c casestat.c tmpvar.c scope.c
@@ -32,12 +32,42 @@ GENHFILES=  errout.h\
        idfsize.h numsize.h strsize.h target_sizes.h debug.h\
        inputtype.h maxset.h ndir.h density.h\
        def.h type.h Lpars.h node.h
+HFILES=                LLlex.h\
+       chk_expr.h class.h const.h desig.h f_info.h idf.h\
+       input.h main.h misc.h scope.h standards.h tokenname.h\
+       walk.h $(GENHFILES)
 #
 GENFILES = $(GENGFILES) $(GENCFILES) $(GENHFILES)
-all:
-       make hfiles
-       make LLfiles
-       make main
+
+all:   Cfiles
+       sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make main ; else sh Resolve main ; fi'
+       @rm -f nmclash.o a.out
+
+clean:
+       rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab cclash.o cid.o cclash cid
+       (cd .. ; rm -rf Xsrc)
+
+lint:  Cfiles
+       sh -c `if $(CC) nmclash.c > /dev/null 2>&1 ; then make Xlint ; else sh Resolve Xlint ; fi'
+       @rm -f nmclash.o a.out
+
+mkdep: mkdep.o
+       $(CC) -o mkdep mkdep.o
+
+cclash:        cclash.o
+       $(CC) -o cclash cclash.o
+
+cid:   cid.o
+       $(CC) -o cid cid.o
+
+# entry points not to be used directly
+
+Xlint:
+       lint $(INCLUDES) $(LINTFLAGS) `./sources $(OBJ)`
+
+Cfiles:        hfiles LLfiles $(GENHFILES) $(GENCFILES)
+       ./sources $(OBJ) > Cfiles
+       sh -c 'for i in $(HFILES) ; do echo $$i ; done >> Cfiles'
 
 LLfiles:       $(LSRC)
        $(LLGEN) $(LLGENOPTIONS) $(LSRC)
@@ -47,47 +77,48 @@ hfiles:     Parameters make.hfiles
        make.hfiles Parameters
        touch hfiles
 
-main:  $(OBJ) Makefile
-       $(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(LIBDIR)/libeme.a $(LIBDIR)/input.a $(LIBDIR)/assert.a $(LIBDIR)/alloc.a $(LIBDIR)/malloc.o $(LIBDIR)/libprint.a $(LIBDIR)/libstr.a $(LIBDIR)/libsystem.a -o main
-       size main
-
-clean:
-       rm -f $(OBJ) $(GENFILES) LLfiles hfiles
-
-lint:  LLfiles hfiles
-       lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)`
+main:  $(OBJ) ../src/Makefile
+       $(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(LIBDIR)/libemk.a $(LIBDIR)/input.a $(LIBDIR)/assert.a $(LIBDIR)/alloc.a $(LIBDIR)/malloc.o $(LIBDIR)/libprint.a $(LIBDIR)/libstr.a $(LIBDIR)/libsystem.a -o ../src/main
+       size ../src/main
 
 tokenfile.g:   tokenname.c make.tokfile
        make.tokfile <tokenname.c >tokenfile.g
 
-symbol2str.c:  tokenname.c make.tokcase
-       make.tokcase <tokenname.c >symbol2str.c
+symbol2str.c:  ../src/tokenname.c ../src/make.tokcase
+       ../src/make.tokcase <../src/tokenname.c >symbol2str.c
+
+def.h:         ../src/def.H ../src/make.allocd
+               ../src/make.allocd < ../src/def.H > def.h
+
+type.h:                ../src/type.H ../src/make.allocd
+               ../src/make.allocd < ../src/type.H > type.h
 
-def.h:         def.H make.allocd
-type.h:                type.H make.allocd
-node.h:                node.H make.allocd
-scope.c:       scope.C make.allocd
-tmpvar.c:      tmpvar.C make.allocd
-casestat.c:    casestat.C make.allocd
+node.h:                ../src/node.H ../src/make.allocd
+               ../src/make.allocd < ../src/node.H > node.h
 
-char.c: char.tab tab
-       ./tab -fchar.tab >char.c
+scope.c:       ../src/scope.C ../src/make.allocd
+               ../src/make.allocd < ../src/scope.C > scope.c
 
-tab: 
-       $(CC) tab.c -o tab
+tmpvar.c:      ../src/tmpvar.C ../src/make.allocd
+               ../src/make.allocd < ../src/tmpvar.C > tmpvar.c
 
-depend:
+casestat.c:    ../src/casestat.C ../src/make.allocd
+               ../src/make.allocd < ../src/casestat.C > casestat.c
+
+char.c: ../src/char.tab ../src/tab
+       ../src/tab -fchar.tab >char.c
+
+../src/tab: 
+       $(CC) ../src/tab.c -o ../src/tab
+
+depend:        mkdep
        sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
        echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
-       /user1/erikb/bin/mkdep `sources $(OBJ)` |\
+       ./mkdep `./sources $(OBJ)` |\
                sed 's/\.c:/\.o:/' >> Makefile.new
        mv Makefile Makefile.old
        mv Makefile.new Makefile
 
-.SUFFIXES:     .H .h .C
-.H.h .C.c :
-       make.allocd < $< > $@
-
 #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
 LLlex.o: LLlex.h Lpars.h class.h const.h debug.h f_info.h idf.h idfsize.h input.h inputtype.h numsize.h strsize.h type.h
 LLmessage.o: LLlex.h Lpars.h idf.h
@@ -116,7 +147,7 @@ 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 main.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
+program.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h main.h node.h scope.h type.h
 declar.o: LLlex.h Lpars.h chk_expr.h debug.h def.h idf.h main.h misc.h node.h scope.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
index acda856..a1d3ff8 100644 (file)
@@ -5,7 +5,7 @@
 
 
 !File: idfsize.h
-#define        IDFSIZE 30      /* maximum significant length of an identifier  */
+#define        IDFSIZE 128     /* maximum significant length of an identifier  */
 
 
 !File: numsize.h
index 0137ec5..ae2571e 100644 (file)
@@ -132,6 +132,8 @@ ChkLinkOrName(expp)
 {
        register struct def *df;
 
+       expp->nd_type = error_type;
+
        if (expp->nd_class == Name) {
                expp->nd_def = lookfor(expp, CurrVis, 1);
                expp->nd_class = Def;
@@ -183,7 +185,7 @@ df->df_idf->id_text);
        assert(expp->nd_class == Def);
 
        df = expp->nd_def;
-       if (df == ill_df) return 0;
+       if (df->df_kind == D_ERROR) return 0;
 
        if (df->df_kind & (D_ENUM | D_CONST)) {
                if (df->df_kind == D_ENUM) {
@@ -855,7 +857,7 @@ ChkStandard(expp, left)
        case S_MIN:
                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");
+node_error(left, "illegal type in %s", std == S_MAX ? "MAX" : "MIN");
                        return 0;
                }
                expp->nd_type = left->nd_type;
@@ -961,7 +963,7 @@ ChkStandard(expp, left)
                expp->nd_type = 0;
                if (! (left = getvariable(&arg))) return 0;
                if (! (left->nd_type->tp_fund & T_DISCRETE)) {
-node_error(left, "illegal type in argument of INC or DEC");
+node_error(left,"illegal type in argument of %s",std == S_INC ? "INC" : "DEC");
                        return 0;
                }
                if (arg->nd_right) {
@@ -982,7 +984,7 @@ node_error(left, "illegal type in argument of INC or DEC");
                if (!(left = getvariable(&arg))) return 0;
                tp = left->nd_type;
                if (tp->tp_fund != T_SET) {
-node_error(arg, "EXCL and INCL expect a SET parameter");
+node_error(arg, "%s expects a SET parameter", std == S_EXCL ? "EXCL" : "INCL");
                        return 0;
                }
                if (!(left = getarg(&arg, T_DISCRETE, 0))) return 0;
index 2e62527..acfeda5 100644 (file)
@@ -201,7 +201,6 @@ CodeCoercion(t1, t2)
        if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER;
        switch(fund1) {
        case T_INTEGER:
-       case T_INTORCARD:
                switch(fund2) {
                case T_INTEGER:
                        if (t2->tp_size != t1->tp_size) {
@@ -232,11 +231,13 @@ CodeCoercion(t1, t2)
        case T_CHAR:
        case T_ENUMERATION:
        case T_CARDINAL:
+       case T_INTORCARD:
                switch(fund2) {
                case T_ENUMERATION:
                case T_CHAR:
                case T_CARDINAL:
                case T_POINTER:
+               case T_INTORCARD:
                        if (t2->tp_size > word_size) {
                                C_loc(word_size);
                                C_loc(t2->tp_size);
@@ -313,16 +314,25 @@ CodeCall(nd)
                CodeParameters(ParamList(left->nd_type), nd->nd_right);
        }
 
-       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);
+       switch(left->nd_class) {
+       case Def: {
+               register struct def *df = left->nd_def;
+
+               if (df->df_kind == D_PROCEDURE) {
+                       arith level = df->df_scope->sc_level;
+
+                       if (level > 0) {
+                               C_lxl((arith) proclevel - level);
+                       }
+                       C_cal(NameOfProc(df));
+                       break;
                }
-               C_cal(NameOfProc(left->nd_def));
-       }
-       else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) {
-               C_cal(left->nd_def->for_name);
-       }
-       else {
+               else if (df->df_kind == D_PROCHEAD) {
+                       C_cal(df->for_name);
+                       break;
+               }}
+               /* Fall through */
+       default:
                CodePExpr(left);
                C_cai();
        }
@@ -342,6 +352,7 @@ CodeParameters(param, arg)
 {
        register struct type *tp;
        register struct node *left;
+       register struct type *left_type;
        
        assert(param != 0 && arg != 0);
 
@@ -351,25 +362,31 @@ CodeParameters(param, arg)
 
        tp = TypeOfParam(param);
        left = arg->nd_left;
+       left_type = left->nd_type;
        if (IsConformantArray(tp)) {
                C_loc(tp->arr_elsize);
-               if (IsConformantArray(left->nd_type)) {
+               if (IsConformantArray(left_type)) {
                        DoHIGH(left);
-                       if (tp->arr_elem->tp_size != left->nd_type->arr_elem->tp_size) {
+                       if (tp->arr_elem->tp_size !=
+                           left_type->arr_elem->tp_size) {
                                /* This can only happen if the formal type is
                                   ARRAY OF WORD
                                */
-                               /* ??? */
+                               assert(tp->arr_elem == word_type);
+                               C_loc(left_type->arr_elem->tp_size);
+                               C_cal("_wa");
+                               C_asp(dword_size);
+                               C_lfr(word_size);
                        }
                }
                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);
+                       C_loc((left_type->tp_size+word_size-1) / word_size - 1);
                }
                else {
-                       tp = IndexType(left->nd_type);
+                       tp = IndexType(left_type);
                        if (tp->tp_fund == T_SUBRANGE) {
                                C_loc(tp->sub_ub - tp->sub_lb);
                        }
@@ -385,11 +402,11 @@ CodeParameters(param, arg)
                CodeDAddress(left);
        }
        else {
-               if (left->nd_type->tp_fund == T_STRING) {
+               if (left_type->tp_fund == T_STRING) {
                        CodePadString(left, tp->tp_size);
                }
                else CodePExpr(left);
-               CheckAssign(left->nd_type, tp);
+               CheckAssign(left_type, tp);
        }
 }
 
@@ -422,6 +439,7 @@ CodeStd(nd)
                        }
                        else    C_cal("_absd");
                }
+               C_asp(tp->tp_size);
                C_lfr(tp->tp_size);
                break;
 
@@ -447,6 +465,7 @@ CodeStd(nd)
                break;
 
        case S_ODD:
+               CodePExpr(left);
                if (tp->tp_size == word_size) {
                        C_loc((arith) 1);
                        C_and(word_size);
@@ -584,45 +603,39 @@ CheckAssign(tpl, tpr)
        }
 }
 
-Operands(leftop, rightop)
+Operands(leftop, rightop, tp)
        register struct node *leftop, *rightop;
+       struct type *tp;
 {
 
        CodePExpr(leftop);
-
-       if (rightop->nd_type->tp_fund == T_POINTER && 
-           leftop->nd_type->tp_size != pointer_size) {
-               CodeCoercion(leftop->nd_type, rightop->nd_type);
-               leftop->nd_type = rightop->nd_type;
-       }
-
+       CodeCoercion(leftop->nd_type, tp);
        CodePExpr(rightop);
+       CodeCoercion(rightop->nd_type, tp);
 }
 
 CodeOper(expr, true_label, false_label)
-       struct node *expr;      /* the expression tree itself           */
+       register struct node *expr;     /* the expression tree itself   */
        label true_label;
        label false_label;      /* labels to jump to in logical expr's  */
 {
-       register int oper = expr->nd_symb;
        register struct node *leftop = expr->nd_left;
        register struct node *rightop = expr->nd_right;
        register struct type *tp = expr->nd_type;
 
-       switch (oper)   {
+       switch (expr->nd_symb)  {
        case '+':
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch (tp->tp_fund)    {
                case T_INTEGER:
                        C_adi(tp->tp_size);
                        break;
-               case T_POINTER:
-                       C_ads(rightop->nd_type->tp_size);
-                       break;
                case T_REAL:
                        C_adf(tp->tp_size);
                        break;
+               case T_POINTER:
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_adu(tp->tp_size);
                        break;
                case T_SET:
@@ -633,24 +646,17 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case '-':
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch (tp->tp_fund)    {
                case T_INTEGER:
                        C_sbi(tp->tp_size);
                        break;
-               case T_POINTER:
-                       if (rightop->nd_type->tp_fund == T_POINTER) {
-                               C_sbs(pointer_size);
-                       }
-                       else    {
-                               C_ngi(rightop->nd_type->tp_size);
-                               C_ads(rightop->nd_type->tp_size);
-                       }
-                       break;
                case T_REAL:
                        C_sbf(tp->tp_size);
                        break;
+               case T_POINTER:
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_sbu(tp->tp_size);
                        break;
                case T_SET:
@@ -662,15 +668,14 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case '*':
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch (tp->tp_fund)    {
                case T_INTEGER:
                        C_mli(tp->tp_size);
                        break;
                case T_POINTER:
-                       CodeCoercion(rightop->nd_type, tp);
-                       /* Fall through */
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_mlu(tp->tp_size);
                        break;
                case T_REAL:
@@ -684,7 +689,7 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case '/':
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch (tp->tp_fund)    {
                case T_REAL:
                        C_dvf(tp->tp_size);
@@ -697,15 +702,14 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case DIV:
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch(tp->tp_fund)     {
                case T_INTEGER:
                        C_dvi(tp->tp_size);
                        break;
                case T_POINTER:
-                       CodeCoercion(rightop->nd_type, tp);
-                       /* Fall through */
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_dvu(tp->tp_size);
                        break;
                default:
@@ -713,15 +717,14 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case MOD:
-               Operands(leftop, rightop);
+               Operands(leftop, rightop, tp);
                switch(tp->tp_fund)     {
                case T_INTEGER:
                        C_rmi(tp->tp_size);
                        break;
                case T_POINTER:
-                       CodeCoercion(rightop->nd_type, tp);
-                       /* Fall through */
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_rmu(tp->tp_size);
                        break;
                default:
@@ -734,18 +737,17 @@ CodeOper(expr, true_label, false_label)
        case GREATEREQUAL:
        case '=':
        case '#':
-               Operands(leftop, rightop);
-               CodeCoercion(rightop->nd_type, leftop->nd_type);
-               tp = BaseType(leftop->nd_type); /* Not the result type! */
+               tp = BaseType(leftop->nd_type);
+               if (tp == intorcard_type) tp = BaseType(rightop->nd_type);
+               Operands(leftop, rightop, tp);
                switch (tp->tp_fund)    {
                case T_INTEGER:
                        C_cmi(tp->tp_size);
                        break;
                case T_HIDDEN:
                case T_POINTER:
-                       C_cmp();
-                       break;
                case T_CARDINAL:
+               case T_INTORCARD:
                        C_cmu(tp->tp_size);
                        break;
                case T_ENUMERATION:
@@ -756,19 +758,18 @@ CodeOper(expr, true_label, false_label)
                        C_cmf(tp->tp_size);
                        break;
                case T_SET:
-                       if (oper == GREATEREQUAL) {
+                       if (expr->nd_symb == GREATEREQUAL) {
                                /* A >= B is the same as A equals A + B
                                */
                                C_dup(2*tp->tp_size);
                                C_asp(tp->tp_size);
-                               C_zer(tp->tp_size);
+                               C_ior(tp->tp_size);
                        }
-                       else if (oper == LESSEQUAL) {
+                       else if (expr->nd_symb == LESSEQUAL) {
                                /* A <= B is the same as A - B = {}
                                */
                                C_com(tp->tp_size);
                                C_and(tp->tp_size);
-                               C_ior(tp->tp_size);
                                C_zer(tp->tp_size);
                        }
                        C_cms(tp->tp_size);
@@ -777,11 +778,11 @@ CodeOper(expr, true_label, false_label)
                        crash("bad type COMPARE");
                }
                if (true_label != 0)    {
-                       compare(oper, true_label);
+                       compare(expr->nd_symb, true_label);
                        C_bra(false_label);
                }
                else    {
-                       truthvalue(oper);
+                       truthvalue(expr->nd_symb);
                }
                break;
        case IN:
@@ -789,7 +790,8 @@ CodeOper(expr, true_label, false_label)
                   INN instruction expects the bit number on top of the
                   stack
                */
-               Operands(rightop, leftop);
+               CodePExpr(rightop);
+               CodePExpr(leftop);
                CodeCoercion(leftop->nd_type, word_type);
                C_inn(rightop->nd_type->tp_size);
                if (true_label != 0) {
@@ -798,19 +800,26 @@ CodeOper(expr, true_label, false_label)
                }
                break;
        case AND:
-       case '&':
+       case '&': {
+               label l_true, l_false, l_maybe = ++text_label, l_end;
+               struct desig Des;
+
                if (true_label == 0)    {
-                       label l_true = ++text_label;
-                       label l_false = ++text_label;
-                       label l_maybe = ++text_label;
-                       label l_end = ++text_label;
-                       struct desig Des;
-
-                       Des = InitDesig;
-                       CodeExpr(leftop, &Des, l_maybe, l_false);
-                       C_df_ilb(l_maybe);
-                       Des = InitDesig;
-                       CodeExpr(rightop, &Des, l_true, l_false);
+                       l_true = ++text_label;
+                       l_false = ++text_label;
+                       l_end = ++text_label;
+               }
+               else {
+                       l_true = true_label;
+                       l_false = false_label;
+               }
+
+               Des = InitDesig;
+               CodeExpr(leftop, &Des, l_maybe, l_false);
+               C_df_ilb(l_maybe);
+               Des = InitDesig;
+               CodeExpr(rightop, &Des, l_true, l_false);
+               if (true_label == 0) {
                        C_df_ilb(l_true);
                        C_loc((arith)1);
                        C_bra(l_end);
@@ -818,30 +827,27 @@ CodeOper(expr, true_label, false_label)
                        C_loc((arith)0);
                        C_df_ilb(l_end);
                }
-               else    {
-                       label l_maybe = ++text_label;
-                       struct desig Des;
-
-                       Des = InitDesig;
-                       CodeExpr(leftop, &Des, l_maybe, false_label);
-                       Des = InitDesig;
-                       C_df_ilb(l_maybe);
-                       CodeExpr(rightop, &Des, true_label, false_label);
-               }
                break;
-       case OR:
+               }
+       case OR: {
+               label l_true, l_false, l_maybe = ++text_label, l_end;
+               struct desig Des;
+
                if (true_label == 0)    {
-                       label l_true = ++text_label;
-                       label l_false = ++text_label;
-                       label l_maybe = ++text_label;
-                       label l_end = ++text_label;
-                       struct desig Des;
-
-                       Des = InitDesig;
-                       CodeExpr(leftop, &Des, l_true, l_maybe);
-                       C_df_ilb(l_maybe);
-                       Des = InitDesig;
-                       CodeExpr(rightop, &Des, l_true, l_false);
+                       l_true = ++text_label;
+                       l_false = ++text_label;
+                       l_end = ++text_label;
+               }
+               else {
+                       l_true = true_label;
+                       l_false = false_label;
+               }
+               Des = InitDesig;
+               CodeExpr(leftop, &Des, l_true, l_maybe);
+               C_df_ilb(l_maybe);
+               Des = InitDesig;
+               CodeExpr(rightop, &Des, l_true, l_false);
+               if (true_label == 0) {
                        C_df_ilb(l_false);
                        C_loc((arith)0);
                        C_bra(l_end);
@@ -849,19 +855,10 @@ CodeOper(expr, true_label, false_label)
                        C_loc((arith)1);
                        C_df_ilb(l_end);
                }
-               else    {
-                       label l_maybe = ++text_label;
-                       struct desig Des;
-
-                       Des = InitDesig;
-                       CodeExpr(leftop, &Des, true_label, l_maybe);
-                       C_df_ilb(l_maybe);
-                       Des = InitDesig;
-                       CodeExpr(rightop, &Des, true_label, false_label);
-               }
                break;
+               }
        default:
-               crash("(CodeOper) Bad operator %s\n", symbol2str(oper));
+               crash("(CodeOper) Bad operator %s\n",symbol2str(expr->nd_symb));
        }
 }
 
@@ -936,6 +933,7 @@ CodeUoper(nd)
        case '-':
                switch(tp->tp_fund) {
                case T_INTEGER:
+               case T_INTORCARD:
                        C_ngi(tp->tp_size);
                        break;
                case T_REAL:
@@ -977,7 +975,7 @@ CodeEl(nd, tp)
                        C_loc(eltype->sub_ub);
                }
                else    C_loc((arith) (eltype->enm_ncst - 1));
-               Operands(nd->nd_left, nd->nd_right);
+               Operands(nd->nd_left, nd->nd_right, word_type);
                C_cal("_LtoUset");      /* library routine to fill set */
                C_asp(4 * word_size);
        }
@@ -1032,13 +1030,20 @@ CodeDStore(nd)
 DoHIGH(nd)
        struct node *nd;
 {
+       /*      Get the high index of a conformant array, indicated by "nd".
+               The high index is the second field in the descriptor of
+               the array, so it is easily found.
+       */
        register struct def *df = nd->nd_def;
        register arith highoff;
 
        assert(nd->nd_class == Def);
        assert(df->df_kind == D_VARIABLE);
+       assert(IsConformantArray(df->df_type));
 
-       highoff = df->var_off + pointer_size + word_size;
+       highoff = df->var_off           /* base address and descriptor */
+                 + pointer_size        /* skip base address */
+                 + word_size;          /* skip first field of descriptor */
        if (df->df_scope->sc_level < proclevel) {
                C_lxa((arith) (proclevel - df->df_scope->sc_level));
                C_lof(highoff);
index 494a7bc..6620b98 100644 (file)
@@ -248,6 +248,7 @@ cstset(expp)
                assert(expp->nd_left->nd_class == Value);
 
                i = expp->nd_left->nd_INT;
+               expp->nd_class = Value;
                expp->nd_INT = (i >= 0 && set2 != 0 &&
                    i < setsize * wrd_bits &&
                    (set2[i / wrd_bits] & (1 << (i % wrd_bits))));
index a634808..a9fdac9 100644 (file)
@@ -108,9 +108,7 @@ declaration:
 FormalParameters(struct paramlist **pr;
                 struct type **ptp;
                 arith *parmaddr;)
-{
-       struct def *df;
-} :
+:      
        '('
        [
                FPSection(pr, parmaddr)
@@ -128,74 +126,38 @@ FPSection(struct paramlist **ppr; arith *parmaddr;)
        struct node *FPList;
        struct type *tp;
        int VARp;
-       struct paramlist *p = 0;
 } :
-       var(&VARp) IdentList(&FPList) ':' FormalType(&p, 0)
-                       { EnterParamList(ppr, FPList, p->par_def->df_type,
-                                        VARp, parmaddr);
-                         free_def(p->par_def);
-                         free_paramlist(p);
-                       }
+       var(&VARp) IdentList(&FPList) ':' FormalType(&tp)
+                       { EnterParamList(ppr, FPList, tp, VARp, parmaddr); }
 ;
 
-FormalType(struct paramlist **ppr; int VARp;)
+FormalType(struct type **ptp;)
 {
-       register struct def *df;
-       int ARRAYflag;
        register struct type *tp;
-       struct type *tp1;
-       register struct paramlist *p = new_paramlist();
        extern arith ArrayElSize();
 } :
-       [ ARRAY OF      { ARRAYflag = 1; }
-       |               { ARRAYflag = 0; }
-       ]
-       qualtype(&tp1)
-               { if (ARRAYflag) {
-                       tp = construct_type(T_ARRAY, NULLTYPE);
-                       tp->arr_elem = tp1;
-                       tp->arr_elsize = ArrayElSize(tp1);
-                       tp->tp_align = lcm(word_align, pointer_align);
-                 }
-                 else  tp = tp1;
-                 p->next = *ppr;
-                 *ppr = p;
-                 p->par_def = df = new_def();
-                 df->df_type = tp;
-                 df->df_flags = VARp;
+       ARRAY OF qualtype(ptp)
+               { tp = construct_type(T_ARRAY, NULLTYPE);
+                 tp->arr_elem = *ptp; *ptp = tp;
+                 tp->arr_elsize = ArrayElSize(tp->arr_elem);
+                 tp->tp_align = lcm(word_align, pointer_align);
                }
+|
+        qualtype(ptp)
 ;
 
 TypeDeclaration
 {
-       register struct def *df;
+       struct def *df;
        struct type *tp;
 }:
        IDENT           { df = define(dot.TOK_IDF,CurrentScope,D_TYPE); }
        '=' type(&tp)
-                       { if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
-                               if (tp->tp_fund != T_POINTER) {
-error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
-                               }
-                               /* Careful now ... we might have declarations
-                                  referring to the hidden type.
-                               */
-                               *(df->df_type) = *tp;
-                               if (! tp->next) {
-                                       /* It also contains a forward
-                                          reference, so update the forward-
-                                          list
-                                       */
-                                       ChForward(tp, df->df_type);
-                               }
-                               free_type(tp);
-                         }
-                         else  df->df_type = tp;
-                       }
+                       { DeclareType(df, tp); }
 ;
 
 type(struct type **ptp;):
-       SimpleType(ptp)
+       %default SimpleType(ptp)
 |
        ArrayType(ptp)
 |
@@ -247,7 +209,7 @@ IdentList(struct node **p;)
        register struct node *q;
 } :
        IDENT           { *p = q = MkLeaf(Value, &dot); }
-       [
+       [ %persistent
                ',' IDENT
                        { q->next = MkLeaf(Value, &dot);
                          q = q->next;
@@ -460,11 +422,12 @@ PointerType(struct type **ptp;)
                */
                qualtype(&((*ptp)->next))
        | %if ( nd = new_node(), nd->nd_token = dot,
-               df = lookfor(nd, CurrVis, 0), free_node(nd),
+               df = lookfor(nd, CurrVis, 0),
                df->df_kind == D_MODULE)
-               type(&((*ptp)->next))
+               type(&((*ptp)->next)) 
+                       { free_node(nd); }
        |
-               IDENT   { Forward(&dot, (*ptp)); }
+               IDENT   { Forward(nd, (*ptp)); }
        ]
 ;
 
@@ -486,24 +449,28 @@ ProcedureType(struct type **ptp;)
 {
        struct paramlist *pr = 0;
        register struct type *tp;
+       arith nbytes = 0;
 } :
                        { *ptp = 0; }
-       PROCEDURE FormalTypeList(&pr, ptp)?
+       PROCEDURE FormalTypeList(&pr, ptp, &nbytes)?
                        { *ptp = tp = construct_type(T_PROCEDURE, *ptp);
                          tp->prc_params = pr;
+                         tp->prc_nbpar = nbytes;
                        }
 ;
 
-FormalTypeList(struct paramlist **ppr; struct type **ptp;)
+FormalTypeList(struct paramlist **ppr; struct type **ptp; arith *parmaddr;)
 {
-       struct def *df;
        int VARp;
+       struct type *tp;
 } :
        '('             { *ppr = 0; }
        [
-               var(&VARp) FormalType(ppr, VARp)
+               var(&VARp) FormalType(&tp)
+                       { EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); }
                [
-                       ',' var(&VARp) FormalType(ppr, VARp)
+                       ',' var(&VARp) FormalType(&tp)
+                       { EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); }
                ]*
        ]?
        ')'
@@ -535,7 +502,7 @@ VariableDeclaration
 } :
        IdentAddr(&VarList)
                        { nd = VarList; }
-       [
+       [ %persistent
                ',' IdentAddr(&(nd->nd_right))
                        { nd = nd->nd_right; }
        ]*
index 037e9bf..8c18915 100644 (file)
@@ -290,7 +290,6 @@ DefineLocalModule(id)
                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];
@@ -316,8 +315,8 @@ DefineLocalModule(id)
 
        /* Create a type for it
        */
-       df->df_type = tp = standard_type(T_RECORD, 0, (arith) 0);
-       tp->rec_scope = sc;
+       df->df_type = standard_type(T_RECORD, 0, (arith) 0);
+       df->df_type->rec_scope = sc;
 
        /* Generate code that indicates that the initialization procedure
           for this module is local.
index 99013db..9488182 100644 (file)
@@ -74,7 +74,7 @@ GetDefinitionModule(id)
                }
                df = lookup(id, GlobalScope);
        }
-       assert(df != 0 && df->df_kind == D_MODULE);
+       assert(df && df->df_kind == D_MODULE);
        level--;
        return df;
 }
index 0d3bf36..2c9f874 100644 (file)
@@ -168,8 +168,12 @@ EnterParamList(ppr, Idlist, type, VARp, off)
        register struct paramlist *pr;
        register struct def *df;
        register struct node *idlist = Idlist;
+       struct node *dummy = 0;
        static struct paramlist *last;
 
+       if (! idlist) {
+               dummy = Idlist = idlist = MkLeaf(Name, &dot);
+       }
        for ( ; idlist; idlist = idlist->next) {
                pr = new_paramlist();
                pr->next = 0;
@@ -178,11 +182,17 @@ EnterParamList(ppr, Idlist, type, VARp, off)
                }
                else    last->next = pr;
                last = pr;
-               df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
+               if (idlist != dummy) {
+                       df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
+                       df->var_off = *off;
+               }
+               else {
+                       df = new_def();
+               }
                pr->par_def = df;
                df->df_type = type;
-               df->var_off = *off;
                df->df_flags = VARp;
+
                if (IsConformantArray(type)) {
                        /* we need room for the base address and a descriptor
                        */
@@ -347,49 +357,38 @@ node_error(idlist, "opaque type \"%s\" is not a pointer type", df->df_idf->id_te
        FreeNode(Idlist);
 }
 
-EnterFromImportList(Idlist, Fromid, local)
+EnterFromImportList(Idlist, FromDef)
        struct node *Idlist;
-       register struct node *Fromid;
+       register struct def *FromDef;
 {
-       /*      Import the list Idlist from the module indicated by Fromid.
-               An exception must be made for imports of the Compilation Unit,
-               because in this case the definition module for Fromid must
-               be read.
-               This case is indicated by  the value 0 of the flag "local".
+       /*      Import the list Idlist from the module indicated by Fromdef.
        */
        register struct node *idlist = Idlist;
+       register struct scopelist *vis;
        register struct def *df;
-       struct scopelist *vis = enclosing(CurrVis);
        int forwflag = 0;
-       extern struct def *GetDefinitionModule();
 
-       if (local) {
-               df = lookfor(Fromid, vis, 0);
-               switch(df->df_kind) {
-               case D_ERROR:
-                       /* The module from which the import was done
-                          is not yet declared. I'm not sure if I must
-                          accept this, but for the time being I will.
-                          ???
-                       */
-                       vis = ForwModule(df, Fromid);
-                       forwflag = 1;
-                       break;
-               case D_FORWMODULE:
-                       vis = df->for_vis;
-                       break;
-               case D_MODULE:
-                       vis = df->mod_vis;
-                       break;
-               default:
-node_error(Fromid, "identifier \"%s\" does not represent a module",
-Fromid->nd_IDF->id_text);
-                       break;
-               }
+       switch(FromDef->df_kind) {
+       case D_ERROR:
+               /* The module from which the import was done
+                  is not yet declared. I'm not sure if I must
+                  accept this, but for the time being I will.
+                  ???
+               */
+               vis = ForwModule(FromDef, FromDef->df_idf);
+               forwflag = 1;
+               break;
+       case D_FORWMODULE:
+               vis = FromDef->for_vis;
+               break;
+       case D_MODULE:
+               vis = FromDef->mod_vis;
+               break;
+       default:
+error("identifier \"%s\" does not represent a module",
+FromDef->df_idf->id_text);
+               break;
        }
-       else    vis = GetDefinitionModule(Fromid->nd_IDF)->mod_vis;
-
-       FreeNode(Fromid);
 
        for (; idlist; idlist = idlist->next) {
                if (forwflag) {
index 36c2bf3..0573fde 100644 (file)
@@ -18,6 +18,7 @@ static  char *RcsId = "$Header$";
 #include       "def.h"
 #include       "type.h"
 #include       "node.h"
+#include       "f_info.h"
 
 }
 /*
@@ -91,12 +92,22 @@ export(int *QUALflag; struct node **ExportList;)
 import(int local;)
 {
        struct node *ImportList;
-       register struct node *id;
+       register struct def *df;
+       int fromid;
+       extern struct def *GetDefinitionModule();
 } :
        [ FROM
-         IDENT         { id = MkLeaf(Value, &dot); }
+         IDENT         { fromid = 1;
+                         if (local) {
+                               struct node *nd = MkLeaf(Name, &dot);
+
+                               df = lookfor(nd,enclosing(CurrVis),0);
+                               FreeNode(nd);
+                         }
+                         else  df = GetDefinitionModule(dot.TOK_IDF);
+                       }
        |
-                       { id = 0; }
+                       { fromid = 0; }
        ]
        IMPORT IdentList(&ImportList) ';'
        /*
@@ -105,7 +116,7 @@ import(int local;)
           If the FROM clause is present, the identifier in it is a module
           name, otherwise the names in the import list are module names.
        */
-                       { if (id) EnterFromImportList(ImportList, id, local);
+                       { if (fromid) EnterFromImportList(ImportList, df);
                          else EnterImportList(ImportList, local);
                        }
 ;
index 5333f37..9962b67 100644 (file)
@@ -67,14 +67,14 @@ InitScope()
 
 struct forwards {
        struct forwards *next;
-       struct node fo_tok;
+       struct node *fo_tok;
        struct type *fo_ptyp;
 };
 
 /* STATICALLOCDEF "forwards" */
 
 Forward(tk, ptp)
-       struct token *tk;
+       struct node *tk;
        struct type *ptp;
 {
        /*      Enter a forward reference into a list belonging to the
@@ -84,7 +84,7 @@ Forward(tk, ptp)
        */
        register struct forwards *f = new_forwards();
 
-       f->fo_tok.nd_token = *tk;
+       f->fo_tok = tk;
        f->fo_ptyp = ptp;
        f->next = CurrentScope->sc_forw;
        CurrentScope->sc_forw = f;
@@ -168,23 +168,24 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared",
 
 STATIC
 rem_forwards(fo)
-       struct forwards *fo;
+       register struct forwards *fo;
 {
        /*      When closing a scope, all forward references must be resolved
        */
-       register struct forwards *f;
        register struct def *df;
 
-       while (f = fo) {
-               df = lookfor(&(f->fo_tok), CurrVis, 1);
-               if (!(df->df_kind & (D_TYPE|D_ERROR))) {
-                       node_error(&(f->fo_tok), "identifier \"%s\" not a type",
-                             df->df_idf->id_text);
-               }
-               f->fo_ptyp->next = df->df_type;
-               fo = f->next;
-               free_forwards(f);
+       if (fo->next) rem_forwards(fo->next);
+       df = lookfor(fo->fo_tok, CurrVis, 0);
+       if (df->df_kind == D_ERROR) {
+               node_error(fo->fo_tok, "identifier \"%s\" not declared",
+                       df->df_idf->id_text);
+       }
+       else if (df->df_kind != D_TYPE) {
+               node_error(fo->fo_tok, "identifier \"%s\" not a type",
+                            df->df_idf->id_text);
        }
+       fo->fo_ptyp->next = df->df_type;
+       free_forwards(fo);
 }
 
 Reverse(pdf)
index 610bc9f..c04f193 100644 (file)
@@ -104,10 +104,11 @@ construct_type(fund, tp)
                break;
 
        case T_ARRAY:
-               dtp->tp_align = tp->tp_align;
+               if (tp) dtp->tp_align = tp->tp_align;
                break;
 
        case T_SUBRANGE:
+               assert(tp != 0);
                dtp->tp_align = tp->tp_align;
                dtp->tp_size = tp->tp_size;
                break;
@@ -386,7 +387,7 @@ ArrayElSize(tp)
 
        if (tp->tp_fund == T_ARRAY) ArraySizes(tp);
        algn = align(tp->tp_size, tp->tp_align);
-       if (word_size % algn != 0) {
+       if (algn && word_size % algn != 0) {
                /* algn is not a dividor of the word size, so make sure it
                   is a multiple
                */
@@ -449,6 +450,36 @@ FreeType(tp)
        free_type(tp);
 }
 
+DeclareType(df, tp)
+       register struct def *df;
+       register struct type *tp;
+{
+       /*      A type with type-description "tp" is declared and must
+               be bound to definition "df".
+               This routine also handles the case that the type-field of
+               "df" is already bound. In that case, it is either an opaque
+               type, or an error message was given when "df" was created.
+       */
+
+       if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
+               if (tp->tp_fund != T_POINTER) {
+error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
+               }
+               /* Careful now ... we might have declarations
+                  referring to the hidden type.
+               */
+               *(df->df_type) = *tp;
+               if (! tp->next) {
+                       /* It also contains a forward reference,
+                          so update the forwardlist
+                       */
+                       ChForward(tp, df->df_type);
+               }
+               free_type(tp);
+       }
+       else    df->df_type = tp;
+}
+
 int
 gcd(m, n)
        register int m, n;
index 0b0b995..422638c 100644 (file)
@@ -81,6 +81,9 @@ TstProcEquiv(tp1, tp2)
                p2 = p2->next;
        }
 
+       /* Here, at least one of the parameterlists is exhausted.
+          Check that they are both.
+       */
        return p1 == p2;
 }
 
@@ -101,18 +104,17 @@ TstCompat(tp1, tp2)
            ||
                (  tp1 == intorcard_type
                &&
-                  (tp2 == int_type || tp2 == card_type)
+                  (tp2 == int_type || tp2 == card_type || tp2 == address_type)
                )
            ||
                (  tp2 == intorcard_type
                &&
-                  (tp1 == int_type || tp1 == card_type)
+                  (tp1 == int_type || tp1 == card_type || tp1 == address_type)
                )
            ||
                (  tp1 == address_type
                && 
                  (  tp2 == card_type
-                 || tp2 == intorcard_type
                  || tp2->tp_fund == T_POINTER
                  )
                )
@@ -120,7 +122,6 @@ TstCompat(tp1, tp2)
                (  tp2 == address_type
                && 
                  (  tp1 == card_type
-                 || tp1 == intorcard_type
                  || tp1->tp_fund == T_POINTER
                  )
                )
@@ -173,7 +174,7 @@ TstAssCompat(tp1, tp2)
 
 int
 TstParCompat(formaltype, actualtype, VARflag, nd)
-       struct type *formaltype, *actualtype;
+       register struct type *formaltype, *actualtype;
        struct node *nd;
 {
        /*      Check type compatibility for a parameter in a procedure call.
@@ -218,19 +219,12 @@ TstParCompat(formaltype, actualtype, VARflag, nd)
                   )
                )
            ||
-               ( VARflag && OldCompat(formaltype, actualtype, nd))
+               (  VARflag
+               && (  TstCompat(formaltype, actualtype)
+                  &&
+(node_warning(nd, "oldfashioned! types of formal and actual must be identical"),
+                     1)
+                  )
+               )
        ;
 }
-
-int
-OldCompat(ft, at, nd)
-       struct type *ft, *at;
-       struct node *nd;
-{
-       if (TstCompat(ft, at)) {
-node_warning(nd, "oldfashioned! types of formal and actual must be identical");
-               return 1;
-       }
-
-       return 0;
-}
index 7454ed9..c632493 100644 (file)
@@ -132,6 +132,8 @@ WalkProcedure(procedure)
        register struct type *tp;
        register struct paramlist *param;
        label func_res_label = 0;
+       arith tmpvar1 = 0;
+       arith retsav = 0;
 
        proclevel++;
        CurrVis = procedure->prc_vis;
@@ -147,6 +149,14 @@ WalkProcedure(procedure)
        DoProfil();
        TmpOpen(sc);
 
+       func_type = tp = ResultType(procedure->df_type);
+
+       if (tp && IsConstructed(tp)) {
+               func_res_label = ++data_label;
+               C_df_dlb(func_res_label);
+               C_bss_cst(tp->tp_size, (arith) 0, 0);
+       }
+
        /* Generate calls to initialization routines of modules defined within
           this procedure
        */
@@ -154,6 +164,7 @@ WalkProcedure(procedure)
 
        /* Make sure that arguments of size < word_size are on a
           fixed place.
+          Also make copies of conformant arrays when neccessary.
        */
        for (param = ParamList(procedure->df_type);
             param;
@@ -161,37 +172,114 @@ WalkProcedure(procedure)
                if (! IsVarParam(param)) {
                        tp = TypeOfParam(param);
 
-                       if (!IsConformantArray(tp) && tp->tp_size < word_size) {
-                               C_lol(param->par_def->var_off);
+                       if (! IsConformantArray(tp)) {
+                               if (tp->tp_size < word_size) {
+                                       C_lol(param->par_def->var_off);
+                                       C_lal(param->par_def->var_off);
+                                       C_sti(tp->tp_size);
+                               }
+                       }
+                       else {
+                               /* Here, we have to make a copy of the
+                                  array. We must also remember how much
+                                  room is reserved for copies, because
+                                  we have to adjust the stack pointer before
+                                  a RET is done. This is even more complicated
+                                  when the procedure returns a value.
+                                  Then, the value must be saved (in retval),
+                                  the stack adjusted, the return value pushed
+                                  again, and then RET
+                               */
+                               arith tmpvar = NewInt();
+
+                               if (! tmpvar1) {
+                                       if (tp && !func_res_label) {
+                                               /* Some local space, only
+                                                  needed if the value itself
+                                                  is returned
+                                               */
+                                               sc->sc_off -= WA(tp->tp_size);
+                                               retsav = sc->sc_off;
+                                       }
+                                       tmpvar1 = NewInt();
+                                       C_loc((arith) 0);
+                                       C_stl(tmpvar1);
+                               }
+                               /* First compute the size */
+                               C_lol(param->par_def->var_off +
+                                     pointer_size + word_size);
+                               C_inc();        /* gives number of elements */
+                               C_loc(tp->arr_elem->tp_size);
+                               C_cal("_wa");
+                               C_asp(dword_size);
+                               C_lfr(word_size);
+                                               /* size in words */
+                               C_loc(word_size);
+                               C_mli(word_size);
+                                               /* size in bytes */
+                               C_stl(tmpvar);
+                               C_lol(tmpvar);
+                               C_dup(word_size);
+                               C_lol(tmpvar1);
+                               C_adi(word_size);
+                               C_stl(tmpvar1); /* remember all stack adjustments */
+                               C_ngi(word_size);
+                               C_ass(word_size);
+                                               /* adjusted stack pointer */
+                               C_lor((arith) 1);
+                                               /* destination address */
+                               C_lal(param->par_def->var_off);
+                               C_loi(pointer_size);
+                                               /* push source address */
+                               C_exg(pointer_size);
+                                               /* exchange them */
+                               C_lol(tmpvar);  /* push size */
+                               C_bls(word_size);
+                                               /* copy */
+                               C_lor((arith) 1);       
+                                               /* push new address of array */
                                C_lal(param->par_def->var_off);
-                               C_sti(tp->tp_size);
+                               C_sti(pointer_size);
+                               FreeInt(tmpvar);
                        }
                }
        }
 
        text_label = 1;
-       func_type = tp = ResultType(procedure->df_type);
-
-       if (IsConstructed(tp)) {
-               func_res_label = ++data_label;
-               C_df_dlb(func_res_label);
-               C_bss_cst(tp->tp_size, (arith) 0, 0);
-       }
 
        DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
        WalkNode(procedure->prc_body, (label) 0);
-       C_ret((arith) 0);
-       if (tp) {
-               C_df_ilb((label) 1);
-               if (func_res_label) {
-                       C_lae_dlb(func_res_label, (arith) 0);
-                       C_sti(tp->tp_size);
-                       C_lae_dlb(func_res_label, (arith) 0);
-                       C_ret(pointer_size);
+       C_df_ilb((label) 1);
+       tp = func_type;
+       if (func_res_label) {
+               C_lae_dlb(func_res_label, (arith) 0);
+               C_sti(tp->tp_size);
+               if (tmpvar1) {
+                       C_lol(tmpvar1);
+                       C_ass(word_size);
                }
-               else    C_ret(WA(tp->tp_size));
+               C_lae_dlb(func_res_label, (arith) 0);
+               C_ret(pointer_size);
        }
-
+       else if (tp) {
+               if (tmpvar1) {
+                       C_lal(retsav);
+                       C_sti(WA(tp->tp_size));
+                       C_lol(tmpvar1);
+                       C_ass(word_size);
+                       C_lal(retsav);
+                       C_loi(WA(tp->tp_size));
+               }
+               C_ret(WA(tp->tp_size));
+       }
+       else    {
+               if (tmpvar1) {
+                       C_lol(tmpvar1);
+                       C_ass(word_size);
+               }
+               C_ret((arith) 0);
+       }
+       if (tmpvar1) FreeInt(tmpvar1);
        if (! options['n']) RegisterMessages(sc->sc_def);
        C_end(-sc->sc_off);
        TmpClose();
@@ -394,7 +482,7 @@ WalkStat(nd, lab)
                        struct desig ds;
                        arith tmp = 0;
 
-                       WalkDesignator(left, &ds);
+                       if (! WalkDesignator(left, &ds)) break;
                        if (left->nd_type->tp_fund != T_RECORD) {
                                node_error(left, "record variable expected");
                                break;
@@ -432,7 +520,7 @@ WalkStat(nd, lab)
 
        case RETURN:
                if (right) {
-                       WalkExpr(right);
+                       if (! WalkExpr(right)) break;
                        /* The type of the return-expression must be
                           assignment compatible with the result type of the
                           function procedure (See Rep. 9.11).
@@ -440,9 +528,8 @@ WalkStat(nd, lab)
                        if (!TstAssCompat(func_type, right->nd_type)) {
 node_error(right, "type incompatibility in RETURN statement");
                        }
-                       C_bra((label) 1);
                }
-               else    C_ret((arith) 0);
+               C_bra((label) 1);
                break;
 
        default:
@@ -487,17 +574,20 @@ ExpectBool(nd, true_label, false_label)
        CodeExpr(nd, &ds,  true_label, false_label);
 }
 
+int
 WalkExpr(nd)
        struct node *nd;
 {
        /*      Check an expression and generate code for it
        */
 
-       if (! ChkExpression(nd)) return;
+       if (! ChkExpression(nd)) return 0;
 
        CodePExpr(nd);
+       return 1;
 }
 
+int
 WalkDesignator(nd, ds)
        struct node *nd;
        struct desig *ds;
@@ -505,10 +595,11 @@ WalkDesignator(nd, ds)
        /*      Check designator and generate code for it
        */
 
-       if (! ChkVariable(nd)) return;
+       if (! ChkVariable(nd)) return 0;
 
        *ds = InitDesig;
        CodeDesig(nd, ds);
+       return 1;
 }
 
 DoForInit(nd, left)