From: ceriel Date: Wed, 28 May 1986 18:36:51 +0000 (+0000) Subject: newer version X-Git-Tag: release-5-5~5288 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=6382054ae563a63cfad88ca588f6586d8ba6f679;p=ack.git newer version --- diff --git a/lang/m2/comp/LLlex.c b/lang/m2/comp/LLlex.c index c7738c649..08a27624a 100644 --- a/lang/m2/comp/LLlex.c +++ b/lang/m2/comp/LLlex.c @@ -182,10 +182,6 @@ again: if (nch == '=') { return tk->tk_symb = LESSEQUAL; } - else - if (nch == '>') { - return tk->tk_symb = '#'; - } PushBack(nch); return tk->tk_symb = ch; diff --git a/lang/m2/comp/LLmessage.c b/lang/m2/comp/LLmessage.c index 0ea6e86a4..ffb3d80b6 100644 --- a/lang/m2/comp/LLmessage.c +++ b/lang/m2/comp/LLmessage.c @@ -4,6 +4,12 @@ static char *RcsId = "$Header$"; #endif +/* Defines the LLmessage routine. LLgen-generated parsers require the + existence of a routine of that name. + The routine must do syntax-error reporting and must be able to + insert tokens in the token stream. +*/ + #include #include #include @@ -12,15 +18,18 @@ static char *RcsId = "$Header$"; #include "LLlex.h" #include "Lpars.h" -extern char *symbol2str(); -extern struct idf *gen_anon_idf(); -int err_occurred = 0; +extern char *symbol2str(); +extern struct idf *gen_anon_idf(); +int err_occurred = 0; LLmessage(tk) int tk; { ++err_occurred; if (tk) { + /* if (tk != 0), it represents the token to be inserted. + otherwize, the current token is deleted + */ error("%s missing", symbol2str(tk)); insert_token(tk); } diff --git a/lang/m2/comp/Makefile b/lang/m2/comp/Makefile index 42805283b..1e00f28ab 100644 --- a/lang/m2/comp/Makefile +++ b/lang/m2/comp/Makefile @@ -11,7 +11,7 @@ LSRC = tokenfile.g program.g declar.g expression.g statement.g CC = cc GEN = LLgen GENOPTIONS = -PROFILE = +PROFILE = CFLAGS = $(PROFILE) $(INCLUDES) LFLAGS = $(PROFILE) LOBJ = tokenfile.o program.o declar.o expression.o statement.o @@ -91,7 +91,7 @@ tokenname.o: Lpars.h idf.h tokenname.h idf.o: idf.h input.o: f_info.h input.h inputtype.h type.o: LLlex.h const.h debug.h def.h idf.h maxset.h node.h target_sizes.h type.h -def.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h +def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h scope.o: LLlex.h debug.h def.h idf.h node.h scope.h type.h misc.o: LLlex.h f_info.h idf.h misc.h node.h enter.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h @@ -101,10 +101,11 @@ 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 options.o: idfsize.h main.h ndir.h type.h -walk.o: LLlex.h Lpars.h debug.h def.h desig.h main.h node.h scope.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 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 type.h +tmpvar.o: debug.h def.h scope.h type.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 diff --git a/lang/m2/comp/casestat.C b/lang/m2/comp/casestat.C index 9ba52fb2e..7fbfeffe4 100644 --- a/lang/m2/comp/casestat.C +++ b/lang/m2/comp/casestat.C @@ -63,15 +63,12 @@ CaseCode(nd, exitlabel) register arith val; label tablabel; - assert(nd->nd_class == Stat && nd->nd_symb == CASE); + assert(pnode->nd_class == Stat && pnode->nd_symb == CASE); - WalkExpr(nd->nd_left, NO_LABEL, NO_LABEL); - sh->sh_type = nd->nd_left->nd_type; + clear((char *) sh, sizeof(*sh)); + WalkExpr(pnode->nd_left, NO_LABEL, NO_LABEL); + sh->sh_type = pnode->nd_left->nd_type; sh->sh_break = text_label(); - sh->sh_default = 0; - sh->sh_nrofentries = 0; - sh->sh_lowerbd = sh->sh_upperbd = (arith)0; /* immaterial ??? */ - sh->sh_entries = (struct case_entry *) 0; /* case-entry list */ /* Now, create case label list */ @@ -189,6 +186,7 @@ AddCases(sh, node, lbl) if (node->nd_symb == UPTO) { assert(node->nd_left->nd_class == Value); assert(node->nd_right->nd_class == Value); + v2 = node->nd_right->nd_INT; node->nd_type = node->nd_left->nd_type; for (v1 = node->nd_left->nd_INT; v1 <= v2; v1++) { @@ -233,9 +231,12 @@ AddOneCase(sh, node, lbl) /* second etc. case entry */ /* find the proper place to put ce into the list */ - if (ce->ce_value < sh->sh_lowerbd) sh->sh_lowerbd = ce->ce_value; - else - if (ce->ce_value > sh->sh_upperbd) sh->sh_upperbd = ce->ce_value; + if (ce->ce_value < sh->sh_lowerbd) { + sh->sh_lowerbd = ce->ce_value; + } + else if (ce->ce_value > sh->sh_upperbd) { + sh->sh_upperbd = ce->ce_value; + } while (c1 && c1->ce_value < ce->ce_value) { c2 = c1; c1 = c1->next; diff --git a/lang/m2/comp/chk_expr.c b/lang/m2/comp/chk_expr.c index daf2befb5..36db56bfe 100644 --- a/lang/m2/comp/chk_expr.c +++ b/lang/m2/comp/chk_expr.c @@ -38,7 +38,7 @@ chk_expr(expp) switch(expp->nd_class) { case Oper: if (expp->nd_symb == '[') { - return chk_designator(expp, DESIGNATOR|VARIABLE); + return chk_designator(expp, DESIGNATOR|VARIABLE, D_NOREG|D_USED); } return chk_expr(expp->nd_left) && @@ -47,7 +47,7 @@ chk_expr(expp) case Uoper: if (expp->nd_symb == '^') { - return chk_designator(expp, DESIGNATOR|VARIABLE); + return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); } return chk_expr(expp->nd_right) && @@ -69,13 +69,13 @@ chk_expr(expp) return chk_set(expp); case Name: - return chk_designator(expp, VALUE); + return chk_designator(expp, VALUE, D_USED); case Call: return chk_call(expp); case Link: - return chk_designator(expp, DESIGNATOR|VALUE); + return chk_designator(expp, DESIGNATOR|VALUE, D_USED|D_NOREG); default: assert(0); @@ -94,6 +94,7 @@ chk_set(expp) struct def *df; register struct node *nd; arith *set; + unsigned size; assert(expp->nd_symb == SET); @@ -102,7 +103,7 @@ chk_set(expp) if (nd = expp->nd_left) { /* A type was given. Check it out */ - if (! chk_designator(nd, 0)) return 0; + if (! chk_designator(nd, 0, D_USED)) return 0; assert(nd->nd_class == Def); df = nd->nd_def; @@ -117,16 +118,26 @@ chk_set(expp) 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 + First allocate room for the set, but only if it is'nt empty. */ - set = (arith *) - Malloc((unsigned) (tp->tp_size * sizeof(arith) / word_size)); + 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 */ - nd = expp->nd_right; while (nd) { assert(nd->nd_class == Link && nd->nd_symb == ','); @@ -134,8 +145,6 @@ chk_set(expp) nd = nd->nd_right; } - expp->nd_type = tp; - 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 @@ -255,7 +264,7 @@ getarg(argp, bases, designator) } argp = argp->nd_right; if ((!designator && !chk_expr(argp->nd_left)) || - (designator && !chk_designator(argp->nd_left, DESIGNATOR))) { + (designator && !chk_designator(argp->nd_left, DESIGNATOR, D_REFERRED))) { return 0; } tp = argp->nd_left->nd_type; @@ -276,7 +285,7 @@ getname(argp, kinds) return 0; } argp = argp->nd_right; - if (! chk_designator(argp->nd_left, 0)) return 0; + if (! chk_designator(argp->nd_left, 0, D_REFERRED)) return 0; assert(argp->nd_left->nd_class == Def); @@ -303,10 +312,9 @@ chk_call(expp) */ expp->nd_type = error_type; left = expp->nd_left; - if (! chk_designator(left, 0)) return 0; + if (! chk_designator(left, 0, D_USED)) return 0; - if (left->nd_class == Def && - (left->nd_def->df_kind & (D_HTYPE|D_TYPE|D_HIDDEN))) { + if (left->nd_class == Def && is_type(left->nd_def)) { /* It was a type cast. This is of course not portable. */ arg = expp->nd_right; @@ -359,10 +367,21 @@ chk_proccall(expp) { /* Check a procedure call */ - register struct node *left = expp->nd_left; + register struct node *left; register 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; arg->nd_type = left->nd_type->next; param = left->nd_type->prc_params; @@ -376,6 +395,9 @@ chk_proccall(expp) node_error(arg->nd_left, "type incompatibility in parameter"); return 0; } + if (param->par_var && arg->nd_left->nd_class == Def) { + arg->nd_left->nd_def->df_flags |= D_NOREG; + } param = param->next; } @@ -422,7 +444,7 @@ FlagCheck(expp, df, flag) } int -chk_designator(expp, flag) +chk_designator(expp, flag, dflags) register struct node *expp; { /* Find the name indicated by "expp", starting from the current @@ -435,6 +457,8 @@ chk_designator(expp, flag) and '^' are allowed for this designator. Also contained may be the flag HASSELECTORS, indicating that the result must have selectors. + "dflags" contains some flags that must be set at the definition + found. */ register struct def *df; register struct type *tp; @@ -454,7 +478,8 @@ chk_designator(expp, flag) assert(expp->nd_right->nd_class == Name); if (! chk_designator(expp->nd_left, - (flag|HASSELECTORS))) return 0; + flag|HASSELECTORS, + dflags|D_NOREG)) return 0; tp = expp->nd_left->nd_type; @@ -512,6 +537,8 @@ df->df_idf->id_text); } } + df->df_flags |= dflags; + return 1; } @@ -526,7 +553,7 @@ df->df_idf->id_text); assert(expp->nd_symb == '['); if ( - !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE) + !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags|D_NOREG) || !chk_expr(expp->nd_right) || @@ -558,7 +585,7 @@ df->df_idf->id_text); if (expp->nd_class == Uoper) { assert(expp->nd_symb == '^'); - if (! chk_designator(expp->nd_right, DESIGNATOR|VARIABLE)) { + if (! chk_designator(expp->nd_right, DESIGNATOR|VARIABLE, dflags)) { return 0; } @@ -703,7 +730,6 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R case '=': case '#': - case UNEQUAL: case GREATEREQUAL: case LESSEQUAL: case '<': @@ -732,7 +758,6 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R case T_POINTER: if (chk_address(tpl, tpr) || expp->nd_symb == '=' || - expp->nd_symb == UNEQUAL || expp->nd_symb == '#') return 1; break; @@ -790,6 +815,7 @@ chk_uoper(expp) case '+': if (tpr->tp_fund & T_NUMERIC) { expp->nd_token = right->nd_token; + expp->nd_class = right->nd_class; FreeNode(right); expp->nd_right = 0; return 1; @@ -809,10 +835,14 @@ chk_uoper(expp) else if (tpr->tp_fund == T_REAL) { if (right->nd_class == Value) { expp->nd_token = right->nd_token; + expp->nd_class = Value; if (*(expp->nd_REL) == '-') { expp->nd_REL++; } - else expp->nd_REL--; + else { + expp->nd_REL--; + *(expp->nd_REL) = '-'; + } FreeNode(right); expp->nd_right = 0; } @@ -853,7 +883,7 @@ getvariable(arg) left = arg->nd_left; - if (! chk_designator(left, DESIGNATOR)) return 0; + if (! chk_designator(left, DESIGNATOR, D_REFERRED)) return 0; if (left->nd_class == Oper || left->nd_class == Uoper) { return arg; } @@ -941,7 +971,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname)); case S_TSIZE: /* ??? */ case S_SIZE: expp->nd_type = intorcard_type; - arg = getname(arg, D_FIELD|D_VARIABLE|D_TYPE|D_HIDDEN|D_HTYPE); + arg = getname(arg, D_FIELD|D_VARIABLE|D_ISTYPE); if (!arg) return 0; cstcall(expp, S_SIZE); break; @@ -955,7 +985,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname)); { struct type *tp; - if (!(arg = getname(arg, D_HIDDEN|D_HTYPE|D_TYPE))) return 0; + if (!(arg = getname(arg, D_ISTYPE))) return 0; tp = arg->nd_left->nd_def->df_type; if (tp->tp_fund == T_SUBRANGE) tp = tp->next; if (!(tp->tp_fund & T_DISCRETE)) { diff --git a/lang/m2/comp/code.c b/lang/m2/comp/code.c index cd2101fa2..54e9bf1be 100644 --- a/lang/m2/comp/code.c +++ b/lang/m2/comp/code.c @@ -52,14 +52,14 @@ CodeString(nd) struct node *nd; { label lab; - + if (nd->nd_type == charc_type) { C_loc(nd->nd_INT); return; } C_df_dlb(lab = data_label()); C_rom_scon(nd->nd_STR, nd->nd_SLE); - C_lae_dlb(lab); + C_lae_dlb(lab, (arith) 0); } CodeReal(nd) @@ -69,7 +69,7 @@ CodeReal(nd) C_df_dlb(lab = data_label()); C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size); - C_lae_dlb(lab); + C_lae_dlb(lab, (arith) 0); C_loi(nd->nd_type->tp_size); } @@ -139,12 +139,16 @@ CodeExpr(nd, ds, true_label, false_label) int i; st = nd->nd_set; - for (i = nd->nd_type->tp_size / word_size, st = nd->nd_set + i; + ds->dsg_kind = DSG_LOADED; + if (!st) { + C_zer(nd->nd_type->tp_size); + break; + } + for (i = nd->nd_type->tp_size / word_size, st += i; i > 0; i--) { C_loc(*--st); } - ds->dsg_kind = DSG_LOADED; } break; @@ -166,9 +170,97 @@ CodeExpr(nd, ds, true_label, false_label) } CodeCoercion(t1, t2) - struct type *t1, *t2; + register struct type *t1, *t2; { - /* ??? */ + 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 ((fund1 = t1->tp_fund) == T_WORD) fund1 = T_INTEGER; + if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER; + switch(fund1) { + case T_INTEGER: + switch(fund2) { + case T_INTEGER: + if (t2->tp_size != t1->tp_size) { + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cii(); + } + break; + case T_ENUMERATION: + case T_CHAR: + case T_CARDINAL: + if (t1->tp_size != word_size) { + C_loc(t1->tp_size); + C_loc(word_size); + C_ciu(); + } + break; + case T_REAL: + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cif(); + break; + default: + crash("Funny integer conversion"); + } + break; + + case T_CHAR: + case T_ENUMERATION: + case T_CARDINAL: + switch(fund2) { + case T_ENUMERATION: + case T_CHAR: + case T_CARDINAL: + case T_POINTER: + if (t2->tp_size > word_size) { + C_loc(word_size); + C_loc(t2->tp_size); + C_cuu(); + } + break; + case T_INTEGER: + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cui(); + break; + case T_REAL: + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cuf(); + break; + default: + crash("Funny cardinal conversion"); + } + break; + + case T_REAL: + switch(fund2) { + case T_REAL: + if (t2->tp_size != t1->tp_size) { + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cff(); + } + break; + case T_INTEGER: + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cfi(); + break; + case T_CARDINAL: + C_loc(t1->tp_size); + C_loc(t2->tp_size); + C_cfu(); + break; + default: + crash("Funny REAL conversion"); + } + break; + } } CodeCall(nd) @@ -190,13 +282,12 @@ CodeCall(nd) } tp = left->nd_type; - if (left->nd_class == Def && - (left->nd_def->df_kind & (D_TYPE|D_HTYPE|D_HIDDEN))) { + if (left->nd_class == Def && is_type(left->nd_def)) { /* it was just a cast. Simply ignore it */ Des = InitDesig; CodeExpr(nd->nd_right->nd_left, &Des, NO_LABEL, NO_LABEL); - CodeValue(&Des); + CodeValue(&Des, tp->tp_size); *nd = *(nd->nd_right->nd_left); nd->nd_type = left->nd_def->df_type; return; @@ -216,6 +307,7 @@ CodeCall(nd) else { CodeExpr(arg->nd_left, &Des, NO_LABEL, NO_LABEL); CodeValue(&Des, arg->nd_left->nd_type->tp_size); + CheckAssign(arg->nd_left->nd_type, param->par_type); pushed += align(arg->nd_left->nd_type->tp_size, word_align); } /* ??? Conformant arrays */ @@ -249,16 +341,55 @@ CodeStd(nd) /* ??? */ } -CodeAssign(nd, dst, dss) +CodeAssign(nd, dss, dst) struct node *nd; struct desig *dst, *dss; { /* Generate code for an assignment. Testing of type compatibility and the like is already done. */ - - CodeCoercion(nd->nd_right->nd_type, nd->nd_left->nd_type); - /* ??? */ + + if (dss->dsg_kind == DSG_LOADED) { + CodeStore(dst, nd->nd_left->nd_type->tp_size); + } + else { + CodeAddress(dst); + C_blm(nd->nd_left->nd_type->tp_size); + } +} + +CheckAssign(tpl, tpr) + register struct type *tpl, *tpr; +{ + /* Generate a range check if neccessary + */ + + 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); + } + else { + /* both types are restricted. check the bounds + to see wether we need a range check + */ + getbounds(tpl, &llo, &lhi); + getbounds(tpr, &rlo, &rhi); + if (llo > rlo || lhi < rhi) { + l = getrck(tpl); + } + } + + if (l) { + C_lae_dlb(l, (arith) 0); + C_rck(word_size); + } + } } Operands(leftop, rightop) @@ -415,29 +546,44 @@ CodeOper(expr, true_label, false_label) case '>': case GREATEREQUAL: case '=': - case UNEQUAL: case '#': Operands(leftop, rightop); CodeCoercion(rightop->nd_type, leftop->nd_type); + tp = leftop->nd_type; /* Not the result type! */ + if (tp->tp_fund == T_SUBRANGE) tp = tp->next; switch (tp->tp_fund) { case T_INTEGER: - C_cmi(leftop->nd_type->tp_size); + C_cmi(tp->tp_size); break; case T_POINTER: C_cmp(); break; case T_CARDINAL: - C_cmu(leftop->nd_type->tp_size); + C_cmu(tp->tp_size); break; case T_ENUMERATION: case T_CHAR: C_cmu(word_size); break; case T_REAL: - C_cmf(leftop->nd_type->tp_size); + C_cmf(tp->tp_size); break; case T_SET: - C_cms(leftop->nd_type->tp_size); + if (oper == 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); + } + else if (oper == 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_cms(tp->tp_size); break; default: crash("bad type COMPARE"); @@ -451,9 +597,13 @@ CodeOper(expr, true_label, false_label) } break; case IN: - Operands(leftop, rightop); - CodeCoercion(rightop->nd_type, word_type); - C_inn(leftop->nd_type->tp_size); + /* In this case, evaluate right hand side first! The + INN instruction expects the bit number on top of the + stack + */ + Operands(rightop, leftop); + CodeCoercion(leftop->nd_type, word_type); + C_inn(rightop->nd_type->tp_size); break; case AND: case '&': @@ -544,7 +694,6 @@ compare(relop, lbl) case '=': C_zeq(lbl); break; - case UNEQUAL: case '#': C_zne(lbl); break; @@ -573,7 +722,6 @@ truthvalue(relop) case '=': C_teq(); break; - case UNEQUAL: case '#': C_tne(); break; @@ -643,7 +791,7 @@ CodeEl(nd, tp) Des = InitDesig; CodeExpr(nd, &Des, NO_LABEL, NO_LABEL); - CodeValue(nd, word_size); + CodeValue(&Des, word_size); C_set(tp->tp_size); } } diff --git a/lang/m2/comp/cstoper.c b/lang/m2/comp/cstoper.c index b298221ab..20d91a50d 100644 --- a/lang/m2/comp/cstoper.c +++ b/lang/m2/comp/cstoper.c @@ -45,7 +45,7 @@ cstunary(expp) o1 = !o1; break; default: - assert(0); + crash("(cstunary)"); } expp->nd_class = Value; expp->nd_token = expp->nd_right->nd_token; @@ -159,7 +159,7 @@ cstbin(expp) ); } else - o1 = o1 < o2; + o1 = (o1 < o2); break; case '>': @@ -170,7 +170,7 @@ cstbin(expp) ); } else - o1 = o1 > o2; + o1 = (o1 > o2); break; case LESSEQUAL: if (uns) { @@ -180,7 +180,7 @@ cstbin(expp) ); } else - o1 = o1 <= o2; + o1 = (o1 <= o2); break; case GREATEREQUAL: if (uns) { @@ -190,27 +190,27 @@ cstbin(expp) ); } else - o1 = o1 >= o2; + o1 = (o1 >= o2); break; case '=': - o1 = o1 == o2; + o1 = (o1 == o2); break; case '#': - case UNEQUAL: - o1 = o1 != o2; + o1 = (o1 != o2); break; case AND: case '&': - o1 = o1 && o2; + o1 = (o1 && o2); break; case OR: - o1 = o1 || o2; + o1 = (o1 || o2); break; default: - assert(0); + crash("(cstbin)"); } expp->nd_class = Value; expp->nd_token = expp->nd_right->nd_token; + if (expp->nd_type == bool_type) expp->nd_symb = INTEGER; expp->nd_INT = o1; CutSize(expp); FreeNode(expp->nd_left); @@ -222,6 +222,7 @@ cstset(expp) register struct node *expp; { register arith *set1 = 0, *set2; + arith *resultset = 0; register int setsize, j; assert(expp->nd_right->nd_class == Set); @@ -233,32 +234,59 @@ cstset(expp) arith i; assert(expp->nd_left->nd_class == Value); + i = expp->nd_left->nd_INT; - expp->nd_INT = (i >= 0 && + expp->nd_INT = (i >= 0 && set2 != 0 && i < setsize * wrd_bits && (set2[i / wrd_bits] & (1 << (i % wrd_bits)))); - free((char *) set2); + if (set2) free((char *) set2); } else { set1 = expp->nd_left->nd_set; + resultset = set1; + expp->nd_left->nd_set = 0; switch(expp->nd_symb) { case '+': - for (j = 0; j < setsize; j++) { + if (!set1) { + resultset = set2; + expp->nd_right->nd_set = 0; + break; + } + if (set2) for (j = 0; j < setsize; j++) { *set1++ |= *set2++; } break; case '-': + if (!set1 || !set2) { + /* The set from which something is substracted + is already empty, or the set that is + substracted is empty + */ + break; + } for (j = 0; j < setsize; j++) { *set1++ &= ~*set2++; } break; case '*': + if (!set1) break; + if (!set2) { + resultset = set2; + expp->nd_right->nd_set = 0; + break; + } + for (j = 0; j < setsize; j++) { *set1++ &= *set2++; } break; case '/': - for (j = 0; j < setsize; j++) { + if (!set1) { + resultset = set2; + expp->nd_right->nd_set = 0; + break; + } + if (set2) for (j = 0; j < setsize; j++) { *set1++ ^= *set2++; } break; @@ -266,42 +294,62 @@ cstset(expp) case LESSEQUAL: case '=': case '#': - case UNEQUAL: /* Clumsy, but who cares? Nobody writes these things! */ + expp->nd_left->nd_set = set1; for (j = 0; j < setsize; j++) { switch(expp->nd_symb) { case GREATEREQUAL: + if (!set2) {j = setsize; break; } + if (!set1) break; if ((*set1 | *set2++) != *set1) break; set1++; continue; case LESSEQUAL: + if (!set1) {j = setsize; break; } + if (!set2) break; if ((*set2 | *set1++) != *set2) break; set2++; continue; case '=': case '#': - case UNEQUAL: + if (!set1 && !set2) { + j = setsize; break; + } + if (!set1 || !set2) break; if (*set1++ != *set2++) break; continue; } - expp->nd_INT = expp->nd_symb != '='; + if (j < setsize) { + expp->nd_INT = expp->nd_symb == '#'; + } + else { + expp->nd_INT = expp->nd_symb != '#'; + } break; } - if (j == setsize) expp->nd_INT = expp->nd_symb == '='; expp->nd_class = Value; expp->nd_symb = INTEGER; - free((char *) expp->nd_left->nd_set); - free((char *) expp->nd_right->nd_set); + if (expp->nd_left->nd_set) { + free((char *) expp->nd_left->nd_set); + } + if (expp->nd_right->nd_set) { + free((char *) expp->nd_right->nd_set); + } FreeNode(expp->nd_left); FreeNode(expp->nd_right); expp->nd_left = expp->nd_right = 0; return; default: - assert(0); + crash("(cstset)"); + } + if (expp->nd_right->nd_set) { + free((char *) expp->nd_right->nd_set); + } + if (expp->nd_left->nd_set) { + free((char *) expp->nd_left->nd_set); } - free((char *) expp->nd_right->nd_set); expp->nd_class = Set; - expp->nd_set = expp->nd_left->nd_set; + expp->nd_set = resultset; } FreeNode(expp->nd_left); FreeNode(expp->nd_right); @@ -405,7 +453,7 @@ cstcall(expp, call) else CutSize(expp); break; default: - assert(0); + crash("(cstcall)"); } FreeNode(expr); FreeNode(expp->nd_left); diff --git a/lang/m2/comp/declar.g b/lang/m2/comp/declar.g index 05acf8948..82b350607 100644 --- a/lang/m2/comp/declar.g +++ b/lang/m2/comp/declar.g @@ -128,8 +128,7 @@ FormalParameters(int doparams; ]? ')' { *tp = 0; } - [ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", - (struct node **) 0) + [ ':' qualident(D_ISTYPE, &df, "type", (struct node **) 0) { *tp = df->df_type; } ]? @@ -169,7 +168,7 @@ FormalType(struct type **tp;) } : [ ARRAY OF { ARRAYflag = 1; } ]? - qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0) + qualident(D_ISTYPE, &df, "type", (struct node **) 0) { if (ARRAYflag) { *tp = construct_type(T_ARRAY, NULLTYPE); (*tp)->arr_elem = df->df_type; @@ -186,14 +185,19 @@ TypeDeclaration struct def *df; struct type *tp; }: - IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); } + IDENT { df = lookup(dot.TOK_IDF, CurrentScope); + if (!df) df = define( dot.TOK_IDF, + CurrentScope, + D_TYPE); + } '=' type(&tp) - { if (df->df_type) free_type(df->df_type); + { if (df->df_type) free_type(df->df_type); /* ??? */ df->df_type = tp; - if (df->df_kind == D_HTYPE && + if (df->df_kind == D_HIDDEN && tp->tp_fund != T_POINTER) { error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text); } + df->df_kind = D_TYPE; } ; @@ -215,7 +219,7 @@ SimpleType(struct type **ptp;) { struct def *df; } : - qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0) + qualident(D_ISTYPE, &df, "type", (struct node **) 0) [ /* nothing */ { *ptp = df->df_type; } @@ -237,22 +241,16 @@ SimpleType(struct type **ptp;) enumeration(struct type **ptp;) { struct node *EnumList; + register struct type *tp; } : '(' IdentList(&EnumList) ')' { - *ptp = standard_type(T_ENUMERATION, 1, (arith) 1); - EnterIdList(EnumList, D_ENUM, 0, *ptp, + *ptp = tp = standard_type(T_ENUMERATION, 1, (arith) 1); + EnterIdList(EnumList, D_ENUM, 0, tp, CurrentScope, (arith *) 0); FreeNode(EnumList); - if ((*ptp)->enm_ncst > 256) { - if (word_size == 1) { - error("Too many enumeration literals"); - } - else { - /* ??? This is crummy */ - (*ptp)->tp_size = word_size; - (*ptp)->tp_align = word_align; - } + if (tp->enm_ncst > 256) { + error("Too many enumeration literals"); } } ; @@ -284,7 +282,8 @@ SubrangeType(struct type **ptp;) '[' ConstExpression(&nd1) UPTO ConstExpression(&nd2) ']' - { *ptp = subr_type(nd1, nd2); } + { *ptp = subr_type(nd1, nd2); + } ; ArrayType(struct type **ptp;) @@ -298,8 +297,8 @@ ArrayType(struct type **ptp;) } [ ',' SimpleType(&tp) - { tp2 = tp2->arr_elem = - construct_type(T_ARRAY, tp); + { tp2->arr_elem = construct_type(T_ARRAY, tp); + tp2 = tp2->arr_elem; } ]* OF type(&tp) { tp2->arr_elem = tp; @@ -365,8 +364,7 @@ FieldList(struct scope *scope; arith *cnt; int *palign;) } else id = nd->nd_IDF; } - ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, - &df, "type", (struct node **) 0) + ':' qualident(D_ISTYPE, &df, "type", (struct node **) 0) | /* Old fashioned! the first qualident now represents the type @@ -374,10 +372,10 @@ FieldList(struct scope *scope; arith *cnt; int *palign;) { warning("Old fashioned Modula-2 syntax!"); id = gen_anon_idf(); df = ill_df; - if (chk_designator(nd, 0) && + if (chk_designator(nd, 0, D_REFERRED) && (nd->nd_class != Def || !(nd->nd_def->df_kind & - (D_ERROR|D_TYPE|D_HTYPE|D_HIDDEN)))) { + (D_ERROR|D_ISTYPE)))) { node_error(nd, "type expected"); } else df = nd->nd_def; @@ -386,7 +384,7 @@ FieldList(struct scope *scope; arith *cnt; int *palign;) ] | /* Aha, third edition? */ - ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0) + ':' qualident(D_ISTYPE, &df, "type", (struct node **) 0) { id = gen_anon_idf(); } ] { tp = df->df_type; @@ -489,7 +487,7 @@ PointerType(struct type **ptp;) /* Either a Module or a Type, but in both cases defined in this scope, so this is the correct identification */ - qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0) + qualident(D_ISTYPE, &df, "type", (struct node **) 0) { if (!df->df_type) { error("type \"%s\" not declared", @@ -555,7 +553,7 @@ FormalTypeList(struct paramlist **ppr; struct type **ptp;) { p->next = 0; } ]? ')' - [ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0) + [ ':' qualident(D_TYPE, &df, "type", (struct node **) 0) { *ptp = df->df_type; } ]? ; diff --git a/lang/m2/comp/def.H b/lang/m2/comp/def.H index 176452c30..df4517a98 100644 --- a/lang/m2/comp/def.H +++ b/lang/m2/comp/def.H @@ -81,19 +81,21 @@ struct def { /* list of definitions for a name */ #define D_IMPORT 0x0080 /* an imported definition */ #define D_PROCHEAD 0x0100 /* a procedure heading in a definition module */ #define D_HIDDEN 0x0200 /* a hidden type */ -#define D_HTYPE 0x0400 /* definition of a hidden type seen */ #define D_FORWARD 0x0800 /* not yet defined */ #define D_UNDEF_IMPORT 0x1000 /* imported from an undefined name */ #define D_FORWMODULE 0x2000 /* module must be declared later */ #define D_ERROR 0x4000 /* a compiler generated definition for an undefined variable */ +#define D_ISTYPE (D_HIDDEN|D_TYPE) +#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE) char df_flags; -#define D_ADDRESS 0x01 /* set if address was taken */ +#define D_NOREG 0x01 /* set if it may not reside in a register */ #define D_USED 0x02 /* set if used */ #define D_DEFINED 0x04 /* set if it is assigned a value */ -#define D_VARPAR 0x08 /* set if it is a VAR parameter */ -#define D_VALPAR 0x10 /* set if it is a value parameter */ +#define D_REFERRED 0x08 /* set if it is referred to */ +#define D_VARPAR 0x10 /* set if it is a VAR parameter */ +#define D_VALPAR 0x20 /* set if it is a value parameter */ #define D_EXPORTED 0x40 /* set if exported */ #define D_QEXPORTED 0x80 /* set if qualified exported */ struct type *df_type; diff --git a/lang/m2/comp/def.c b/lang/m2/comp/def.c index 8006d58ab..3f811aebf 100644 --- a/lang/m2/comp/def.c +++ b/lang/m2/comp/def.c @@ -18,6 +18,7 @@ static char *RcsId = "$Header$"; #include "scope.h" #include "LLlex.h" #include "node.h" +#include "Lpars.h" struct def *h_def; /* Pointer to free list of def structures */ @@ -80,7 +81,7 @@ define(id, scope, kind) switch(df->df_kind) { case D_HIDDEN: if (kind == D_TYPE && !DefinitionModule) { - df->df_kind = D_HTYPE; + df->df_kind = D_TYPE; return df; } break; @@ -94,6 +95,7 @@ define(id, scope, kind) FreeNode(df->for_node); df->mod_vis = df->for_vis; df->df_kind = kind; + DefInFront(df); return df; } break; @@ -241,9 +243,9 @@ df->df_idf->id_text); else if (df1 && df1->df_kind == D_HIDDEN) { if (df->df_kind == D_TYPE) { if (df->df_type->tp_fund != T_POINTER) { -error("Opaque type \"%s\" is not a pointer type", df->df_idf->id_text); +error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text); } - df->df_kind = D_HTYPE; + df->df_kind = D_TYPE; df1->df_kind = D_IMPORT; df1->imp_def = df; continue; @@ -436,8 +438,10 @@ DeclProc(type) module. Create a def structure for it (if neccessary) */ register struct def *df; - extern char *sprint(), *Malloc(), *strcpy(); static int nmcount = 0; + extern char *Malloc(); + extern char *strcpy(); + extern char *sprint(); char buf[256]; assert(type & (D_PROCEDURE | D_PROCHEAD)); @@ -462,6 +466,7 @@ DeclProc(type) open_scope(OPENSCOPE); CurrentScope->sc_name = df->for_name; df->prc_vis = CurrVis; + DefInFront(df); } else { df = define(dot.TOK_IDF, CurrentScope, type); @@ -492,6 +497,46 @@ InitProc(nd, df) /* Keep it this way, or really create a procedure out of it??? */ } +AddModule(id) + struct idf *id; +{ + /* Add the name of a module to the Module list. This list is + maintained to create the initialization routine of the + program/implementation module currently defined. + */ + static struct node *nd_end; /* to remember end of list */ + register struct node *n; + extern struct node *Modules; + + n = MkNode(Name, NULLNODE, NULLNODE, &dot); + n->nd_IDF = id; + n->nd_symb = IDENT; + if (nd_end) nd_end->next = n; + nd_end = n; + if (!Modules) Modules = n; +} + +DefInFront(df) + register struct def *df; +{ + /* Put definition "df" in front of the list of definitions + in its scope. + This is neccessary because in some cases the order in this + list is important. + */ + register struct def *df1; + + if (df->df_scope->sc_def != df) { + df1 = df->df_scope->sc_def; + while (df1 && df1->df_nextinscope != df) { + df1 = df1->df_nextinscope; + } + if (df1) df1->df_nextinscope = df->df_nextinscope; + df->df_nextinscope = df->df_scope->sc_def; + df->df_scope->sc_def = df; + } +} + #ifdef DEBUG PrDef(df) register struct def *df; diff --git a/lang/m2/comp/defmodule.c b/lang/m2/comp/defmodule.c index cad40b376..fe6d63c1e 100644 --- a/lang/m2/comp/defmodule.c +++ b/lang/m2/comp/defmodule.c @@ -52,7 +52,9 @@ GetDefinitionModule(id) We may have to read the definition module itself. */ struct def *df; + static int level; + level++; df = lookup(id, GlobalScope); if (!df) { /* Read definition module. Make an exception for SYSTEM. @@ -63,10 +65,19 @@ GetDefinitionModule(id) else { GetFile(id->id_text); DefModule(); + if (level == 1) { + /* The module is directly imported by the + currently defined module, so we have to + remember its name because we have to call + its initialization routine + */ + AddModule(id); + } } df = lookup(id, GlobalScope); } assert(df != 0 && df->df_kind == D_MODULE); + level--; return df; } diff --git a/lang/m2/comp/desig.c b/lang/m2/comp/desig.c index fd7949bb8..c4bc9eb10 100644 --- a/lang/m2/comp/desig.c +++ b/lang/m2/comp/desig.c @@ -232,6 +232,7 @@ CodeVarDesig(df, ds) CodeConst(df->var_off, pointer_size); ds->dsg_kind = DSG_PLOADED; ds->dsg_offset = 0; + df->df_flags |= D_NOREG; return; } @@ -242,6 +243,7 @@ CodeVarDesig(df, ds) ds->dsg_name = df->var_name; ds->dsg_offset = 0; ds->dsg_kind = DSG_FIXED; + df->df_flags |= D_NOREG; return; } @@ -254,6 +256,7 @@ CodeVarDesig(df, ds) ds->dsg_name = &(sc->sc_name[1]); ds->dsg_offset = df->var_off; ds->dsg_kind = DSG_FIXED; + df->df_flags |= D_NOREG; return; } @@ -278,6 +281,7 @@ 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; } @@ -304,6 +308,7 @@ CodeDesig(nd, ds) case Def: { register struct def *df = nd->nd_def; + df->df_flags |= D_USED; switch(df->df_kind) { case D_FIELD: CodeFieldDesig(df, ds); @@ -335,14 +340,16 @@ CodeDesig(nd, ds) *ds = InitDesig; CodeExpr(nd->nd_right, ds, NO_LABEL, NO_LABEL); CodeValue(ds, nd->nd_right->nd_type->tp_size); - CodeCoercion(nd->nd_right->nd_type, int_type); + if (nd->nd_right->nd_type->tp_size > word_size) { + CodeCoercion(nd->nd_right->nd_type, int_type); + } if (IsConformantArray(nd->nd_left->nd_type)) { /* ??? */ } else { /* load address of descriptor */ - /* ??? */ + C_lae_dlb(nd->nd_left->nd_type->arr_descr, (arith) 0); } ds->dsg_kind = DSG_INDEXED; break; diff --git a/lang/m2/comp/enter.c b/lang/m2/comp/enter.c index 782ad9b14..b88dd68d3 100644 --- a/lang/m2/comp/enter.c +++ b/lang/m2/comp/enter.c @@ -67,27 +67,23 @@ EnterIdList(idlist, kind, flags, type, scope, addr) int xalign = type->tp_align; if (xalign < word_align && kind != D_FIELD) { + /* variables are at least word aligned + */ xalign = word_align; } if (*addr >= 0) { - if (scope->sc_level) { + if (scope->sc_level && kind != D_FIELD) { /* alignment of parameters is on word boundaries. We cannot do any better, because we don't know the alignment of the stack pointer when starting to push parameters */ - off = *addr; - *addr = align(off, word_align); - } - else { - /* for global variables we can honour - the alignment requirements totally. - */ - off = align(*addr, xalign); - *addr = off + type->tp_size; + xalign = word_align; } + off = align(*addr, xalign); + *addr = off + type->tp_size; } else { off = -align(-*addr-type->tp_size, xalign); diff --git a/lang/m2/comp/expression.g b/lang/m2/comp/expression.g index 8f306e290..071b306af 100644 --- a/lang/m2/comp/expression.g +++ b/lang/m2/comp/expression.g @@ -25,6 +25,7 @@ number(struct node **p;) struct type *tp; } : [ + %default INTEGER { tp = numtype; } | REAL { tp = real_type; } @@ -46,7 +47,7 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) { if (types) { df = ill_df; - if (chk_designator(nd, 0)) { + if (chk_designator(nd, 0, D_REFERRED)) { if (nd->nd_class != Def) { node_error(nd, "%s expected", str); } @@ -113,9 +114,7 @@ expression(struct node **pnd;) SimpleExpression(pnd) [ /* relation */ - [ '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | - GREATEREQUAL | IN - ] + [ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ] { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); } SimpleExpression(&((*pnd)->nd_right)) ]? @@ -123,7 +122,7 @@ expression(struct node **pnd;) /* Inline in expression relation: - '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN + '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ; */ @@ -184,9 +183,7 @@ factor(struct node **p;) ]? | bare_set(&nd) - { nd->nd_left = *p; - *p = nd; - } + { nd->nd_left = *p; *p = nd; } ] | bare_set(p) @@ -200,9 +197,9 @@ factor(struct node **p;) tp = charc_type; i = *(dot.TOK_STR) & 0377; - free((char *) dot.tk_data.tk_str); free(dot.TOK_STR); - dot.TOK_INT = i; + free((char *) dot.tk_data.tk_str); + (*p)->nd_INT = i; } else tp = standard_type(T_STRING, 1, dot.TOK_SLE); (*p)->nd_type = tp; diff --git a/lang/m2/comp/main.c b/lang/m2/comp/main.c index d4e112d5e..c9b6a3237 100644 --- a/lang/m2/comp/main.c +++ b/lang/m2/comp/main.c @@ -23,13 +23,14 @@ static char *RcsId = "$Header$"; #include "tokenname.h" #include "node.h" +int state; /* either IMPLEMENTATION or PROGRAM */ char options[128]; int DefinitionModule; int SYSTEMModule = 0; char *ProgName; -extern int err_occurred; char *DEFPATH[NDIRS+1]; struct def *Defined; +extern int err_occurred; main(argc, argv) char *argv[]; @@ -93,6 +94,7 @@ Compile(src, dst) C_magic(); C_ms_emx(word_size, pointer_size); CompUnit(); + close_scope(SC_REVERSE); if (err_occurred) { C_close(); return 0; diff --git a/lang/m2/comp/main.h b/lang/m2/comp/main.h index 35a0f9ad1..642f7f5ea 100644 --- a/lang/m2/comp/main.h +++ b/lang/m2/comp/main.h @@ -17,3 +17,4 @@ extern struct def *Defined; compilation */ extern char *DEFPATH[]; /* search path for DEFINITION MODULE's */ +extern int state; /* either IMPLEMENTATION or PROGRAM */ diff --git a/lang/m2/comp/node.c b/lang/m2/comp/node.c index 352347c4a..c2270aa0e 100644 --- a/lang/m2/comp/node.c +++ b/lang/m2/comp/node.c @@ -31,7 +31,7 @@ MkNode(class, left, right, token) nd->nd_right = right; nd->nd_token = *token; nd->nd_class = class; - nd->nd_type = NULLTYPE; + nd->nd_type = error_type; DO_DEBUG(4,(debug("Create node:"), PrNode(nd))); return nd; } diff --git a/lang/m2/comp/program.g b/lang/m2/comp/program.g index 3fb43e3a1..e33952607 100644 --- a/lang/m2/comp/program.g +++ b/lang/m2/comp/program.g @@ -231,7 +231,7 @@ Semicolon: { warning("; expected"); } ; -ProgramModule(int state;) +ProgramModule { struct idf *id; struct def *GetDefinitionModule(); @@ -267,16 +267,15 @@ ProgramModule(int state;) '.' ; -Module -{ - int state = PROGRAM; -} : +Module: DefinitionModule | [ IMPLEMENTATION { state = IMPLEMENTATION; } - ]? - ProgramModule(state) + | + { state = PROGRAM; } + ] + ProgramModule ; CompilationUnit: diff --git a/lang/m2/comp/scope.C b/lang/m2/comp/scope.C index f98998724..a4c5bb3ab 100644 --- a/lang/m2/comp/scope.C +++ b/lang/m2/comp/scope.C @@ -166,7 +166,7 @@ rem_forwards(fo) while (f = fo) { df = lookfor(&(f->fo_tok), CurrVis, 1); - if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) { + if (!(df->df_kind & (D_TYPE|D_ERROR))) { node_error(&(f->fo_tok), "identifier \"%s\" not a type", df->df_idf->id_text); } diff --git a/lang/m2/comp/tokenname.c b/lang/m2/comp/tokenname.c index bb248137f..e6add6124 100644 --- a/lang/m2/comp/tokenname.c +++ b/lang/m2/comp/tokenname.c @@ -24,7 +24,6 @@ struct tokenname tkspec[] = { /* the names of the special tokens */ }; struct tokenname tkcomp[] = { /* names of the composite tokens */ - {UNEQUAL, "<>"}, {LESSEQUAL, "<="}, {GREATEREQUAL, ">="}, {UPTO, ".."}, diff --git a/lang/m2/comp/type.H b/lang/m2/comp/type.H index b0cbd5643..13533ef02 100644 --- a/lang/m2/comp/type.H +++ b/lang/m2/comp/type.H @@ -16,7 +16,7 @@ struct enume { label en_rck; /* Label of range check descriptor */ #define enm_enums tp_value.tp_enum.en_enums #define enm_ncst tp_value.tp_enum.en_ncst -#define enm_rck tp_value.tp_enum.enm_rck +#define enm_rck tp_value.tp_enum.en_rck }; struct subrange { @@ -68,9 +68,10 @@ struct type { #define T_ARRAY 0x2000 #define T_STRING 0x4000 #define T_INTORCARD (T_INTEGER|T_CARDINAL) -#define T_DISCRETE (T_ENUMERATION|T_INTORCARD|T_CHAR) #define T_NUMERIC (T_INTORCARD|T_REAL) #define T_INDEX (T_ENUMERATION|T_CHAR|T_SUBRANGE) +#define T_DISCRETE (T_INDEX|T_INTORCARD) +#define T_PRCRESULT (T_DISCRETE|T_REAL|T_POINTER|T_WORD) int tp_align; /* alignment requirement of this type */ arith tp_size; /* size of this type */ union { @@ -131,3 +132,7 @@ struct type #define NULLTYPE ((struct type *) 0) #define IsConformantArray(tpx) ((tpx)->tp_fund == T_ARRAY && (tpx)->next == 0) +#define bounded(tpx) ((tpx)->tp_fund & T_INDEX) +#define complex(tpx) ((tpx)->tp_fund & (T_RECORD|T_ARRAY)) +#define returntype(tpx) (((tpx)->tp_fund & T_PRCRESULT) ||\ + ((tpx)->tp_fund == T_SET && (tpx)->tp_size <= dword_size)) diff --git a/lang/m2/comp/type.c b/lang/m2/comp/type.c index cdea3b4ee..1ac5eb5ce 100644 --- a/lang/m2/comp/type.c +++ b/lang/m2/comp/type.c @@ -61,6 +61,8 @@ struct paramlist *h_paramlist; struct type *h_type; +extern label data_label(); + struct type * create_type(fund) register int fund; @@ -117,7 +119,7 @@ construct_type(fund, tp) break; default: - assert(0); + crash("funny type constructor"); } return dtp; @@ -325,6 +327,52 @@ subr_type(lb, ub) return res; } +label +getrck(tp) + register struct type *tp; +{ + /* generate a range check descriptor for type "tp" when + neccessary. Return its label + */ + + assert(bounded(tp)); + + 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); + } + 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)); + } + return tp->enm_rck; +} + +getbounds(tp, plo, phi) + register struct type *tp; + arith *plo, *phi; +{ + /* Get the bounds of a bounded type + */ + + assert(bounded(tp)); + + if (tp->tp_fund == T_SUBRANGE) { + *plo = tp->sub_lb; + *phi = tp->sub_ub; + } + else { + *plo = 0; + *phi = tp->enm_ncst - 1; + } +} struct type * set_type(tp) struct type *tp; @@ -385,18 +433,30 @@ ArraySizes(tp) /* find out HIGH, LOW and size of ARRAY */ + tp->arr_descr = data_label(); + C_df_dlb(tp->arr_descr); + switch(index_type->tp_fund) { case T_SUBRANGE: tp->tp_size = elem_size * (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 = elem_size * index_type->enm_ncst; + C_rom_cst((arith) 0); + C_rom_cst((arith) (index_type->enm_ncst - 1)); break; + default: - assert(0); + crash("Funny index type"); } + + C_rom_cst(elem_size); + /* ??? overflow checking ??? */ } diff --git a/lang/m2/comp/walk.c b/lang/m2/comp/walk.c index 111ea1808..b24bcacde 100644 --- a/lang/m2/comp/walk.c +++ b/lang/m2/comp/walk.c @@ -23,14 +23,17 @@ static char *RcsId = "$Header$"; #include "Lpars.h" #include "desig.h" #include "f_info.h" +#include "idf.h" extern arith align(); extern arith NewPtr(); +extern arith NewInt(); extern int proclevel; static label instructionlabel; static char return_expr_occurred; static struct type *func_type; struct withdesig *WithDesigs; +struct node *Modules; label text_label() @@ -88,7 +91,9 @@ WalkModule(module) /* WHY ??? because we generated an INA for it ??? */ C_df_dnam(&(sc->sc_name[1])); + size = align(size, word_align); C_bss_cst(size, (arith) 0, 0); + C_exp(sc->sc_name); } else if (CurrVis == Defined->mod_vis) { /* This module is the module currently being compiled. @@ -98,10 +103,14 @@ WalkModule(module) while (df) { if (df->df_kind == D_VARIABLE) { C_df_dnam(df->var_name); - C_bss_cst(df->df_type->tp_size, (arith) 0, 0); + C_bss_cst( + align(df->df_type->tp_size, word_align), + (arith) 0, 0); } df = df->df_nextinscope; } + if (state == PROGRAM) C_exp("main"); + else C_exp(sc->sc_name); } /* Now, walk through it's local definitions @@ -115,26 +124,55 @@ WalkModule(module) sc->sc_off = 0; instructionlabel = 2; func_type = 0; - C_pro_narg(sc->sc_name); + C_pro_narg(state == PROGRAM ? "main" : sc->sc_name); DoProfil(); + if (CurrVis == Defined->mod_vis) { + /* Body of implementation or program module. + Call initialization routines of imported modules. + Also prevent recursive calls of this one. + */ + label l1 = data_label(), l2 = text_label(); + struct node *nd; + + /* 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_loc((arith) 1); + C_ste_dlb(l1, (arith) 0); + + nd = Modules; + while (nd) { + C_cal(nd->nd_IDF->id_text); + nd = nd->next; + } + } MkCalls(sc->sc_def); + proclevel++; WalkNode(module->mod_body, (label) 0); C_df_ilb((label) 1); - C_ret(0); + C_ret((arith) 0); C_end(-sc->sc_off); + proclevel--; TmpClose(); CurrVis = vis; } WalkProcedure(procedure) - struct def *procedure; + register struct def *procedure; { /* Walk through the definition of a procedure and all its local definitions */ struct scopelist *vis = CurrVis; register struct scope *sc; + register struct type *res_type; proclevel++; CurrVis = procedure->prc_vis; @@ -152,16 +190,19 @@ WalkProcedure(procedure) MkCalls(sc->sc_def); return_expr_occurred = 0; instructionlabel = 2; - func_type = procedure->df_type->next; + func_type = res_type = procedure->df_type->next; + if (! returntype(res_type)) { + node_error(procedure->prc_body, "illegal result type"); + } WalkNode(procedure->prc_body, (label) 0); C_df_ilb((label) 1); - if (func_type) { + if (res_type) { if (! return_expr_occurred) { node_error(procedure->prc_body,"function procedure does not return a value"); } - C_ret((int) align(func_type->tp_size, word_align)); + C_ret(align(res_type->tp_size, word_align)); } - else C_ret(0); + else C_ret((arith) 0); C_end(-sc->sc_off); TmpClose(); CurrVis = vis; @@ -195,6 +236,7 @@ MkCalls(df) if (df->df_kind == D_MODULE) { C_lxl((arith) 0); C_cal(df->mod_vis->sc_scope->sc_name); + C_asp(pointer_size); } df = df->df_nextinscope; } @@ -246,20 +288,8 @@ WalkStat(nd, lab) assert(nd->nd_class == Stat); switch(nd->nd_symb) { - case BECOMES: { - struct desig ds; - - WalkExpr(right, NO_LABEL, NO_LABEL); - ds = Desig; - WalkDesignator(left); /* May we do it in this order??? */ - - if (! TstAssCompat(left->nd_type, right->nd_type)) { - node_error(nd, "type incompatibility in assignment"); - break; - } - - CodeAssign(nd, &ds, pds); - } + case BECOMES: + DoAssign(nd, left, right, 0); break; case IF: @@ -327,8 +357,61 @@ WalkStat(nd, lab) } case FOR: - /* ??? */ - WalkNode(right, lab); + { + arith tmp = 0; + struct node *fnd; + label l1 = instructionlabel++; + label l2 = instructionlabel++; + arith incr = 1; + arith size; + + assert(left->nd_symb == TO); + assert(left->nd_left->nd_symb == BECOMES); + + DoAssign(left->nd_left, + left->nd_left->nd_left, + left->nd_left->nd_right, 1); + fnd = left->nd_right; + if (fnd->nd_symb == BY) { + incr = fnd->nd_left->nd_INT; + fnd = fnd->nd_right; + } + if (! chk_expr(fnd)) return; + size = fnd->nd_type->tp_size; + if (fnd->nd_class != Value) { + *pds = InitDesig; + CodeExpr(fnd, pds, NO_LABEL, NO_LABEL); + CodeValue(pds, size); + tmp = NewInt(); + C_stl(tmp); + } + if (!TstCompat(left->nd_left->nd_left->nd_type, + fnd->nd_type)) { +node_error(fnd, "type incompatibility in limit of FOR loop"); + break; + } + C_bra(l1); + C_df_ilb(l2); + WalkNode(right, lab); + *pds = InitDesig; + C_loc(incr); + CodeDesig(left->nd_left->nd_left, pds); + CodeValue(pds, size); + C_adi(int_size); + *pds = InitDesig; + CodeDesig(left->nd_left->nd_left, pds); + CodeStore(pds, size); + C_df_ilb(l1); + *pds = InitDesig; + CodeDesig(left->nd_left->nd_left, pds); + CodeValue(pds, size); + if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT); + if (incr > 0) { + C_ble(l2); + } + else C_bge(l2); + if (tmp) FreeInt(tmp); + } break; case WITH: @@ -358,7 +441,7 @@ WalkStat(nd, lab) pds->dsg_kind = DSG_PFIXED; /* the record is indirectly available */ } - wds.w_desig = Desig; + wds.w_desig = *pds; link.sc_scope = wds.w_scope; link.next = CurrVis; CurrVis = &link; @@ -432,10 +515,47 @@ WalkDesignator(nd) DO_DEBUG(1, (DumpTree(nd), print("\n"))); - if (! chk_designator(nd, DESIGNATOR|VARIABLE)) return; + if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return; Desig = InitDesig; CodeDesig(nd, &Desig); + +} + +DoAssign(nd, left, right, forloopass) + struct node *nd; + register struct node *left, *right; +{ + /* May we do it in this order (expression first) ??? */ + struct desig ds; + + WalkExpr(right, NO_LABEL, NO_LABEL); + if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return; + + if (forloopass) { + if (! TstCompat(left->nd_type, right->nd_type)) { + node_error(nd, "type incompatibility in FOR loop"); + return; + } + /* Test if the left hand side may be a for loop variable ??? */ + } + else if (! TstAssCompat(left->nd_type, right->nd_type)) { + node_error(nd, "type incompatibility in assignment"); + return; + } + + if (complex(right->nd_type)) { + CodeAddress(&Desig); + } + else { + CodeValue(&Desig, right->nd_type->tp_size); + CheckAssign(left->nd_type, right->nd_type); + } + ds = Desig; + Desig = InitDesig; + CodeDesig(left, &Desig); + + CodeAssign(nd, &ds, &Desig); } #ifdef DEBUG