sets now allowed for all subranges

This commit is contained in:
ceriel 1987-10-28 16:03:56 +00:00
parent d80b501829
commit b668810351
10 changed files with 36 additions and 38 deletions

View file

@ -39,7 +39,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 density.h squeeze.h \
def.h debugcst.h type.h Lpars.h node.h desig.h strict3rd.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\
@ -214,13 +214,13 @@ type.o: debug.h
type.o: debugcst.h type.o: debugcst.h
type.o: def.h type.o: def.h
type.o: idf.h type.o: idf.h
type.o: maxset.h
type.o: node.h type.o: node.h
type.o: scope.h type.o: scope.h
type.o: squeeze.h type.o: squeeze.h
type.o: target_sizes.h type.o: target_sizes.h
type.o: type.h type.o: type.h
type.o: walk.h type.o: walk.h
type.o: warning.h
def.o: LLlex.h def.o: LLlex.h
def.o: Lpars.h def.o: Lpars.h
def.o: debug.h def.o: debug.h

View file

@ -52,11 +52,6 @@
#define INP_READ_IN_ONE 1 /* read input file in one */ #define INP_READ_IN_ONE 1 /* read input file in one */
!File: maxset.h
#define MAXSET 1024 /* maximum number of elements in a set,
but what is a reasonable choice ???
*/
!File: density.h !File: density.h
#define DENSITY 3 /* see casestat.C for an explanation */ #define DENSITY 3 /* see casestat.C for an explanation */

View file

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

View file

@ -369,6 +369,7 @@ ChkElement(expp, tp, set)
Also try to compute the set! Also try to compute the set!
*/ */
register t_node *expr = *expp; register t_node *expr = *expp;
t_type *el_type = ElementType(tp);
register unsigned int i; register unsigned int i;
arith lo, hi, low, high; arith lo, hi, low, high;
@ -376,8 +377,8 @@ ChkElement(expp, tp, set)
/* { ... , expr1 .. expr2, ... } /* { ... , expr1 .. expr2, ... }
First check expr1 and expr2, and try to compute them. First check expr1 and expr2, and try to compute them.
*/ */
if (! (ChkEl(&(expr->nd_left), tp) & if (! (ChkEl(&(expr->nd_left), el_type) &
ChkEl(&(expr->nd_right), tp))) { ChkEl(&(expr->nd_right), el_type))) {
return 0; return 0;
} }
@ -393,7 +394,7 @@ ChkElement(expp, tp, set)
high = expr->nd_right->nd_INT; high = expr->nd_right->nd_INT;
} }
else { else {
if (! ChkEl(expp, tp)) return 0; if (! ChkEl(expp, el_type)) return 0;
expr = *expp; expr = *expp;
if (expr->nd_class != Value) { if (expr->nd_class != Value) {
return 1; return 1;
@ -405,12 +406,14 @@ ChkElement(expp, tp, set)
return 0; return 0;
} }
getbounds(tp, &lo, &hi); getbounds(el_type, &lo, &hi);
if (low < lo || high > hi) { if (low < lo || high > hi) {
node_error(expr, "set element out of range"); node_error(expr, "set element out of range");
return 0; return 0;
} }
low -= tp->set_low;
high -= tp->set_low;
for (i=(unsigned)low; i<= (unsigned)high; i++) { for (i=(unsigned)low; i<= (unsigned)high; i++) {
set[i/wrd_bits] |= (1<<(i%wrd_bits)); set[i/wrd_bits] |= (1<<(i%wrd_bits));
} }
@ -494,8 +497,7 @@ ChkSet(expp)
while (nd) { while (nd) {
assert(nd->nd_class == Link && nd->nd_symb == ','); assert(nd->nd_class == Link && nd->nd_symb == ',');
if (!ChkElement(&(nd->nd_left), ElementType(tp), if (!ChkElement(&(nd->nd_left), tp, expp->nd_set)) {
expp->nd_set)) {
retval = 0; retval = 0;
} }
if (nd->nd_left) SetIsConstant = 0; if (nd->nd_left) SetIsConstant = 0;

View file

@ -569,6 +569,8 @@ CodeStd(nd)
case S_EXCL: case S_EXCL:
CodePExpr(left); CodePExpr(left);
CodePExpr(arg->nd_left); CodePExpr(arg->nd_left);
C_loc(tp->set_low);
C_sbi(word_size);
C_set(tp->tp_size); C_set(tp->tp_size);
if (std == S_INCL) { if (std == S_INCL) {
C_ior(tp->tp_size); C_ior(tp->tp_size);
@ -822,6 +824,8 @@ CodeOper(expr, true_label, false_label)
*/ */
CodePExpr(rightop); CodePExpr(rightop);
CodePExpr(leftop); CodePExpr(leftop);
C_loc(rightop->nd_type->set_low);
C_sbi(word_size);
C_inn(rightop->nd_type->tp_size); C_inn(rightop->nd_type->tp_size);
if (true_label != NO_LABEL) { if (true_label != NO_LABEL) {
C_zne(true_label); C_zne(true_label);
@ -975,6 +979,7 @@ CodeEl(nd, tp)
register t_type *eltype = ElementType(tp); register t_type *eltype = ElementType(tp);
if (nd->nd_class == Link && nd->nd_symb == UPTO) { if (nd->nd_class == Link && nd->nd_symb == UPTO) {
C_loc(tp->set_low);
C_loc(tp->tp_size); /* push size */ C_loc(tp->tp_size); /* push size */
if (eltype->tp_fund == T_SUBRANGE) { if (eltype->tp_fund == T_SUBRANGE) {
C_loc(eltype->sub_ub); C_loc(eltype->sub_ub);
@ -982,10 +987,12 @@ CodeEl(nd, tp)
else C_loc((arith) (eltype->enm_ncst - 1)); else C_loc((arith) (eltype->enm_ncst - 1));
Operands(nd->nd_left, nd->nd_right); Operands(nd->nd_left, nd->nd_right);
C_cal("_LtoUset"); /* library routine to fill set */ C_cal("_LtoUset"); /* library routine to fill set */
C_asp(4 * word_size); C_asp(5 * word_size);
} }
else { else {
CodePExpr(nd); CodePExpr(nd);
C_loc(tp->set_low);
C_sbi(word_size);
C_set(tp->tp_size); C_set(tp->tp_size);
C_ior(tp->tp_size); C_ior(tp->tp_size);
} }

View file

@ -258,6 +258,7 @@ cstset(expp)
assert(expp->nd_left->nd_class == Value); assert(expp->nd_left->nd_class == Value);
expp->nd_left->nd_INT -= expp->nd_right->nd_type->set_low;
i = expp->nd_left->nd_INT; i = expp->nd_left->nd_INT;
expp->nd_class = Value; expp->nd_class = Value;
expp->nd_INT = (expp->nd_left->nd_INT >= 0 && expp->nd_INT = (expp->nd_left->nd_INT >= 0 &&

View file

@ -62,9 +62,6 @@ 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\-i\fR\fInum\fR
maximum number of bits in a set. When not used, a default value is
retained.
.IP \fB\-s\fR .IP \fB\-s\fR
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER). make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
This is useful for interpreters that use the "real" MIN(INTEGER) to This is useful for interpreters that use the "real" MIN(INTEGER) to

View file

@ -51,19 +51,6 @@ DoOption(text)
options[text[-1]]++; options[text[-1]]++;
break; break;
case 'i': /* # of bits in set */
{
char *t = text;
int val;
extern int maxset;
val = txt2int(&t);
if (val <= 0 || *t) {
error("bad -i flag; use -i<num>");
}
else maxset = val;
break;
}
case 'w': case 'w':
if (*text) { if (*text) {
while (*text) { while (*text) {

View file

@ -65,6 +65,11 @@ struct proc {
#define prc_nbpar tp_value.tp_proc.pr_nbpar #define prc_nbpar tp_value.tp_proc.pr_nbpar
}; };
struct set {
arith st_low;
#define set_low tp_value.tp_set.st_low
};
struct type { struct type {
struct type *tp_next; /* used with ARRAY, PROCEDURE, POINTER, SET, struct type *tp_next; /* used with ARRAY, PROCEDURE, POINTER, SET,
SUBRANGE, EQUAL SUBRANGE, EQUAL
@ -98,6 +103,7 @@ struct type {
struct array *tp_arr; struct array *tp_arr;
struct record tp_record; struct record tp_record;
struct proc tp_proc; struct proc tp_proc;
struct set tp_set;
} tp_value; } tp_value;
}; };

View file

@ -11,7 +11,6 @@
#include "target_sizes.h" #include "target_sizes.h"
#include "debug.h" #include "debug.h"
#include "maxset.h"
#include <assert.h> #include <assert.h>
#include <alloc.h> #include <alloc.h>
@ -29,6 +28,7 @@
#include "scope.h" #include "scope.h"
#include "walk.h" #include "walk.h"
#include "chk_expr.h" #include "chk_expr.h"
#include "warning.h"
int int
word_align = AL_WORD, word_align = AL_WORD,
@ -40,9 +40,6 @@ int
pointer_align = AL_POINTER, pointer_align = AL_POINTER,
struct_align = AL_STRUCT; struct_align = AL_STRUCT;
int
maxset = MAXSET;
arith arith
word_size = SZ_WORD, word_size = SZ_WORD,
dword_size = 2 * SZ_WORD, dword_size = 2 * SZ_WORD,
@ -467,7 +464,7 @@ set_type(tp)
/* Construct a set type with base type "tp", but first /* Construct a set type with base type "tp", but first
perform some checks perform some checks
*/ */
arith lb, ub; arith lb, ub, diff;
if (! bounded(tp)) { if (! bounded(tp)) {
error("illegal base type for set"); error("illegal base type for set");
@ -476,13 +473,19 @@ set_type(tp)
getbounds(tp, &lb, &ub); getbounds(tp, &lb, &ub);
if (lb < 0 || ub > maxset-1 || (sizeof(int)==2 && ub > 65535)) { if (lb < 0) {
warning(W_STRICT, "base type of set has negative lower bound");
}
diff = ub - lb + 1;
if (diff < 0 || (sizeof(int) == 2 && diff > 65535)) {
error("set type limits exceeded"); error("set type limits exceeded");
return error_type; return error_type;
} }
tp = construct_type(T_SET, tp); tp = construct_type(T_SET, tp);
tp->tp_size = WA((ub + 8) >> 3); tp->tp_size = WA((diff + 7) >> 3);
tp->set_low = lb;
return tp; return tp;
} }