fixed some problems:

- removed null-reference in illegal use of pointers in constant expressions
- FOR-loops that count downwards did not work
- POINTER TO mechanism changed; works better now
This commit is contained in:
ceriel 1988-11-15 14:45:59 +00:00
parent 090f27251e
commit f1245e2e00
8 changed files with 86 additions and 49 deletions

View file

@ -161,7 +161,8 @@ ChkArrow(expp)
return ex_error(expp, "illegal operand type"); return ex_error(expp, "illegal operand type");
} }
expp->nd_type = RemoveEqual(PointedtoType(tp)); if ((tp = RemoveEqual(PointedtoType(tp))) == 0) tp = error_type;
expp->nd_type = tp;
return 1; return 1;
} }

View file

@ -71,7 +71,9 @@ struct dforward {
struct forwtype { struct forwtype {
struct node *f_node; struct node *f_node;
struct def *f_def;
#define df_forw_node df_value.df_fortype.f_node #define df_forw_node df_value.df_fortype.f_node
#define df_forw_def df_value.df_fortype.f_def
}; };
struct def { /* list of definitions for a name */ struct def { /* list of definitions for a name */
@ -94,14 +96,13 @@ struct def { /* list of definitions for a name */
#define D_FORWARD 0x0400 /* not yet defined */ #define D_FORWARD 0x0400 /* not yet defined */
#define D_FORWMODULE 0x0800 /* module must be declared later */ #define D_FORWMODULE 0x0800 /* module must be declared later */
#define D_FORWTYPE 0x1000 /* forward type */ #define D_FORWTYPE 0x1000 /* forward type */
#define D_FTYPE 0x2000 /* resolved forward type */
#define D_ERROR 0x4000 /* a compiler generated definition for an #define D_ERROR 0x4000 /* a compiler generated definition for an
undefined variable undefined variable
*/ */
#define D_INUSE 0x8000 /* identification in this scope (like D_IMPORT) #define D_INUSE 0x8000 /* identification in this scope (like D_IMPORT)
*/ */
#define D_VALUE (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD) #define D_VALUE (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD)
#define D_ISTYPE (D_HIDDEN|D_TYPE|D_FTYPE) #define D_ISTYPE (D_HIDDEN|D_TYPE)
#define D_IMPORTED (D_IMPORT|D_INUSE) #define D_IMPORTED (D_IMPORT|D_INUSE)
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE) #define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
unsigned short df_flags; unsigned short df_flags;

View file

@ -157,10 +157,7 @@ define(id, scope, kind)
if (kind == D_FORWTYPE) return df; if (kind == D_FORWTYPE) return df;
break; break;
case D_FORWTYPE: case D_FORWTYPE:
if (kind == D_FORWTYPE) return df; if (kind & (D_FORWTYPE|D_TYPE)) return df;
if (kind == D_TYPE) {
df->df_kind = D_FTYPE;
}
else { else {
error("identifier \"%s\" must be a type", error("identifier \"%s\" must be a type",
id->id_text); id->id_text);

View file

@ -251,8 +251,7 @@ ImportEffects(idef, scope, flag)
} }
tp = BaseType(df->df_type); tp = BaseType(df->df_type);
if ((df->df_kind & (D_TYPE|D_FTYPE)) && if (df->df_kind == D_TYPE && tp->tp_fund == T_ENUMERATION) {
tp->tp_fund == T_ENUMERATION) {
/* Also import all enumeration literals /* Also import all enumeration literals
*/ */
for (df = tp->enm_enums; df; df = df->enm_next) { for (df = tp->enm_enums; df; df = df->enm_next) {
@ -416,7 +415,7 @@ EnterExportList(Idlist, qualified)
continue; continue;
} }
if (df1->df_kind == D_HIDDEN && if (df1->df_kind == D_HIDDEN &&
(df2->df_kind & (D_TYPE|D_FTYPE))) { df2->df_kind == D_TYPE) {
DeclareType(idlist, df1, df2->df_type); DeclareType(idlist, df1, df2->df_type);
df1->df_kind = D_TYPE; df1->df_kind = D_TYPE;
continue; continue;

View file

@ -189,6 +189,7 @@ definition
[ %persistent [ %persistent
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); } IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
[ '=' type(&(df->df_type)) [ '=' type(&(df->df_type))
{ SolveForwardTypeRefs(df); }
| /* empty */ | /* empty */
/* /*
Here, the exported type has a hidden implementation. Here, the exported type has a hidden implementation.

View file

@ -109,34 +109,10 @@ chk_forw(pdf)
while (df = *pdf) { while (df = *pdf) {
if (df->df_kind == D_FORWTYPE) { if (df->df_kind == D_FORWTYPE) {
register t_def *df1 = df; ForceForwardTypeDef(df); /* removes df */
register t_node *nd = df->df_forw_node;
*pdf = df->df_nextinscope;
RemoveFromIdList(df);
df = lookfor(nd, CurrVis, 1, 0);
if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) {
node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
}
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df1->df_forw_node);
free_def(df1);
continue; continue;
} }
else if (df->df_kind == D_FTYPE) { if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
register t_node *nd = df->df_forw_node;
df->df_kind = D_TYPE;
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df->df_forw_node);
}
else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
/* These definitions must be found in /* These definitions must be found in
the enclosing closed scope, which of course the enclosing closed scope, which of course
may be the scope that is now closed! may be the scope that is now closed!

View file

@ -269,7 +269,11 @@ node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
} }
FreeNode(nd); FreeNode(nd);
if (df->df_kind == D_FORWTYPE) { if (df->df_kind == D_FORWTYPE) {
df->df_kind = D_FTYPE; /* Here, df->df_type was already set,
so there is an actual definition in the
surrounding scope, which is now used.
*/
ForceForwardTypeDef(df);
} }
return df->df_type; return df->df_type;
} }
@ -646,6 +650,58 @@ DeclareType(nd, df, tp)
CheckForImports(df); CheckForImports(df);
} }
} }
SolveForwardTypeRefs(df);
}
SolveForwardTypeRefs(df)
register t_def *df;
{
register t_node *nd;
if (df->df_kind == D_FORWTYPE) {
nd = df->df_forw_node;
df->df_kind = D_TYPE;
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df->df_forw_node);
}
}
ForceForwardTypeDef(df)
register t_def *df;
{
register t_def *df1 = df, *df2;
register t_node *nd = df->df_forw_node;
while (df && df->df_kind == D_FORWTYPE) {
RemoveFromIdList(df);
if ((df2 = df->df_scope->sc_def) == df) {
df->df_scope->sc_def = df->df_nextinscope;
}
else {
while (df2->df_nextinscope != df) {
df2 = df2->df_nextinscope;
}
df2->df_nextinscope = df->df_nextinscope;
}
df = df->df_forw_def;
}
df = lookfor(nd, CurrVis, 1, 0);
if (! df->df_kind & (D_ERROR|D_TYPE)) {
node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
}
while (df1 && df1->df_kind == D_FORWTYPE) {
t_def *df2 = df1->df_forw_def;
df1->df_type = df->df_type;
SolveForwardTypeRefs(df1);
free_def(df1);
df1 = df2;
}
} }
t_type * t_type *
@ -686,6 +742,8 @@ type_or_forward(ptp)
existing compilers do it like this, and the existing compilers do it like this, and the
alternative is difficult with a lookahead of only alternative is difficult with a lookahead of only
one token. one token.
This path should actually only be taken if the next token
is a '.'.
??? ???
*/ */
FreeNode(nd); FreeNode(nd);
@ -697,17 +755,17 @@ type_or_forward(ptp)
same scope. same scope.
*/ */
df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE); df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
assert(df->df_kind == D_FORWTYPE);
df->df_flags |= D_USED | D_DEFINED; df->df_flags |= D_USED | D_DEFINED;
if (df->df_kind == D_TYPE) {
(*ptp)->tp_next = df->df_type;
FreeNode(nd);
return 0;
}
nd->nd_type = *ptp; nd->nd_type = *ptp;
df->df_forw_node = nd; df->df_forw_node = nd;
if (df1->df_kind == D_TYPE) { if (df != df1 && (df1->df_kind & (D_TYPE | D_FORWTYPE))) {
/* "df1" refers to a possible identification, but
we cannot be sure at this point. For the time
being, however, we use this one.
*/
df->df_type = df1->df_type; df->df_type = df1->df_type;
df->df_forw_def = df1;
} }
return 0; return 0;
} }

View file

@ -552,8 +552,10 @@ WalkStat(nd, exit_label)
C_lol(tmp); C_lol(tmp);
if (uns) C_cmu(int_size); if (uns) C_cmu(int_size);
else C_cmi(int_size); else C_cmi(int_size);
C_zgt(l2); if (left->nd_INT >= 0) C_zgt(l2);
else C_zlt(l2);
C_lol(tmp2); C_lol(tmp2);
RangeCheck(nd->nd_type, left->nd_left->nd_type);
CodeDStore(nd); CodeDStore(nd);
C_lol(tmp); C_lol(tmp);
ForLoopVarExpr(nd); ForLoopVarExpr(nd);
@ -736,6 +738,7 @@ DoForInit(nd)
{ {
register t_node *left = nd->nd_left; register t_node *left = nd->nd_left;
register t_def *df; register t_def *df;
register t_type *base_tp;
t_type *tpl, *tpr; t_type *tpl, *tpr;
nd->nd_left = nd->nd_right = 0; nd->nd_left = nd->nd_right = 0;
@ -778,12 +781,13 @@ DoForInit(nd)
return 1; return 1;
} }
base_tp = BaseType(df->df_type);
tpl = left->nd_left->nd_type; tpl = left->nd_left->nd_type;
tpr = left->nd_right->nd_type; tpr = left->nd_right->nd_type;
#ifndef STRICT_3RD_ED #ifndef STRICT_3RD_ED
if (! options['3']) { if (! options['3']) {
if (!ChkAssCompat(&(left->nd_left), df->df_type, "FOR statement") || if (!ChkAssCompat(&(left->nd_left), base_tp, "FOR statement") ||
!ChkAssCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) { !ChkAssCompat(&(left->nd_right), base_tp, "FOR statement")) {
return 1; return 1;
} }
if (!TstCompat(df->df_type, tpl) || if (!TstCompat(df->df_type, tpl) ||
@ -792,8 +796,8 @@ node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
} }
} else } else
#endif #endif
if (!ChkCompat(&(left->nd_left), df->df_type, "FOR statement") || if (!ChkCompat(&(left->nd_left), base_tp, "FOR statement") ||
!ChkCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) { !ChkCompat(&(left->nd_right), base_tp, "FOR statement")) {
return 1; return 1;
} }