- 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:
parent
b93c1cb093
commit
efafb68f00
11 changed files with 57 additions and 21 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 :
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in a new issue