- fixes: improved POINTER TO IDENT mechanism, prevent core dump when

definition module not found, corrected typo.
- changed mechanism for variables that have their address given.
- added option for symmetric integer ranges
This commit is contained in:
ceriel 1987-06-29 12:46:00 +00:00
parent b93c1cb093
commit efafb68f00
11 changed files with 57 additions and 21 deletions

View file

@ -177,7 +177,7 @@ CodeCoercion(t1, t2)
fund1 = T_CARDINAL; fund1 = T_CARDINAL;
break; break;
} }
switch(fund2 = t1->tp_fund) { switch(fund2 = t2->tp_fund) {
case T_WORD: case T_WORD:
fund2 = T_INTEGER; fund2 = T_INTEGER;
break; break;
@ -556,7 +556,10 @@ CodeStd(nd)
if (tp->tp_fund == T_INTEGER) C_adi(size); if (tp->tp_fund == T_INTEGER) C_adi(size);
else C_adu(size); else C_adu(size);
} }
if (size == word_size) RangeCheck(tp, int_type); if (size == word_size) {
RangeCheck(tp, tp->tp_fund == T_INTEGER ?
int_type : card_type);
}
CodeDStore(left); CodeDStore(left);
break; break;
} }

View file

@ -21,10 +21,8 @@ struct module {
struct variable { struct variable {
arith va_off; /* address or offset of variable */ arith va_off; /* address or offset of variable */
char *va_name; /* name of variable if given */ char *va_name; /* name of variable if given */
char va_addrgiven; /* an address was given in the program */
#define var_off df_value.df_variable.va_off #define var_off df_value.df_variable.va_off
#define var_name df_value.df_variable.va_name #define var_name df_value.df_variable.va_name
#define var_addrgiven df_value.df_variable.va_addrgiven
}; };
struct constant { struct constant {
@ -74,8 +72,6 @@ struct dforward {
struct forwtype { struct forwtype {
struct node *f_node; struct node *f_node;
struct type *f_type;
#define df_forw_type df_value.df_fortype.f_type
#define df_forw_node df_value.df_fortype.f_node #define df_forw_node df_value.df_fortype.f_node
}; };
@ -116,6 +112,7 @@ struct def { /* list of definitions for a name */
#define D_QEXPORTED 0x40 /* set if qualified exported */ #define D_QEXPORTED 0x40 /* set if qualified exported */
#define D_BUSY 0x80 /* set if busy reading this definition module */ #define D_BUSY 0x80 /* set if busy reading this definition module */
#define D_FOREIGN 0x100 /* set for foreign language modules */ #define D_FOREIGN 0x100 /* set for foreign language modules */
#define D_ADDRGIVEN 0x200 /* set if address given for variable */
struct type *df_type; struct type *df_type;
union { union {
struct module df_module; struct module df_module;

View file

@ -142,7 +142,6 @@ define(id, scope, kind)
if (kind == D_FORWTYPE) return df; if (kind == D_FORWTYPE) return df;
if (kind == D_TYPE) { if (kind == D_TYPE) {
df->df_kind = D_FTYPE; df->df_kind = D_FTYPE;
FreeNode(df->df_forw_node);
} }
else { else {
error("identifier \"%s\" must be a type", error("identifier \"%s\" must be a type",

View file

@ -94,6 +94,7 @@ GetDefinitionModule(id, incr)
struct scopelist *vis; struct scopelist *vis;
char *fn = FileName; char *fn = FileName;
int ln = LineNumber; int ln = LineNumber;
struct scope *newsc = CurrentScope;
level += incr; level += incr;
df = lookup(id, GlobalScope, 1); df = lookup(id, GlobalScope, 1);
@ -110,6 +111,7 @@ GetDefinitionModule(id, incr)
ForeignFlag = 0; ForeignFlag = 0;
open_scope(CLOSEDSCOPE); open_scope(CLOSEDSCOPE);
newsc = CurrentScope;
if (!is_anon_idf(id) && GetFile(id->id_text)) { if (!is_anon_idf(id) && GetFile(id->id_text)) {
DefModule(); DefModule();
@ -136,7 +138,7 @@ GetDefinitionModule(id, incr)
} }
else { else {
df = lookup(id, GlobalScope, 1); df = lookup(id, GlobalScope, 1);
CurrentScope->sc_name = id->id_text; newsc->sc_name = id->id_text;
} }
vis = CurrVis; vis = CurrVis;
close_scope(SC_CHKFORW); close_scope(SC_CHKFORW);
@ -145,6 +147,7 @@ GetDefinitionModule(id, incr)
df = MkDef(id, GlobalScope, D_ERROR); df = MkDef(id, GlobalScope, D_ERROR);
df->df_type = error_type; df->df_type = error_type;
df->mod_vis = vis; df->mod_vis = vis;
newsc->sc_definedby = df;
} }
} }
else if (df->df_flags & D_BUSY) { else if (df->df_flags & D_BUSY) {

View file

@ -438,7 +438,7 @@ CodeVarDesig(df, ds)
*/ */
assert(ds->dsg_kind == DSG_INIT); assert(ds->dsg_kind == DSG_INIT);
if (df->var_addrgiven) { if (df->df_flags & D_ADDRGIVEN) {
/* the programmer specified an address in the declaration of /* the programmer specified an address in the declaration of
the variable. Generate code to push the address. the variable. Generate code to push the address.
*/ */

View file

@ -65,6 +65,10 @@ make all procedure names global, so that \fIadb\fR(1) understands them.
.IP \fB\-i\fR\fInum\fR .IP \fB\-i\fR\fInum\fR
maximum number of bits in a set. When not used, a default value is maximum number of bits in a set. When not used, a default value is
retained. retained.
.IP \fB\-s\fR
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
This is useful for interpreters that use the "real" MIN(INTEGER) to
indicate "undefined".
.LP .LP
.SH FILES .SH FILES
.IR ~em/lib/em_m2 : .IR ~em/lib/em_m2 :

View file

@ -133,8 +133,7 @@ EnterVarList(Idlist, type, local)
*/ */
register struct type *tp = idlist->nd_left->nd_type; register struct type *tp = idlist->nd_left->nd_type;
df->var_addrgiven = 1; df->df_flags |= D_ADDRGIVEN | D_NOREG;
df->df_flags |= D_NOREG;
if (tp != error_type && !(tp->tp_fund & T_CARDINAL)){ if (tp != error_type && !(tp->tp_fund & T_CARDINAL)){
node_error(idlist->nd_left, node_error(idlist->nd_left,
"illegal type for address"); "illegal type for address");

View file

@ -80,6 +80,10 @@ By default, warnings in class \fBO\fR and \fBW\fR are given.
allow for warning messages whose class is a member of \fIclasses\fR. allow for warning messages whose class is a member of \fIclasses\fR.
.IP \fB\-x\fR .IP \fB\-x\fR
make all procedure names global, so that \fIadb\fR(1) understands them. make all procedure names global, so that \fIadb\fR(1) understands them.
.IP \fB\-Xs\fR
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
This is useful for interpreters that use the "real" MIN(INTEGER) to
indicate "undefined".
.LP .LP
.SH SEE ALSO .SH SEE ALSO
\fIack\fR(1), \fIem_m2\fR(6) \fIack\fR(1), \fIem_m2\fR(6)

View file

@ -117,21 +117,31 @@ chk_forw(pdf)
while (df = *pdf) { while (df = *pdf) {
if (df->df_kind == D_FORWTYPE) { if (df->df_kind == D_FORWTYPE) {
register struct def *df1 = df; register struct def *df1 = df;
register struct node *nd = df->df_forw_node;
*pdf = df->df_nextinscope; *pdf = df->df_nextinscope;
RemoveFromIdList(df); RemoveFromIdList(df);
df = lookfor(df->df_forw_node, CurrVis, 1); df = lookfor(nd, CurrVis, 1);
if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) { if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) {
node_error(df1->df_forw_node, "\"%s\" is not a type", df1->df_idf->id_text); node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
}
while (nd) {
nd->nd_type->next = df->df_type;
nd = nd->nd_right;
} }
df1->df_forw_type->next = df->df_type;
FreeNode(df1->df_forw_node); FreeNode(df1->df_forw_node);
free_def(df1); free_def(df1);
continue; continue;
} }
else if (df->df_kind == D_FTYPE) { else if (df->df_kind == D_FTYPE) {
register struct node *nd = df->df_forw_node;
df->df_kind = D_TYPE; df->df_kind = D_TYPE;
df->df_forw_type->next = df->df_type; while (nd) {
nd->nd_type->next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df->df_forw_node);
} }
else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) { else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
/* These definitions must be found in /* These definitions must be found in

View file

@ -249,11 +249,16 @@ qualified_type(nd)
else { else {
register struct def *df = nd->nd_def; register struct def *df = nd->nd_def;
if (df->df_kind&(D_ISTYPE|D_FORWARD|D_ERROR)) { if (df->df_kind&(D_ISTYPE|D_FORWARD|D_FORWTYPE|D_ERROR)) {
if (! df->df_type) { if (! df->df_type) {
node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text); node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
} }
else tp = df->df_type; else {
if (df->df_kind == D_FORWTYPE) {
df->df_kind = D_FTYPE;
}
tp = df->df_type;
}
} }
else { else {
node_error(nd,"identifier \"%s\" is not a type", df->df_idf->id_text); node_error(nd,"identifier \"%s\" is not a type", df->df_idf->id_text);
@ -577,17 +582,25 @@ type_or_forward(ptp)
in "dot". This routine handles the different cases. in "dot". This routine handles the different cases.
*/ */
register struct node *nd; register struct node *nd;
register struct def *df1;
*ptp = construct_type(T_POINTER, NULLTYPE); *ptp = construct_type(T_POINTER, NULLTYPE);
if (lookup(dot.TOK_IDF, CurrentScope, 1)) { if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1))) {
/* Either a Module or a Type, but in both cases defined /* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification in this scope, so this is the correct identification
*/ */
if (df1->df_kind == D_FORWTYPE) {
nd = new_node();
nd->nd_token = dot;
nd->nd_right = df1->df_forw_node;
df1->df_forw_node = nd;
nd->nd_type = *ptp;
}
return 1; return 1;
} }
nd = new_node(); nd = new_node();
nd->nd_token = dot; nd->nd_token = dot;
if (lookfor(nd, CurrVis, 0)->df_kind == D_MODULE) { if ((df1 = lookfor(nd, CurrVis, 0))->df_kind == D_MODULE) {
/* A Modulename in one of the enclosing scopes. /* A Modulename in one of the enclosing scopes.
It is not clear from the language definition that It is not clear from the language definition that
it is correct to handle these like this, but it is correct to handle these like this, but
@ -610,10 +623,14 @@ type_or_forward(ptp)
if (df->df_kind == D_TYPE) { if (df->df_kind == D_TYPE) {
(*ptp)->next = df->df_type; (*ptp)->next = df->df_type;
free_node(nd);
} }
else { else {
df->df_forw_type = *ptp; nd->nd_type = *ptp;
df->df_forw_node = nd; df->df_forw_node = nd;
if (df1->df_kind == D_TYPE) {
df->df_type = df1->df_type;
}
} }
} }
return 0; return 0;

View file

@ -325,7 +325,7 @@ WalkDef(df)
WalkProcedure(df); WalkProcedure(df);
break; break;
case D_VARIABLE: case D_VARIABLE:
if (!proclevel && !df->var_addrgiven) { if (!proclevel && !(df->df_flags & D_ADDRGIVEN)) {
C_df_dnam(df->var_name); C_df_dnam(df->var_name);
C_bss_cst( C_bss_cst(
WA(df->df_type->tp_size), WA(df->df_type->tp_size),