sets now allowed for all subranges
This commit is contained in:
parent
d80b501829
commit
b668810351
10 changed files with 36 additions and 38 deletions
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
static char Version[] = "ACK Modula-2 compiler Version 0.23";
|
static char Version[] = "ACK Modula-2 compiler Version 0.24";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue