From: ceriel Date: Tue, 17 Jun 1986 12:04:05 +0000 (+0000) Subject: newer version X-Git-Tag: release-5-5~5277 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a9dfdc494b09ba6525e911f6e8fc2bad90e69866;p=ack.git newer version --- diff --git a/lang/m2/comp/LLlex.c b/lang/m2/comp/LLlex.c index 5f4c8b437..20d08b3bd 100644 --- a/lang/m2/comp/LLlex.c +++ b/lang/m2/comp/LLlex.c @@ -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: diff --git a/lang/m2/comp/Makefile b/lang/m2/comp/Makefile index a295f17f9..48df7b4ce 100644 --- a/lang/m2/comp/Makefile +++ b/lang/m2/comp/Makefile @@ -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 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 diff --git a/lang/m2/comp/chk_expr.c b/lang/m2/comp/chk_expr.c index 82f32881d..ea1b0a2cc 100644 --- a/lang/m2/comp/chk_expr.c +++ b/lang/m2/comp/chk_expr.c @@ -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 index 000000000..6b4422b39 --- /dev/null +++ b/lang/m2/comp/chk_expr.h @@ -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)) diff --git a/lang/m2/comp/code.c b/lang/m2/comp/code.c index 48c55d28d..9c81eb76a 100644 --- a/lang/m2/comp/code.c +++ b/lang/m2/comp/code.c @@ -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: diff --git a/lang/m2/comp/declar.g b/lang/m2/comp/declar.g index 9bad30c1e..63c0e3c99 100644 --- a/lang/m2/comp/declar.g +++ b/lang/m2/comp/declar.g @@ -461,7 +461,6 @@ PointerType(struct type **ptp;) { struct type *tp; struct def *df; - struct def *lookfor(); struct node *nd; } : POINTER TO diff --git a/lang/m2/comp/def.H b/lang/m2/comp/def.H index bdf908815..e87d3ac01 100644 --- a/lang/m2/comp/def.H +++ b/lang/m2/comp/def.H @@ -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) diff --git a/lang/m2/comp/def.c b/lang/m2/comp/def.c index 1b703ff65..91f4402a1 100644 --- a/lang/m2/comp/def.c +++ b/lang/m2/comp/def.c @@ -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; diff --git a/lang/m2/comp/desig.c b/lang/m2/comp/desig.c index 3cde10de2..1a325fb23 100644 --- a/lang/m2/comp/desig.c +++ b/lang/m2/comp/desig.c @@ -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; } diff --git a/lang/m2/comp/desig.h b/lang/m2/comp/desig.h index ac2f37608..a7c1c736f 100644 --- a/lang/m2/comp/desig.h +++ b/lang/m2/comp/desig.h @@ -50,6 +50,6 @@ struct withdesig { }; extern struct withdesig *WithDesigs; -extern struct desig Desig, InitDesig; +extern struct desig InitDesig; #define NO_LABEL ((label) 0) diff --git a/lang/m2/comp/enter.c b/lang/m2/comp/enter.c index 6184d23d1..04d4dda75 100644 --- a/lang/m2/comp/enter.c +++ b/lang/m2/comp/enter.c @@ -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); diff --git a/lang/m2/comp/expression.g b/lang/m2/comp/expression.g index bfdfe427d..3adfc1603 100644 --- a/lang/m2/comp/expression.g +++ b/lang/m2/comp/expression.g @@ -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; } ; diff --git a/lang/m2/comp/lookup.c b/lang/m2/comp/lookup.c index a150d79a9..12775cbee 100644 --- a/lang/m2/comp/lookup.c +++ b/lang/m2/comp/lookup.c @@ -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; diff --git a/lang/m2/comp/misc.c b/lang/m2/comp/misc.c index d28f4efc5..d3f00bad6 100644 --- a/lang/m2/comp/misc.c +++ b/lang/m2/comp/misc.c @@ -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 diff --git a/lang/m2/comp/node.H b/lang/m2/comp/node.H index ca2bf2288..a5e83862d 100644 --- a/lang/m2/comp/node.H +++ b/lang/m2/comp/node.H @@ -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 diff --git a/lang/m2/comp/node.c b/lang/m2/comp/node.c index c940e4273..f8ea57b1e 100644 --- a/lang/m2/comp/node.c +++ b/lang/m2/comp/node.c @@ -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; { diff --git a/lang/m2/comp/program.g b/lang/m2/comp/program.g index 32cba66b7..9ee7cec46 100644 --- a/lang/m2/comp/program.g +++ b/lang/m2/comp/program.g @@ -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))? diff --git a/lang/m2/comp/scope.C b/lang/m2/comp/scope.C index f1731fb32..2cd6d34ae 100644 --- a/lang/m2/comp/scope.C +++ b/lang/m2/comp/scope.C @@ -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); diff --git a/lang/m2/comp/statement.g b/lang/m2/comp/statement.g index aef6e22c2..62fd0a912 100644 --- a/lang/m2/comp/statement.g +++ b/lang/m2/comp/statement.g @@ -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) ]* ; diff --git a/lang/m2/comp/type.c b/lang/m2/comp/type.c index ae272a6f5..98595b187 100644 --- a/lang/m2/comp/type.c +++ b/lang/m2/comp/type.c @@ -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) diff --git a/lang/m2/comp/walk.c b/lang/m2/comp/walk.c index a68f48f6a..ae214d500 100644 --- a/lang/m2/comp/walk.c +++ b/lang/m2/comp/walk.c @@ -12,6 +12,7 @@ static char *RcsId = "$Header$"; #include #include +#include #include #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