walk.o: f_info.h
walk.o: idf.h
walk.o: main.h
+walk.o: misc.h
walk.o: node.h
walk.o: scope.h
walk.o: squeeze.h
-static char Version[] = "ACK Modula-2 compiler Version 0.21";
+static char Version[] = "ACK Modula-2 compiler Version 0.22";
expp->nd_type = error_type;
if (expp->nd_class == Name) {
- expp->nd_def = df = lookfor(expp, CurrVis, 1);
+ df = lookfor(expp, CurrVis, 1, flags);
+ expp->nd_def = df;
expp->nd_class = Def;
expp->nd_type = RemoveEqual(df->df_type);
- df->df_flags |= flags;
}
else if (expp->nd_class == Link) {
/* A selection from a record or a module.
return 0;
}
- if (!(df = lookup(expp->nd_IDF, left->nd_type->rec_scope, 1))) {
+ if (!(df = lookup(expp->nd_IDF, left->nd_type->rec_scope, 1, flags))) {
id_not_declared(expp);
return 0;
}
- df->df_flags |= flags;
expp->nd_def = df;
expp->nd_type = RemoveEqual(df->df_type);
expp->nd_class = Def;
if (nd = expp->nd_left) {
/* A type was given. Check it out
*/
- if (! ChkDesignator(nd)) return 0;
+ if (! ChkDesig(nd, D_USED)) return 0;
assert(nd->nd_class == Def);
df = nd->nd_def;
*/
register t_node *left = nextarg(argp, edf);
- if (!left || ! ChkDesignator(left)) return 0;
+ if (!left || ! ChkDesig(left, D_USED)) return 0;
if (left->nd_class != Def) {
return (t_node *)df_error(left, "identifier expected", edf);
free_it = 1;
break;
+#ifndef STRICT_3RD_ED
case S_NEW:
case S_DISPOSE:
{
if (!warning_given) {
warning_given = 1;
-#ifndef STRICT_3RD_ED
if (! options['3'])
node_warning(expp, W_OLDFASHIONED, "NEW and DISPOSE are obsolete");
else
-#endif
node_error(expp, "NEW and DISPOSE are obsolete");
}
}
-#ifdef STRICT_3RD_ED
- return 0;
-#else
+ left = getvariable(&arg,
+ edf,
+ edf->df_value.df_stdname == S_NEW ? D_DEFINED : D_USED);
expp->nd_type = 0;
- if (! (left = getvariable(&arg, edf,D_DEFINED))) return 0;
+ if (! left) return 0;
if (! (left->nd_type->tp_fund == T_POINTER)) {
return df_error(left, "pointer variable expected", edf);
}
#define D_ERROR 0x4000 /* a compiler generated definition for an
undefined variable
*/
+#define D_IMP_BY_EXP 0x8000 /* imported definition by export */
#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_IMPORTED (D_IMPORT|D_IMP_BY_EXP)
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
unsigned short df_flags;
#define D_NOREG 0x01 /* set if it may not reside in a register */
-#define D_USED 0x02 /* set if used (future use ???) */
-#define D_DEFINED 0x04 /* set if it is assigned a value (future use ???) */
+#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_EXPORTED 0x20 /* set if exported */
df->df_scope = scope;
df->df_kind = kind;
df->df_next = id->id_def;
- df->df_flags = D_USED | D_DEFINED;
id->id_def = df;
if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type;
*/
register t_def *df;
- df = lookup(id, scope, 1);
+ df = lookup(id, scope, 1, 0);
if ( /* Already in this scope */
df
|| /* A closed scope, and id defined in the pervasive scope */
(
scopeclosed(scope)
&&
- (df = lookup(id, PervasiveScope, 1)))
+ (df = lookup(id, PervasiveScope, 1, 0)))
) {
switch(df->df_kind) {
case D_HIDDEN:
register t_def *df = *pdf;
while (df) {
- if (df->df_kind == D_IMPORT) {
+ if (df->df_kind & D_IMPORTED) {
RemoveFromIdList(df);
*pdf = df->df_nextinscope;
free_def(df);
else {
char *name;
- df = lookup(id, CurrentScope, 1);
+ df = lookup(id, CurrentScope, 1, 0);
if (df && df->df_kind == D_PROCHEAD) {
/* C_exp already generated when we saw the definition
in the definition module
t_scope *newsc = CurrentScope;
level += incr;
- df = lookup(id, GlobalScope, 1);
+ df = lookup(id, GlobalScope, 1, 0);
if (!df) {
/* Read definition module. Make an exception for SYSTEM.
*/
DefId = id;
if (!strcmp(id->id_text, "SYSTEM")) {
do_SYSTEM();
- df = lookup(id, GlobalScope, 1);
+ df = lookup(id, GlobalScope, 1, 0);
}
else {
extern int ForeignFlag;
if (!is_anon_idf(id) && GetFile(id->id_text)) {
DefModule();
- df = lookup(id, GlobalScope, 1);
+ df = lookup(id, GlobalScope, 1, 0);
if (level == 1 &&
(!df || !(df->df_flags & D_FOREIGN))) {
/* The module is directly imported by
}
}
else {
- df = lookup(id, GlobalScope, 1);
+ df = lookup(id, GlobalScope, 1, 0);
newsc->sc_name = id->id_text;
}
vis = CurrVis;
indicate "undefined".
.IP \fB-R\fR
disable all range checks.
+.IP \fB-3\fR
+only accept Modula-2 programs that strictly conform to [1].
.LP
.SH FILES
.IR ~em/lib/em_m2 :
binary of the Modula-2 compiler.
.SH SEE ALSO
\fIack\fR(1), \fImodula-2\fR(1)
+.IP [1]
+N. Wirth, \fIProgramming in Modula-2\fP, 3rd edition, Springer Verlag.
.SH DIAGNOSTICS
All warning and error messages are written on standard error output.
.SH REMARKS
}
STATIC
-DoImport(df, scope)
+DoImport(df, scope, kind)
register t_def *df;
t_scope *scope;
{
Handle the case that it is an enumeration type or a module.
*/
- define(df->df_idf, scope, D_IMPORT)->imp_def = df;
+ define(df->df_idf, scope, kind)->imp_def = df;
- while (df->df_kind == D_IMPORT) {
+ while (df->df_kind & D_IMPORTED) {
df = df->imp_def;
}
/* Also import all enumeration literals
*/
for (df = df->df_type->enm_enums; df; df = df->enm_next) {
- define(df->df_idf, scope, D_IMPORT)->imp_def = df;
+ register t_def *df1 = define(df->df_idf, scope, kind);
+
+ df1->imp_def = df;
+ df1->df_flags |= D_USED;/* don't complain when these
+ are not used
+ */
}
}
else if (df->df_kind == D_MODULE) {
df;
df = df->df_nextinscope) {
if (df->df_flags & D_EXPORTED) {
- define(df->df_idf,scope,D_IMPORT)->imp_def = df;
+ register t_def *df1 =
+ define(df->df_idf, scope, kind);
+
+ df1->imp_def = df;
+ df1->df_flags |= D_USED;
+ /* don't complain when these are not used */
}
}
}
*/
register t_def *df;
- if (!(df = lookup(ids->nd_IDF, scope, 0))) {
+ if (!(df = lookup(ids->nd_IDF, scope, 0, 0))) {
df = define(ids->nd_IDF, scope, D_FORWARD);
df->for_node = MkLeaf(Name, &(ids->nd_token));
}
register t_def *df, *df1;
for (;idlist; idlist = idlist->nd_left) {
- df = lookup(idlist->nd_IDF, CurrentScope, 0);
+ df = lookup(idlist->nd_IDF, CurrentScope, 0, 0);
if (!df) {
/* undefined item in export list
*/
df1 = CurrentScope->sc_definedby->df_idf->id_def;
while (df1) {
- if (df1->df_kind == D_IMPORT &&
+ if ((df1->df_kind & D_IMPORTED) &&
df1->imp_def == CurrentScope->sc_definedby) {
- DoImport(df, df1->df_scope);
+ DoImport(df, df1->df_scope, D_IMP_BY_EXP);
}
df1 = df1->df_next;
}
scope imports it.
*/
df1 = lookup(idlist->nd_IDF,
- enclosing(CurrVis)->sc_scope, 1);
+ enclosing(CurrVis)->sc_scope, 1, 0);
if (df1) {
/* It was already defined in the enclosing
scope. There are two legal possibilities,
*/
t_def *df2 = df;
- while (df2->df_kind == D_IMPORT) {
+ while (df2->df_kind & D_IMPORTED) {
df2 = df2->imp_def;
}
if (df1->df_kind == D_PROCHEAD &&
df2->df_kind == D_PROCEDURE) {
- df1->df_kind = D_IMPORT;
+ df1->df_kind = D_IMP_BY_EXP;
df1->imp_def = df;
continue;
}
}
}
- DoImport(df, enclosing(CurrVis)->sc_scope);
+ DoImport(df, enclosing(CurrVis)->sc_scope, D_IMP_BY_EXP);
}
}
FreeNode(Idlist);
for (; idlist; idlist = idlist->nd_left) {
if (forwflag) df = ForwDef(idlist, vis->sc_scope);
- else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0))) {
+ else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0, 0))) {
if (! is_anon_idf(idlist->nd_IDF)) {
node_error(idlist,
"identifier \"%s\" not declared in module \"%s\"",
module_name);
df->df_flags |= D_QEXPORTED;
}
- DoImport(df, CurrentScope);
+ DoImport(df, CurrentScope, D_IMPORT);
}
if (!forwflag) FreeNode(FromId);
f = file_info;
for (; idlist; idlist = idlist->nd_left) {
- DoImport(GetDefinitionModule(idlist->nd_IDF, 1), CurrentScope);
+ DoImport(GetDefinitionModule(idlist->nd_IDF, 1), CurrentScope, D_IMPORT);
file_info = f;
}
}
/* Import "idlist" from the enclosing scope.
*/
t_scope *sc = enclosing(CurrVis)->sc_scope;
- extern t_def *GetDefinitionModule();
for (; idlist; idlist = idlist->nd_left) {
- t_def *df;
-
- DoImport(ForwDef(idlist, sc), CurrentScope);
- df = lookup(idlist->nd_def, CurrentScope, 0);
- df->df_flags |= D_EXPORTED;
+ DoImport(ForwDef(idlist, sc), CurrentScope, D_IMPORT);
}
}
#include "misc.h"
t_def *
-lookup(id, scope, import)
+lookup(id, scope, import, flags)
register t_idf *id;
t_scope *scope;
{
df->df_next = id->id_def;
id->id_def = df;
}
+ df->df_flags |= flags;
if (import) {
- while (df->df_kind == D_IMPORT) {
+ while (df->df_kind & D_IMPORTED) {
assert(df->imp_def != 0);
df = df->imp_def;
}
}
t_def *
-lookfor(id, vis, give_error)
+lookfor(id, vis, message, flags)
register t_node *id;
t_scopelist *vis;
{
/* Look for an identifier in the visibility range started by "vis".
If it is not defined create a dummy definition and,
- if "give_error" is set, give an error message.
+ if message is set, give an error message
*/
register t_def *df;
register t_scopelist *sc = vis;
while (sc) {
- df = lookup(id->nd_IDF, sc->sc_scope, 1);
+ df = lookup(id->nd_IDF, sc->sc_scope, 1, flags);
if (df) return df;
sc = nextvisible(sc);
}
- if (give_error) id_not_declared(id);
+ if (message) id_not_declared(id);
df = MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
return df;
{ "DEC", S_DEC },
{ "INC", S_INC },
{ "VAL", S_VAL },
+#ifndef STRICT_3RD_ED
{ "NEW", S_NEW },
{ "DISPOSE", S_DISPOSE },
+#endif
{ "TRUNC", S_TRUNC },
{ "SIZE", S_SIZE },
{ "ORD", S_ORD },
} :
[ FROM
IDENT { FromId = dot2leaf(Name);
- if (local) df = lookfor(FromId,enclosing(CurrVis),0);
+ if (local) {
+ df = lookfor(FromId,enclosing(CurrVis),0,D_USED);
+ }
else df = GetDefinitionModule(dot.TOK_IDF, 1);
}
]?
*pdf = df->df_nextinscope;
RemoveFromIdList(df);
- df = lookfor(nd, CurrVis, 1);
+ 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);
}
assert(sc != 0);
- if (! sc->sc_end) {
- sc->sc_end = dot2leaf(Link);
- }
+ FreeNode(sc->sc_end);
+ sc->sc_end = dot2leaf(Link);
if (flag) {
DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def)));
{
register t_def *df;
- if (ChkDesignator(nd)) {
+ if (ChkDesig(nd, D_USED)) {
if (nd->nd_class != Def) {
node_error(nd, "type expected");
FreeNode(nd);
register t_node *nd;
register t_def *df, *df1;
- if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1))) {
+ if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1, D_USED))) {
/* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification
*/
return 1;
}
nd = dot2leaf(0);
- if ((df1 = lookfor(nd, CurrVis, 0))->df_kind == D_MODULE) {
+ if ((df1 = lookfor(nd, CurrVis, 0, D_USED))->df_kind == D_MODULE) {
/* A Modulename in one of the enclosing scopes.
It is not clear from the language definition that
it is correct to handle these like this, but
#include "idf.h"
#include "chk_expr.h"
#include "walk.h"
+#include "misc.h"
#include "warning.h"
extern arith NewPtr();
if (!TstCompat(df->df_type, tpl) ||
!TstCompat(df->df_type, tpr)) {
node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
- node_error(nd, "compatibility required in FOR statement");
}
} else
#endif
UseWarnings(df)
register t_def *df;
{
- if (df->df_kind & (D_IMPORT | D_VARIABLE | D_PROCEDURE)) {
+ if (is_anon_idf(df->df_idf)) return;
+ if (df->df_kind & (D_IMPORTED | D_VARIABLE | D_PROCEDURE)) {
struct node *nd;
if (df->df_flags & (D_EXPORTED | D_QEXPORTED)) return;
- if (df->df_kind == D_IMPORT) df = df->imp_def;
+ if (df->df_kind & D_IMPORTED) {
+ register t_def *df1 = df->imp_def;
+
+ df1->df_flags |= df->df_flags & (D_USED|D_DEFINED);
+ if (df->df_kind == D_IMPORT) {
+ if (! (df->df_flags & (D_USED | D_DEFINED))) {
+ node_warning(
+ df->df_scope->sc_end,
+ W_ORDINARY,
+ "identifier \"%s\" imported but not used/assigned",
+ df->df_idf->id_text);
+ }
+ return;
+ }
+ df = df1;
+ }
if (! (df->df_kind & (D_VARIABLE|D_PROCEDURE))) return;
nd = df->df_scope->sc_end;
if (! (df->df_flags & D_DEFINED)) {