New version, with an option for strict Modula-2, and

warnings for unused or uninitialized variables
This commit is contained in:
ceriel 1987-10-19 11:28:37 +00:00
parent 211d2bcfff
commit 503edee161
21 changed files with 341 additions and 196 deletions

View file

@ -40,7 +40,7 @@ OBJ = $(COBJ) $(LOBJ) Lpars.o
GENH= errout.h\ GENH= errout.h\
idfsize.h numsize.h strsize.h target_sizes.h \ idfsize.h numsize.h strsize.h target_sizes.h \
inputtype.h maxset.h density.h squeeze.h \ inputtype.h maxset.h density.h squeeze.h \
def.h debugcst.h type.h Lpars.h node.h desig.h def.h debugcst.h type.h Lpars.h node.h desig.h strict3rd.h
HFILES= LLlex.h\ HFILES= LLlex.h\
chk_expr.h class.h const.h debug.h f_info.h idf.h\ chk_expr.h class.h const.h debug.h f_info.h idf.h\
input.h main.h misc.h scope.h standards.h tokenname.h\ input.h main.h misc.h scope.h standards.h tokenname.h\
@ -181,6 +181,7 @@ error.o: input.h
error.o: inputtype.h error.o: inputtype.h
error.o: main.h error.o: main.h
error.o: node.h error.o: node.h
error.o: strict3rd.h
error.o: warning.h error.o: warning.h
main.o: LLlex.h main.o: LLlex.h
main.o: Lpars.h main.o: Lpars.h
@ -195,6 +196,7 @@ main.o: inputtype.h
main.o: node.h main.o: node.h
main.o: scope.h main.o: scope.h
main.o: standards.h main.o: standards.h
main.o: strict3rd.h
main.o: tokenname.h main.o: tokenname.h
main.o: type.h main.o: type.h
main.o: warning.h main.o: warning.h
@ -264,7 +266,9 @@ typequiv.o: debug.h
typequiv.o: debugcst.h typequiv.o: debugcst.h
typequiv.o: def.h typequiv.o: def.h
typequiv.o: idf.h typequiv.o: idf.h
typequiv.o: main.h
typequiv.o: node.h typequiv.o: node.h
typequiv.o: strict3rd.h
typequiv.o: type.h typequiv.o: type.h
typequiv.o: warning.h typequiv.o: warning.h
node.o: LLlex.h node.o: LLlex.h
@ -291,14 +295,17 @@ chk_expr.o: debug.h
chk_expr.o: debugcst.h chk_expr.o: debugcst.h
chk_expr.o: def.h chk_expr.o: def.h
chk_expr.o: idf.h chk_expr.o: idf.h
chk_expr.o: main.h
chk_expr.o: misc.h chk_expr.o: misc.h
chk_expr.o: node.h chk_expr.o: node.h
chk_expr.o: scope.h chk_expr.o: scope.h
chk_expr.o: standards.h chk_expr.o: standards.h
chk_expr.o: strict3rd.h
chk_expr.o: type.h chk_expr.o: type.h
chk_expr.o: warning.h chk_expr.o: warning.h
options.o: idfsize.h options.o: idfsize.h
options.o: main.h options.o: main.h
options.o: strict3rd.h
options.o: type.h options.o: type.h
options.o: warning.h options.o: warning.h
walk.o: LLlex.h walk.o: LLlex.h
@ -314,6 +321,7 @@ walk.o: main.h
walk.o: node.h walk.o: node.h
walk.o: scope.h walk.o: scope.h
walk.o: squeeze.h walk.o: squeeze.h
walk.o: strict3rd.h
walk.o: type.h walk.o: type.h
walk.o: walk.h walk.o: walk.h
walk.o: warning.h walk.o: warning.h
@ -360,6 +368,7 @@ program.o: idf.h
program.o: main.h program.o: main.h
program.o: node.h program.o: node.h
program.o: scope.h program.o: scope.h
program.o: strict3rd.h
program.o: type.h program.o: type.h
program.o: warning.h program.o: warning.h
declar.o: LLlex.h declar.o: LLlex.h
@ -373,6 +382,7 @@ declar.o: main.h
declar.o: misc.h declar.o: misc.h
declar.o: node.h declar.o: node.h
declar.o: scope.h declar.o: scope.h
declar.o: strict3rd.h
declar.o: type.h declar.o: type.h
declar.o: warning.h declar.o: warning.h
expression.o: LLlex.h expression.o: LLlex.h
@ -401,6 +411,7 @@ casestat.o: Lpars.h
casestat.o: chk_expr.h casestat.o: chk_expr.h
casestat.o: debug.h casestat.o: debug.h
casestat.o: debugcst.h casestat.o: debugcst.h
casestat.o: def.h
casestat.o: density.h casestat.o: density.h
casestat.o: desig.h casestat.o: desig.h
casestat.o: node.h casestat.o: node.h

View file

@ -65,3 +65,10 @@
#undef SQUEEZE 1 /* define on "small" machines */ #undef SQUEEZE 1 /* define on "small" machines */
!File: strict3rd.h
#undef STRICT_3RD_ED 1 /* define on "small" machines, and if you want
a compiler that only implements "3rd edition"
Modula-2
*/

View file

@ -11,8 +11,15 @@
/* Text of SYSTEM module, for as far as it can be expressed in Modula-2 */ /* Text of SYSTEM module, for as far as it can be expressed in Modula-2 */
#ifndef STRICT_3RD_ED
#define SYSTEMTEXT "DEFINITION MODULE SYSTEM;\n\ #define SYSTEMTEXT "DEFINITION MODULE SYSTEM;\n\
TYPE PROCESS = ADDRESS;\n\ TYPE PROCESS = ADDRESS;\n\
PROCEDURE NEWPROCESS(P:PROC; A:ADDRESS; n:CARDINAL; VAR p1:ADDRESS);\n\ PROCEDURE NEWPROCESS(P:PROC; A:ADDRESS; n:CARDINAL; VAR p1:ADDRESS);\n\
PROCEDURE TRANSFER(VAR p1,p2:ADDRESS);\n\ PROCEDURE TRANSFER(VAR p1,p2:ADDRESS);\n\
END SYSTEM.\n" END SYSTEM.\n"
#else
#define SYSTEMTEXT "DEFINITION MODULE SYSTEM;\n\
PROCEDURE NEWPROCESS(P:PROC; A:ADDRESS; n:CARDINAL; VAR p1:ADDRESS);\n\
PROCEDURE TRANSFER(VAR p1,p2:ADDRESS);\n\
END SYSTEM.\n"
#endif

View file

@ -1 +1 @@
static char Version[] = "ACK Modula-2 compiler Version 0.20"; static char Version[] = "ACK Modula-2 compiler Version 0.21";

View file

@ -32,6 +32,7 @@
#include "desig.h" #include "desig.h"
#include "walk.h" #include "walk.h"
#include "chk_expr.h" #include "chk_expr.h"
#include "def.h"
#include "density.h" #include "density.h"

View file

@ -19,6 +19,7 @@
#include <assert.h> #include <assert.h>
#include <alloc.h> #include <alloc.h>
#include "strict3rd.h"
#include "Lpars.h" #include "Lpars.h"
#include "idf.h" #include "idf.h"
#include "type.h" #include "type.h"
@ -31,6 +32,7 @@
#include "chk_expr.h" #include "chk_expr.h"
#include "misc.h" #include "misc.h"
#include "warning.h" #include "warning.h"
#include "main.h"
extern char *symbol2str(); extern char *symbol2str();
extern char *sprint(); extern char *sprint();
@ -125,14 +127,14 @@ MkCoercion(pnd, tp)
} }
int int
ChkVariable(expp) ChkVariable(expp, flags)
register t_node *expp; register t_node *expp;
{ {
/* Check that "expp" indicates an item that can be /* Check that "expp" indicates an item that can be
assigned to. assigned to.
*/ */
return ChkDesignator(expp) && return ChkDesig(expp, flags) &&
( expp->nd_class != Def || ( expp->nd_class != Def ||
( expp->nd_def->df_kind & (D_FIELD|D_VARIABLE)) || ( expp->nd_def->df_kind & (D_FIELD|D_VARIABLE)) ||
df_error(expp, "variable expected", expp->nd_def)); df_error(expp, "variable expected", expp->nd_def));
@ -152,7 +154,7 @@ ChkArrow(expp)
expp->nd_type = error_type; expp->nd_type = error_type;
if (! ChkVariable(expp->nd_right)) return 0; if (! ChkVariable(expp->nd_right, D_USED)) return 0;
tp = expp->nd_right->nd_type; tp = expp->nd_right->nd_type;
@ -166,7 +168,7 @@ ChkArrow(expp)
} }
STATIC int STATIC int
ChkArr(expp) ChkArr(expp, flags)
register t_node *expp; register t_node *expp;
{ {
/* Check an array selection. /* Check an array selection.
@ -182,7 +184,7 @@ ChkArr(expp)
expp->nd_type = error_type; expp->nd_type = error_type;
if (! (ChkVariable(expp->nd_left) & ChkExpression(expp->nd_right))) { if (! (ChkVariable(expp->nd_left, flags) & ChkExpression(expp->nd_right))) {
/* Bitwise and, because we want them both evaluated. /* Bitwise and, because we want them both evaluated.
*/ */
return 0; return 0;
@ -225,7 +227,7 @@ ChkValue(expp)
#endif #endif
STATIC int STATIC int
ChkLinkOrName(expp) ChkLinkOrName(expp, flags)
register t_node *expp; register t_node *expp;
{ {
/* Check either an ID or a construction of the form /* Check either an ID or a construction of the form
@ -236,9 +238,10 @@ ChkLinkOrName(expp)
expp->nd_type = error_type; expp->nd_type = error_type;
if (expp->nd_class == Name) { if (expp->nd_class == Name) {
expp->nd_def = lookfor(expp, CurrVis, 1); expp->nd_def = df = lookfor(expp, CurrVis, 1);
expp->nd_class = Def; expp->nd_class = Def;
expp->nd_type = RemoveEqual(expp->nd_def->df_type); expp->nd_type = RemoveEqual(df->df_type);
df->df_flags |= flags;
} }
else if (expp->nd_class == Link) { else if (expp->nd_class == Link) {
/* A selection from a record or a module. /* A selection from a record or a module.
@ -248,7 +251,7 @@ ChkLinkOrName(expp)
assert(expp->nd_symb == '.'); assert(expp->nd_symb == '.');
if (! ChkDesignator(left)) return 0; if (! ChkDesig(left, flags)) return 0;
if (left->nd_class==Def && if (left->nd_class==Def &&
(left->nd_type->tp_fund != T_RECORD || (left->nd_type->tp_fund != T_RECORD ||
@ -266,6 +269,7 @@ ChkLinkOrName(expp)
id_not_declared(expp); id_not_declared(expp);
return 0; return 0;
} }
df->df_flags |= flags;
expp->nd_def = df; expp->nd_def = df;
expp->nd_type = RemoveEqual(df->df_type); expp->nd_type = RemoveEqual(df->df_type);
expp->nd_class = Def; expp->nd_class = Def;
@ -300,7 +304,7 @@ ChkExLinkOrName(expp)
*/ */
register t_def *df; register t_def *df;
if (! ChkLinkOrName(expp)) return 0; if (! ChkLinkOrName(expp, D_USED)) return 0;
df = expp->nd_def; df = expp->nd_def;
@ -537,7 +541,7 @@ getarg(argp, bases, designator, edf)
register t_node *left = nextarg(argp, edf); register t_node *left = nextarg(argp, edf);
if (! left || if (! left ||
! (designator ? ChkVariable(left) : ChkExpression(left))) { ! (designator ? ChkVariable(left, D_USED|D_DEFINED) : ChkExpression(left))) {
return 0; return 0;
} }
@ -616,7 +620,9 @@ ChkProcCall(expp)
*/ */
for (param = ParamList(left->nd_type); param; param = param->par_next) { for (param = ParamList(left->nd_type); param; param = param->par_next) {
if (!(left = getarg(&expp, 0, IsVarParam(param), edf))) { if (!(left = getarg(&expp, 0, IsVarParam(param), edf))) {
return 0; retval = 0;
cnt++;
continue;
} }
cnt++; cnt++;
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
@ -673,7 +679,7 @@ ChkCall(expp)
/* First, get the name of the function or procedure /* First, get the name of the function or procedure
*/ */
if (ChkDesignator(left)) { if (ChkDesig(left, D_USED)) {
if (IsCast(left)) { if (IsCast(left)) {
/* It was a type cast. /* It was a type cast.
*/ */
@ -920,8 +926,8 @@ ChkUnOper(expp)
return 1; return 1;
case '-': case '-':
if (tpr->tp_fund & T_INTORCARD) { if (tpr->tp_fund == T_INTORCARD || tpr->tp_fund == T_INTEGER) {
if (tpr == intorcard_type || tpr == card_type) { if (tpr == intorcard_type) {
expp->nd_type = int_type; expp->nd_type = int_type;
} }
if (right->nd_class == Value) { if (right->nd_class == Value) {
@ -957,7 +963,7 @@ ChkUnOper(expp)
} }
STATIC t_node * STATIC t_node *
getvariable(argp, edf) getvariable(argp, edf, flags)
t_node **argp; t_node **argp;
t_def *edf; t_def *edf;
{ {
@ -966,7 +972,7 @@ getvariable(argp, edf)
*/ */
register t_node *left = nextarg(argp, edf); register t_node *left = nextarg(argp, edf);
if (!left || !ChkVariable(left)) return 0; if (!left || !ChkVariable(left, flags)) return 0;
return left; return left;
} }
@ -1072,6 +1078,7 @@ ChkStandard(expp)
if (left->nd_type->tp_fund == T_ARRAY) { if (left->nd_type->tp_fund == T_ARRAY) {
expp->nd_type = IndexType(left->nd_type); expp->nd_type = IndexType(left->nd_type);
if (! IsConformantArray(left->nd_type)) { if (! IsConformantArray(left->nd_type)) {
left->nd_type = expp->nd_type;
cstcall(expp, S_MAX); cstcall(expp, S_MAX);
} }
break; break;
@ -1120,11 +1127,19 @@ ChkStandard(expp)
if (!warning_given) { if (!warning_given) {
warning_given = 1; warning_given = 1;
#ifndef STRICT_3RD_ED
if (! options['3'])
node_warning(expp, W_OLDFASHIONED, "NEW and DISPOSE are obsolete"); 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
expp->nd_type = 0; expp->nd_type = 0;
if (! (left = getvariable(&arg, edf))) return 0; if (! (left = getvariable(&arg, edf,D_DEFINED))) return 0;
if (! (left->nd_type->tp_fund == T_POINTER)) { if (! (left->nd_type->tp_fund == T_POINTER)) {
return df_error(left, "pointer variable expected", edf); return df_error(left, "pointer variable expected", edf);
} }
@ -1150,6 +1165,7 @@ ChkStandard(expp)
expp->nd_left = MkLeaf(Name, &dt); expp->nd_left = MkLeaf(Name, &dt);
} }
return ChkCall(expp); return ChkCall(expp);
#endif
case S_TSIZE: /* ??? */ case S_TSIZE: /* ??? */
case S_SIZE: case S_SIZE:
@ -1197,7 +1213,7 @@ ChkStandard(expp)
case S_DEC: case S_DEC:
case S_INC: case S_INC:
expp->nd_type = 0; expp->nd_type = 0;
if (! (left = getvariable(&arg, edf))) return 0; if (! (left = getvariable(&arg, edf, D_USED|D_DEFINED))) return 0;
if (! (left->nd_type->tp_fund & T_DISCRETE)) { if (! (left->nd_type->tp_fund & T_DISCRETE)) {
return df_error(left,"illegal parameter type", edf); return df_error(left,"illegal parameter type", edf);
} }
@ -1217,7 +1233,7 @@ ChkStandard(expp)
t_node *dummy; t_node *dummy;
expp->nd_type = 0; expp->nd_type = 0;
if (!(left = getvariable(&arg, edf))) return 0; if (!(left = getvariable(&arg, edf, D_USED|D_DEFINED))) return 0;
tp = left->nd_type; tp = left->nd_type;
if (tp->tp_fund != T_SET) { if (tp->tp_fund != T_SET) {
return df_error(arg, "SET parameter expected", edf); return df_error(arg, "SET parameter expected", edf);

View file

@ -16,8 +16,9 @@ extern int (*DesigChkTable[])(); /* table of designator checking
functions, indexed by node class functions, indexed by node class
*/ */
#define ChkExpression(expp) ((*ExprChkTable[(expp)->nd_class])(expp)) #define ChkExpression(expp) ((*ExprChkTable[(expp)->nd_class])(expp,D_USED))
#define ChkDesignator(expp) ((*DesigChkTable[(expp)->nd_class])(expp)) #define ChkDesignator(expp) ((*DesigChkTable[(expp)->nd_class])(expp,0))
#define ChkDesig(expp, flags) ((*DesigChkTable[(expp)->nd_class])(expp,flags))
#define inc_refcount(s) (*((s) - 1) += 1) #define inc_refcount(s) (*((s) - 1) += 1)
#define dec_refcount(s) (*((s) - 1) -= 1) #define dec_refcount(s) (*((s) - 1) -= 1)

View file

@ -14,8 +14,6 @@ extern long
extern int extern int
mach_long_size; /* size of long on this machine == sizeof(long) */ mach_long_size; /* size of long on this machine == sizeof(long) */
extern arith extern arith
max_int, /* maximum integer on target machine */ max_int; /* maximum integer on target machine */
max_unsigned, /* maximum unsigned on target machine */
max_longint; /* maximum longint on target machine */
extern unsigned int extern unsigned int
wrd_bits; /* Number of bits in a word */ wrd_bits; /* Number of bits in a word */

View file

@ -29,8 +29,6 @@ int mach_long_size; /* size of long on this machine == sizeof(long) */
long full_mask[MAXSIZE];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */ long full_mask[MAXSIZE];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */
long int_mask[MAXSIZE]; /* int_mask[1] == 0x7F, int_mask[2] == 0x7FFF, .. */ long int_mask[MAXSIZE]; /* int_mask[1] == 0x7F, int_mask[2] == 0x7FFF, .. */
arith max_int; /* maximum integer on target machine */ arith max_int; /* maximum integer on target machine */
arith max_unsigned; /* maximum unsigned on target machine */
arith max_longint; /* maximum longint on target machine */
unsigned int wrd_bits; /* number of bits in a word */ unsigned int wrd_bits; /* number of bits in a word */
extern char options[]; extern char options[];
@ -52,10 +50,10 @@ cstunary(expp)
*/ */
case '-': case '-':
if (right->nd_INT < -int_mask[(int)(right->nd_type->tp_size)])
node_warning(expp, W_ORDINARY, ovflow);
expp->nd_INT = -right->nd_INT; expp->nd_INT = -right->nd_INT;
if (expp->nd_type->tp_fund == T_INTORCARD) {
expp->nd_type = int_type;
}
break; break;
case NOT: case NOT:
@ -74,6 +72,62 @@ cstunary(expp)
expp->nd_right = 0; expp->nd_right = 0;
} }
STATIC
divide(pdiv, prem, uns)
arith *pdiv, *prem;
{
/* Divide *pdiv by *prem, and store result in *pdiv,
remainder in *prem
*/
register arith o1 = *pdiv;
register arith o2 = *prem;
if (uns) {
/* this is more of a problem than you might
think on C compilers which do not have
unsigned long.
*/
if (o2 & mach_long_sign) {/* o2 > max_long */
if (! (o1 >= 0 || o1 < o2)) {
/* this is the unsigned test
o1 < o2 for o2 > max_long
*/
*prem = o2 - o1;
*pdiv = 1;
}
else {
*pdiv = 0;
}
}
else { /* o2 <= max_long */
long half, bit, hdiv, hrem, rem;
half = (o1 >> 1) & ~mach_long_sign;
bit = o1 & 01;
/* now o1 == 2 * half + bit
and half <= max_long
and bit <= max_long
*/
hdiv = half / o2;
hrem = half % o2;
rem = 2 * hrem + bit;
*pdiv = 2*hdiv;
*prem = rem;
if (rem < 0 || rem >= o2) {
/* that is the unsigned compare
rem >= o2 for o2 <= max_long
*/
*pdiv += 1;
*prem -= o2;
}
}
}
else {
*pdiv = o1 / o2; /* ??? */
*prem = o1 - *pdiv * o2;
}
}
cstbin(expp) cstbin(expp)
register t_node *expp; register t_node *expp;
{ {
@ -81,8 +135,8 @@ cstbin(expp)
expressions below it, and the result restored in expressions below it, and the result restored in
expp. expp.
*/ */
register arith o1 = expp->nd_left->nd_INT; arith o1 = expp->nd_left->nd_INT;
register arith o2 = expp->nd_right->nd_INT; arith o2 = expp->nd_right->nd_INT;
register int uns = expp->nd_left->nd_type != int_type; register int uns = expp->nd_left->nd_type != int_type;
assert(expp->nd_class == Oper); assert(expp->nd_class == Oper);
@ -99,37 +153,7 @@ cstbin(expp)
node_error(expp, "division by 0"); node_error(expp, "division by 0");
return; return;
} }
if (uns) { divide(&o1, &o2, uns);
/* this is more of a problem than you might
think on C compilers which do not have
unsigned long.
*/
if (o2 & mach_long_sign) {/* o2 > max_long */
o1 = ! (o1 >= 0 || o1 < o2);
/* this is the unsigned test
o1 < o2 for o2 > max_long
*/
}
else { /* o2 <= max_long */
long half, bit, hdiv, hrem, rem;
half = (o1 >> 1) & ~mach_long_sign;
bit = o1 & 01;
/* now o1 == 2 * half + bit
and half <= max_long
and bit <= max_long
*/
hdiv = half / o2;
hrem = half % o2;
rem = 2 * hrem + bit;
o1 = 2 * hdiv + (rem < 0 || rem >= o2);
/* that is the unsigned compare
rem >= o2 for o2 <= max_long
*/
}
}
else
o1 /= o2;
break; break;
case MOD: case MOD:
@ -137,29 +161,8 @@ cstbin(expp)
node_error(expp, "modulo by 0"); node_error(expp, "modulo by 0");
return; return;
} }
if (uns) { divide(&o1, &o2, uns);
if (o2 & mach_long_sign) {/* o2 > max_long */ o1 = o2;
o1 = (o1 >= 0 || o1 < o2) ? o1 : o1 - o2;
/* this is the unsigned test
o1 < o2 for o2 > max_long
*/
}
else { /* o2 <= max_long */
long half, bit, hrem, rem;
half = (o1 >> 1) & ~mach_long_sign;
bit = o1 & 01;
/* now o1 == 2 * half + bit
and half <= max_long
and bit <= max_long
*/
hrem = half % o2;
rem = 2 * hrem + bit;
o1 = (rem < 0 || rem >= o2) ? rem - o2 : rem;
}
}
else
o1 %= o2;
break; break;
case '+': case '+':
@ -343,15 +346,15 @@ cstcall(expp, call)
/* a standard procedure call is found that can be evaluated /* a standard procedure call is found that can be evaluated
compile time, so do so. compile time, so do so.
*/ */
register t_node *expr = 0; register t_node *expr;
register t_type *tp;
assert(expp->nd_class == Call); assert(expp->nd_class == Call);
if (expp->nd_right) { expr = expp->nd_right->nd_left;
expr = expp->nd_right->nd_left; expp->nd_right->nd_left = 0;
expp->nd_right->nd_left = 0; FreeNode(expp->nd_right);
FreeNode(expp->nd_right); tp = expr->nd_type;
}
expp->nd_class = Value; expp->nd_class = Value;
expp->nd_symb = INTEGER; expp->nd_symb = INTEGER;
@ -370,32 +373,25 @@ cstcall(expp, call)
break; break;
case S_MAX: case S_MAX:
if (expp->nd_type == int_type) { if (tp->tp_fund == T_INTEGER) {
expp->nd_INT = max_int; expp->nd_INT = int_mask[(int)(tp->tp_size)];
} }
else if (expp->nd_type == longint_type) { else if (tp == card_type) {
expp->nd_INT = max_longint; expp->nd_INT = full_mask[(int)(int_size)];
} }
else if (expp->nd_type == card_type) { else if (tp->tp_fund == T_SUBRANGE) {
expp->nd_INT = max_unsigned; expp->nd_INT = tp->sub_ub;
} }
else if (expp->nd_type->tp_fund == T_SUBRANGE) { else expp->nd_INT = tp->enm_ncst - 1;
expp->nd_INT = expp->nd_type->sub_ub;
}
else expp->nd_INT = expp->nd_type->enm_ncst - 1;
break; break;
case S_MIN: case S_MIN:
if (expp->nd_type == int_type) { if (tp->tp_fund == T_INTEGER) {
expp->nd_INT = -max_int; expp->nd_INT = -int_mask[(int)(tp->tp_size)];
if (! options['s']) expp->nd_INT--; if (! options['s']) expp->nd_INT--;
} }
else if (expp->nd_type == longint_type) { else if (tp->tp_fund == T_SUBRANGE) {
expp->nd_INT = - max_longint; expp->nd_INT = tp->sub_lb;
if (! options['s']) expp->nd_INT--;
}
else if (expp->nd_type->tp_fund == T_SUBRANGE) {
expp->nd_INT = expp->nd_type->sub_lb;
} }
else expp->nd_INT = 0; else expp->nd_INT = 0;
break; break;
@ -405,7 +401,7 @@ cstcall(expp, call)
break; break;
case S_SIZE: case S_SIZE:
expp->nd_INT = expr->nd_type->tp_size; expp->nd_INT = tp->tp_size;
break; break;
default: default:
@ -466,8 +462,6 @@ InitCst()
fatal("sizeof (long) insufficient on this machine"); fatal("sizeof (long) insufficient on this machine");
} }
max_int = int_mask[int_size]; max_int = int_mask[(int)int_size];
max_unsigned = full_mask[int_size];
max_longint = int_mask[long_size];
wrd_bits = 8 * (unsigned) word_size; wrd_bits = 8 * (unsigned) word_size;
} }

View file

@ -17,6 +17,7 @@
#include <alloc.h> #include <alloc.h>
#include <assert.h> #include <assert.h>
#include "strict3rd.h"
#include "idf.h" #include "idf.h"
#include "LLlex.h" #include "LLlex.h"
#include "def.h" #include "def.h"
@ -336,8 +337,13 @@ FieldList(t_scope *scope; arith *cnt; int *palign;)
| /* Old fashioned! the first qualident now represents | /* Old fashioned! the first qualident now represents
the type the type
*/ */
{ warning(W_OLDFASHIONED, {
#ifndef STRICT_3RD_ED
if (! options['3']) warning(W_OLDFASHIONED,
"old fashioned Modula-2 syntax; ':' missing"); "old fashioned Modula-2 syntax; ':' missing");
else
#endif
error("':' missing");
tp = qualified_type(nd); tp = qualified_type(nd);
} }
] ]

View file

@ -73,6 +73,7 @@ MkDef(id, scope, kind)
df->df_scope = scope; df->df_scope = scope;
df->df_kind = kind; df->df_kind = kind;
df->df_next = id->id_def; df->df_next = id->id_def;
df->df_flags = D_USED | D_DEFINED;
id->id_def = df; id->id_def = df;
if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type; if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type;
@ -241,6 +242,7 @@ DeclProc(type, id)
*/ */
df = define(id, CurrentScope, type); df = define(id, CurrentScope, type);
df->for_node = dot2leaf(Name); df->for_node = dot2leaf(Name);
df->df_flags |= D_USED | D_DEFINED;
if (CurrentScope->sc_definedby->df_flags & D_FOREIGN) { if (CurrentScope->sc_definedby->df_flags & D_FOREIGN) {
df->for_name = id->id_text; df->for_name = id->id_text;
} }
@ -275,6 +277,7 @@ DeclProc(type, id)
C_exp(buf); C_exp(buf);
} }
else C_inp(buf); else C_inp(buf);
df->df_flags |= D_DEFINED;
} }
open_scope(OPENSCOPE); open_scope(OPENSCOPE);
scope = CurrentScope; scope = CurrentScope;
@ -360,11 +363,12 @@ CheckWithDef(df, tp)
possible earlier definition in the definition module. possible earlier definition in the definition module.
*/ */
if (df->df_kind == D_PROCHEAD && df->df_type != error_type) { if (df->df_kind == D_PROCHEAD &&
df->df_type &&
df->df_type != error_type) {
/* We already saw a definition of this type /* We already saw a definition of this type
in the definition module. in the definition module.
*/ */
assert(df->df_type != 0);
if (!TstProcEquiv(tp, df->df_type)) { if (!TstProcEquiv(tp, df->df_type)) {
error("inconsistent procedure declaration for \"%s\"", error("inconsistent procedure declaration for \"%s\"",

View file

@ -129,6 +129,7 @@ EnterVarList(Idlist, type, local)
for (; idlist; idlist = idlist->nd_right) { for (; idlist; idlist = idlist->nd_right) {
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE); df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
df->df_type = type; df->df_type = type;
df->df_flags &= ~(D_USED | D_DEFINED);
if (idlist->nd_left) { if (idlist->nd_left) {
/* An address was supplied /* An address was supplied
*/ */
@ -166,6 +167,7 @@ EnterVarList(Idlist, type, local)
df->df_flags |= D_NOREG; df->df_flags |= D_NOREG;
if (DefinitionModule) { if (DefinitionModule) {
df->df_flags |= D_USED | D_DEFINED;
if (sc == Defined->mod_vis) { if (sc == Defined->mod_vis) {
C_exa_dnam(df->var_name); C_exa_dnam(df->var_name);
} }
@ -212,7 +214,8 @@ EnterParamList(ppr, Idlist, type, VARp, off)
else df = new_def(); else df = new_def();
pr->par_def = df; pr->par_def = df;
df->df_type = type; df->df_type = type;
df->df_flags = VARp; df->df_flags |= (VARp | D_DEFINED);
if (df->df_flags & D_VARPAR) df->df_flags |= D_USED;
if (IsConformantArray(type)) { if (IsConformantArray(type)) {
/* we need room for the base address and a descriptor /* we need room for the base address and a descriptor
@ -240,6 +243,10 @@ DoImport(df, scope)
define(df->df_idf, scope, D_IMPORT)->imp_def = df; define(df->df_idf, scope, D_IMPORT)->imp_def = df;
while (df->df_kind == D_IMPORT) {
df = df->imp_def;
}
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) { if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
/* Also import all enumeration literals /* Also import all enumeration literals
*/ */
@ -305,7 +312,7 @@ ForwDef(ids, scope)
*/ */
register t_def *df; register t_def *df;
if (!(df = lookup(ids->nd_IDF, scope, 1))) { if (!(df = lookup(ids->nd_IDF, scope, 0))) {
df = define(ids->nd_IDF, scope, D_FORWARD); df = define(ids->nd_IDF, scope, D_FORWARD);
df->for_node = MkLeaf(Name, &(ids->nd_token)); df->for_node = MkLeaf(Name, &(ids->nd_token));
} }
@ -341,8 +348,6 @@ EnterExportList(Idlist, qualified)
idlist->nd_IDF->id_text); idlist->nd_IDF->id_text);
} }
if (df->df_kind == D_IMPORT) df = df->imp_def;
df->df_flags |= qualified; df->df_flags |= qualified;
if (qualified == D_EXPORTED) { if (qualified == D_EXPORTED) {
/* Export, but not qualified. /* Export, but not qualified.
@ -368,15 +373,20 @@ EnterExportList(Idlist, qualified)
scope. There are two legal possibilities, scope. There are two legal possibilities,
which are examined below. which are examined below.
*/ */
t_def *df2 = df;
while (df2->df_kind == D_IMPORT) {
df2 = df2->imp_def;
}
if (df1->df_kind == D_PROCHEAD && if (df1->df_kind == D_PROCHEAD &&
df->df_kind == D_PROCEDURE) { df2->df_kind == D_PROCEDURE) {
df1->df_kind = D_IMPORT; df1->df_kind = D_IMPORT;
df1->imp_def = df; df1->imp_def = df;
continue; continue;
} }
if (df1->df_kind == D_HIDDEN && if (df1->df_kind == D_HIDDEN &&
df->df_kind == D_TYPE) { df2->df_kind == D_TYPE) {
DeclareType(idlist, df1, df->df_type); DeclareType(idlist, df1, df2->df_type);
df1->df_kind = D_TYPE; df1->df_kind = D_TYPE;
continue; continue;
} }
@ -388,14 +398,13 @@ EnterExportList(Idlist, qualified)
FreeNode(Idlist); FreeNode(Idlist);
} }
EnterFromImportList(Idlist, FromDef, FromId) EnterFromImportList(idlist, FromDef, FromId)
t_node *Idlist; register t_node *idlist;
register t_def *FromDef; register t_def *FromDef;
t_node *FromId; t_node *FromId;
{ {
/* Import the list Idlist from the module indicated by Fromdef. /* Import the list Idlist from the module indicated by Fromdef.
*/ */
register t_node *idlist = Idlist;
register t_scopelist *vis; register t_scopelist *vis;
register t_def *df; register t_def *df;
char *module_name = FromDef->df_idf->id_text; char *module_name = FromDef->df_idf->id_text;
@ -430,7 +439,7 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
for (; idlist; idlist = idlist->nd_left) { for (; idlist; idlist = idlist->nd_left) {
if (forwflag) df = ForwDef(idlist, vis->sc_scope); if (forwflag) df = ForwDef(idlist, vis->sc_scope);
else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 1))) { else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0))) {
if (! is_anon_idf(idlist->nd_IDF)) { if (! is_anon_idf(idlist->nd_IDF)) {
node_error(idlist, node_error(idlist,
"identifier \"%s\" not declared in module \"%s\"", "identifier \"%s\" not declared in module \"%s\"",
@ -450,30 +459,38 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
} }
if (!forwflag) FreeNode(FromId); if (!forwflag) FreeNode(FromId);
FreeNode(Idlist);
} }
EnterImportList(Idlist, local) EnterGlobalImportList(idlist)
t_node *Idlist; register t_node *idlist;
{ {
/* Import "Idlist" from the enclosing scope. /* Import "idlist" from the enclosing scope.
An exception must be made for imports of the compilation unit. Definition modules must be read for "idlist".
In this case, definition modules must be read for "Idlist".
This case is indicated by the value 0 of the "local" flag.
*/ */
register t_node *idlist = Idlist;
t_scope *sc = enclosing(CurrVis)->sc_scope;
extern t_def *GetDefinitionModule(); extern t_def *GetDefinitionModule();
struct f_info f; struct f_info f;
f = file_info; f = file_info;
for (; idlist; idlist = idlist->nd_left) { for (; idlist; idlist = idlist->nd_left) {
DoImport(local ? DoImport(GetDefinitionModule(idlist->nd_IDF, 1), CurrentScope);
ForwDef(idlist, sc) :
GetDefinitionModule(idlist->nd_IDF, 1) ,
CurrentScope);
file_info = f; file_info = f;
} }
FreeNode(Idlist); }
EnterImportList(idlist)
register t_node *idlist;
{
/* 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;
}
} }

View file

@ -21,6 +21,7 @@
#include <em_arith.h> #include <em_arith.h>
#include <em_label.h> #include <em_label.h>
#include "strict3rd.h"
#include "input.h" #include "input.h"
#include "f_info.h" #include "f_info.h"
#include "LLlex.h" #include "LLlex.h"
@ -170,9 +171,11 @@ _error(class, node, fmt, argv)
case WARNING: case WARNING:
case LEXWARNING: case LEXWARNING:
switch(warn_class) { switch(warn_class) {
#ifndef STRICT_3RD_ED
case W_OLDFASHIONED: case W_OLDFASHIONED:
remark = "(old-fashioned use)"; remark = "(old-fashioned use)";
break; break;
#endif
case W_STRICT: case W_STRICT:
remark = "(strict)"; remark = "(strict)";
break; break;

View file

@ -16,6 +16,7 @@
#include <em_label.h> #include <em_label.h>
#include <alloc.h> #include <alloc.h>
#include "strict3rd.h"
#include "input.h" #include "input.h"
#include "f_info.h" #include "f_info.h"
#include "idf.h" #include "idf.h"

View file

@ -15,6 +15,7 @@
#include <em_label.h> #include <em_label.h>
#include <alloc.h> #include <alloc.h>
#include "strict3rd.h"
#include "type.h" #include "type.h"
#include "main.h" #include "main.h"
#include "warning.h" #include "warning.h"
@ -44,6 +45,9 @@ DoOption(text)
case 'n': /* no register messages */ case 'n': /* no register messages */
case 'x': /* every name global */ case 'x': /* every name global */
case 's': /* symmetric: MIN(INTEGER) = -MAX(INTEGER) */ case 's': /* symmetric: MIN(INTEGER) = -MAX(INTEGER) */
#ifndef STRICT_3RD_ED
case '3': /* strict 3rd edition Modula-2 */
#endif
options[text[-1]]++; options[text[-1]]++;
break; break;
@ -64,9 +68,11 @@ DoOption(text)
if (*text) { if (*text) {
while (*text) { while (*text) {
switch(*text++) { switch(*text++) {
#ifndef STRICT_3RD_ED
case 'O': case 'O':
warning_classes &= ~W_OLDFASHIONED; warning_classes &= ~W_OLDFASHIONED;
break; break;
#endif
case 'R': case 'R':
warning_classes &= ~W_STRICT; warning_classes &= ~W_STRICT;
break; break;
@ -83,9 +89,11 @@ DoOption(text)
if (*text) { if (*text) {
while (*text) { while (*text) {
switch(*text++) { switch(*text++) {
#ifndef STRICT_3RD_ED
case 'O': case 'O':
warning_classes |= W_OLDFASHIONED; warning_classes |= W_OLDFASHIONED;
break; break;
#endif
case 'R': case 'R':
warning_classes |= W_STRICT; warning_classes |= W_STRICT;
break; break;

View file

@ -16,6 +16,7 @@
#include <em_arith.h> #include <em_arith.h>
#include <em_label.h> #include <em_label.h>
#include "strict3rd.h"
#include "main.h" #include "main.h"
#include "idf.h" #include "idf.h"
#include "LLlex.h" #include "LLlex.h"
@ -114,7 +115,9 @@ import(int local;)
{ if (FromId) { { if (FromId) {
EnterFromImportList(ImportList, df, FromId); EnterFromImportList(ImportList, df, FromId);
} }
else EnterImportList(ImportList, local); else if (local) EnterImportList(ImportList);
else EnterGlobalImportList(ImportList);
FreeNode(ImportList);
} }
; ;
@ -150,8 +153,13 @@ DefinitionModule
modules. Issue a warning. modules. Issue a warning.
*/ */
{ {
#ifndef STRICT_3RD_ED
if (! options['3'])
node_warning(exportlist, W_OLDFASHIONED, "export list in definition module ignored"); node_warning(exportlist, W_OLDFASHIONED, "export list in definition module ignored");
FreeNode(exportlist); else
#endif
error("export list not allowed in definition module");
FreeNode(exportlist);
} }
| |
/* empty */ /* empty */

View file

@ -217,6 +217,10 @@ close_scope(flag)
assert(sc != 0); assert(sc != 0);
if (! sc->sc_end) {
sc->sc_end = dot2leaf(Link);
}
if (flag) { if (flag) {
DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def))); DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def)));
if (flag & SC_CHKPROC) chk_proc(sc->sc_def); if (flag & SC_CHKPROC) chk_proc(sc->sc_def);

View file

@ -30,6 +30,7 @@ struct scope {
char sc_scopeclosed; /* flag indicating closed or open scope */ char sc_scopeclosed; /* flag indicating closed or open scope */
int sc_level; /* level of this scope */ int sc_level; /* level of this scope */
struct def *sc_definedby; /* The def structure defining this scope */ struct def *sc_definedby; /* The def structure defining this scope */
struct node *sc_end; /* node to remember line number of end of scope */
}; };
struct scopelist { struct scopelist {

View file

@ -611,7 +611,7 @@ type_or_forward(ptp)
in this scope, so this is the correct identification in this scope, so this is the correct identification
*/ */
if (df1->df_kind == D_FORWTYPE) { if (df1->df_kind == D_FORWTYPE) {
nd = dot2node(NULLNODE, df1->df_forw_node, 0); nd = dot2node(0, NULLNODE, df1->df_forw_node);
df1->df_forw_node = nd; df1->df_forw_node = nd;
nd->nd_type = *ptp; nd->nd_type = *ptp;
} }

View file

@ -18,12 +18,14 @@
#include <em_label.h> #include <em_label.h>
#include <assert.h> #include <assert.h>
#include "strict3rd.h"
#include "type.h" #include "type.h"
#include "LLlex.h" #include "LLlex.h"
#include "idf.h" #include "idf.h"
#include "def.h" #include "def.h"
#include "node.h" #include "node.h"
#include "warning.h" #include "warning.h"
#include "main.h"
extern char *sprint(); extern char *sprint();
@ -239,7 +241,8 @@ TstParCompat(parno, formaltype, VARflag, nd, edf)
) )
) )
return 1; return 1;
if (VARflag && TstCompat(formaltype, actualtype)) { #ifndef STRICT_3RD_ED
if (! options['3'] && VARflag && TstCompat(formaltype, actualtype)) {
if (formaltype->tp_size == actualtype->tp_size) { if (formaltype->tp_size == actualtype->tp_size) {
sprint(ebuf1, ebuf, "identical types required"); sprint(ebuf1, ebuf, "identical types required");
node_warning(*nd, node_warning(*nd,
@ -251,7 +254,7 @@ TstParCompat(parno, formaltype, VARflag, nd, edf)
node_error(*nd, ebuf1); node_error(*nd, ebuf1);
return 0; return 0;
} }
#endif
sprint(ebuf1, ebuf, "type incompatibility"); sprint(ebuf1, ebuf, "type incompatibility");
node_error(*nd, ebuf1); node_error(*nd, ebuf1);
return 0; return 0;

View file

@ -23,6 +23,7 @@
#include <assert.h> #include <assert.h>
#include <alloc.h> #include <alloc.h>
#include "strict3rd.h"
#include "squeeze.h" #include "squeeze.h"
#include "LLlex.h" #include "LLlex.h"
#include "def.h" #include "def.h"
@ -40,14 +41,22 @@
extern arith NewPtr(); extern arith NewPtr();
extern arith NewInt(); extern arith NewInt();
extern int proclevel; extern int proclevel;
label text_label; label text_label;
label data_label = 1; label data_label = 1;
static t_type *func_type;
struct withdesig *WithDesigs; struct withdesig *WithDesigs;
t_node *Modules; t_node *Modules;
static t_type *func_type;
static arith priority; static arith priority;
static int RegisterMessage();
static int WalkDef();
static int MkCalls();
static int UseWarnings();
#define NO_EXIT_LABEL ((label) 0) #define NO_EXIT_LABEL ((label) 0)
#define RETURN_LABEL ((label) 1) #define RETURN_LABEL ((label) 1)
@ -119,7 +128,7 @@ WalkModule(module)
/* Walk through it's local definitions /* Walk through it's local definitions
*/ */
WalkDef(sc->sc_def); WalkDefList(sc->sc_def, WalkDef);
/* Now, generate initialization code for this module. /* Now, generate initialization code for this module.
First call initialization routines for modules defined within First call initialization routines for modules defined within
@ -156,7 +165,7 @@ WalkModule(module)
C_cal(nd->nd_IDF->id_text); C_cal(nd->nd_IDF->id_text);
} }
} }
MkCalls(sc->sc_def); WalkDefList(sc->sc_def, MkCalls);
proclevel++; proclevel++;
WalkNode(module->mod_body, NO_EXIT_LABEL); WalkNode(module->mod_body, NO_EXIT_LABEL);
DO_DEBUG(options['X'], PrNode(module->mod_body, 0)); DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
@ -168,6 +177,7 @@ WalkModule(module)
TmpClose(); TmpClose();
CurrVis = savevis; CurrVis = savevis;
WalkDefList(sc->sc_def, UseWarnings);
} }
WalkProcedure(procedure) WalkProcedure(procedure)
@ -190,7 +200,7 @@ WalkProcedure(procedure)
/* Generate code for all local modules and procedures /* Generate code for all local modules and procedures
*/ */
WalkDef(sc->sc_def); WalkDefList(sc->sc_def, WalkDef);
/* Generate code for this procedure /* Generate code for this procedure
*/ */
@ -221,7 +231,7 @@ WalkProcedure(procedure)
/* Generate calls to initialization routines of modules defined within /* Generate calls to initialization routines of modules defined within
this procedure this procedure
*/ */
MkCalls(sc->sc_def); WalkDefList(sc->sc_def, MkCalls);
/* Make sure that arguments of size < word_size are on a /* Make sure that arguments of size < word_size are on a
fixed place. fixed place.
@ -327,54 +337,53 @@ WalkProcedure(procedure)
} }
EndPriority(); EndPriority();
C_ret(func_res_size); C_ret(func_res_size);
if (! options['n']) RegisterMessages(sc->sc_def); if (! options['n']) WalkDefList(sc->sc_def, RegisterMessage);
C_end(-sc->sc_off); C_end(-sc->sc_off);
TmpClose(); TmpClose();
CurrVis = savevis; CurrVis = savevis;
proclevel--; proclevel--;
WalkDefList(sc->sc_def, UseWarnings);
} }
static int
WalkDef(df) WalkDef(df)
register t_def *df; register t_def *df;
{ {
/* Walk through a list of definitions /* Walk through a list of definitions
*/ */
for ( ; df; df = df->df_nextinscope) { switch(df->df_kind) {
switch(df->df_kind) { case D_MODULE:
case D_MODULE: WalkModule(df);
WalkModule(df); break;
break; case D_PROCEDURE:
case D_PROCEDURE: WalkProcedure(df);
WalkProcedure(df); break;
break; case D_VARIABLE:
case D_VARIABLE: if (!proclevel && !(df->df_flags & D_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), (arith) 0, 0);
(arith) 0, 0);
}
break;
default:
/* nothing */
;
} }
break;
default:
/* nothing */
;
} }
} }
static int
MkCalls(df) MkCalls(df)
register t_def *df; register t_def *df;
{ {
/* Generate calls to initialization routines of modules /* Generate calls to initialization routines of modules
*/ */
for ( ; df; df = df->df_nextinscope) { if (df->df_kind == D_MODULE) {
if (df->df_kind == D_MODULE) { C_lxl((arith) 0);
C_lxl((arith) 0); C_cal(df->mod_vis->sc_scope->sc_name);
C_cal(df->mod_vis->sc_scope->sc_name); C_asp(pointer_size);
C_asp(pointer_size);
}
} }
} }
@ -579,7 +588,7 @@ WalkStat(nd, exit_label)
struct withdesig wds; struct withdesig wds;
t_desig ds; t_desig ds;
if (! WalkDesignator(left, &ds)) break; if (! WalkDesignator(left, &ds, D_USED|D_DEFINED)) break;
if (left->nd_type->tp_fund != T_RECORD) { if (left->nd_type->tp_fund != T_RECORD) {
node_error(left, "record variable expected"); node_error(left, "record variable expected");
break; break;
@ -686,14 +695,14 @@ ExpectBool(nd, true_label, false_label)
} }
int int
WalkDesignator(nd, ds) WalkDesignator(nd, ds, flags)
t_node *nd; t_node *nd;
t_desig *ds; t_desig *ds;
{ {
/* Check designator and generate code for it /* Check designator and generate code for it
*/ */
if (! ChkVariable(nd)) return 0; if (! ChkVariable(nd, flags)) return 0;
clear((char *) ds, sizeof(t_desig)); clear((char *) ds, sizeof(t_desig));
CodeDesig(nd, ds); CodeDesig(nd, ds);
@ -711,7 +720,7 @@ DoForInit(nd)
nd->nd_class = Name; nd->nd_class = Name;
nd->nd_symb = IDENT; nd->nd_symb = IDENT;
if (!( ChkVariable(nd) & if (!( ChkVariable(nd, D_USED|D_DEFINED) &
ChkExpression(left->nd_left) & ChkExpression(left->nd_left) &
ChkExpression(left->nd_right))) return 0; ChkExpression(left->nd_right))) return 0;
@ -749,13 +758,22 @@ DoForInit(nd)
tpl = left->nd_left->nd_type; tpl = left->nd_left->nd_type;
tpr = left->nd_right->nd_type; tpr = left->nd_right->nd_type;
if (!ChkAssCompat(&(left->nd_left), df->df_type, "FOR statement") || #ifndef STRICT_3RD_ED
!ChkAssCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) { if (! options['3']) {
if (!ChkAssCompat(&(left->nd_left), df->df_type, "FOR statement") ||
!ChkAssCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
return 1; return 1;
} }
if (!TstCompat(df->df_type, tpl) || if (!TstCompat(df->df_type, tpl) ||
!TstCompat(df->df_type, tpr)) { !TstCompat(df->df_type, tpr)) {
node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement"); node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
node_error(nd, "compatibility required in FOR statement");
}
} else
#endif
if (!ChkCompat(&(left->nd_left), df->df_type, "FOR statement") ||
!ChkCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
return 1;
} }
CodePExpr(left->nd_left); CodePExpr(left->nd_left);
@ -774,7 +792,7 @@ DoAssign(left, right)
register t_desig *dsr; register t_desig *dsr;
register t_type *tp; register t_type *tp;
if (! (ChkExpression(right) & ChkVariable(left))) return; if (! (ChkExpression(right) & ChkVariable(left, D_DEFINED))) return;
tp = left->nd_type; tp = left->nd_type;
if (right->nd_symb == STRING) TryToString(right, tp); if (right->nd_symb == STRING) TryToString(right, tp);
@ -798,20 +816,22 @@ DoAssign(left, right)
free_desig(dsr); free_desig(dsr);
} }
RegisterMessages(df) static int
RegisterMessage(df)
register t_def *df; register t_def *df;
{ {
register t_type *tp; register t_type *tp;
arith sz; arith sz;
int regtype = -1; int regtype;
for (; df; df = df->df_nextinscope) { if (df->df_kind == D_VARIABLE) {
if (df->df_kind == D_VARIABLE && !(df->df_flags & D_NOREG)) { if ( !(df->df_flags & D_NOREG)) {
/* Examine type and size /* Examine type and size
*/ */
regtype = -1;
tp = BaseType(df->df_type); tp = BaseType(df->df_type);
if ((df->df_flags & D_VARPAR) || if ((df->df_flags & D_VARPAR) ||
(tp->tp_fund & (T_POINTER|T_HIDDEN|T_EQUAL))) { (tp->tp_fund&(T_POINTER|T_HIDDEN|T_EQUAL))) {
sz = pointer_size; sz = pointer_size;
regtype = reg_pointer; regtype = reg_pointer;
} }
@ -826,3 +846,38 @@ RegisterMessages(df)
} }
} }
} }
static int
UseWarnings(df)
register t_def *df;
{
if (df->df_kind & (D_IMPORT | 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_VARIABLE|D_PROCEDURE))) return;
nd = df->df_scope->sc_end;
if (! (df->df_flags & D_DEFINED)) {
node_warning(nd,
W_ORDINARY,
"identifier \"%s\" never assigned",
df->df_idf->id_text);
}
if (! (df->df_flags & D_USED)) {
node_warning(nd,
W_ORDINARY,
"identifier \"%s\" never used",
df->df_idf->id_text);
}
}
}
WalkDefList(df, proc)
register t_def *df;
int (*proc)();
{
for (; df; df = df->df_nextinscope) {
(*proc)(df);
}
}