newer version

This commit is contained in:
ceriel 1986-11-26 16:40:45 +00:00
parent 552f5a3f61
commit da54801353
19 changed files with 264 additions and 205 deletions

View file

@ -106,9 +106,8 @@ GetString(upto)
} }
str->s_length = p - str->s_str; str->s_length = p - str->s_str;
while (p - str->s_str < len) *p++ = '\0'; while (p - str->s_str < len) *p++ = '\0';
if (str->s_length == 0) str->s_length = 1; /* ??? string length if (str->s_length == 0) str->s_length = 1;
at least 1 ??? /* ??? string length at least 1 ??? */
*/
return str; return str;
} }
@ -239,12 +238,10 @@ again1:
goto again; goto again;
case STGARB: case STGARB:
if (040 < ch && ch < 0177) { if ((unsigned) ch - 040 < 0137) {
lexerror("garbage char %c", ch); lexerror("garbage char %c", ch);
} }
else { else lexerror("garbage char \\%03o", ch);
lexerror("garbage char \\%03o", ch);
}
goto again; goto again;
case STSIMP: case STSIMP:

View file

@ -5,11 +5,11 @@ PKGDIR = $(EMDIR)/modules/pkg
LIBDIR = $(EMDIR)/modules/lib LIBDIR = $(EMDIR)/modules/lib
OBJECTCODE = $(LIBDIR)/libemk.a OBJECTCODE = $(LIBDIR)/libemk.a
LLGEN = $(EMDIR)/bin/LLgen LLGEN = $(EMDIR)/bin/LLgen
CURRDIR = .
INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR) INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR)
GFILES = tokenfile.g program.g declar.g expression.g statement.g GFILES = tokenfile.g program.g declar.g expression.g statement.g
CC = cc
LLGENOPTIONS = LLGENOPTIONS =
PROFILE = PROFILE =
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC= CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
@ -50,14 +50,14 @@ GENFILES = $(GENGFILES) $(GENCFILES) $(GENHFILES)
#EXCLEXCLEXCLEXCL #EXCLEXCLEXCLEXCL
all: Cfiles all: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make ../comp/main ; else sh Resolve ../comp/main ; fi' sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make $(CURRDIR)/main ; else sh Resolve main ; fi'
@rm -f nmclash.o a.out @rm -f nmclash.o a.out
install: all install: all
cp main $(EMDIR)/lib/em_m2 cp $(CURRDIR)/main $(EMDIR)/lib/em_m2
clean: clean:
rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab clashes main rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab clashes $(CURRDIR)/main
(cd .. ; rm -rf Xsrc) (cd .. ; rm -rf Xsrc)
lint: Cfiles lint: Cfiles
@ -123,9 +123,9 @@ depend:
Xlint: Xlint:
lint $(INCLUDES) $(LINTFLAGS) $(SRC) lint $(INCLUDES) $(LINTFLAGS) $(SRC)
../comp/main: $(OBJ) ../comp/Makefile $(CURRDIR)/main: $(OBJ)
$(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(OBJECTCODE) $(LIBDIR)/libinput.a $(LIBDIR)/libassert.a $(LIBDIR)/liballoc.a $(MALLOC) $(LIBDIR)/libprint.a $(LIBDIR)/libstring.a $(LIBDIR)/libsystem.a -o ../comp/main $(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(OBJECTCODE) $(LIBDIR)/libinput.a $(LIBDIR)/libassert.a $(LIBDIR)/liballoc.a $(MALLOC) $(LIBDIR)/libprint.a $(LIBDIR)/libstring.a $(LIBDIR)/libsystem.a -o $(CURRDIR)/main
size ../comp/main size $(CURRDIR)/main
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
LLlex.o: LLlex.h Lpars.h class.h const.h debug.h debugcst.h f_info.h idf.h idfsize.h input.h inputtype.h numsize.h strsize.h type.h warning.h LLlex.o: LLlex.h Lpars.h class.h const.h debug.h debugcst.h f_info.h idf.h idfsize.h input.h inputtype.h numsize.h strsize.h type.h warning.h

View file

@ -8,8 +8,11 @@ case $# in
exit 1 exit 1
;; ;;
esac esac
currdir=`pwd`
case $1 in case $1 in
../comp/main|Xlint) main) target=$currdir/$1
;;
Xlint) target=$1
;; ;;
*) echo "$0: $1: Illegal argument" 1>&2 *) echo "$0: $1: Illegal argument" 1>&2
exit 1 exit 1
@ -48,4 +51,4 @@ $i: clashes $PW/$i
cid -Fclashes < $PW/$i > $i cid -Fclashes < $PW/$i > $i
EOF EOF
done done
make $1 make CURRDIR=$currdir $target

View file

@ -438,6 +438,7 @@ getarg(argp, bases, designator, edf)
} }
left = arg->nd_left; left = arg->nd_left;
*argp = arg;
if (designator ? !ChkVariable(left) : !ChkExpression(left)) { if (designator ? !ChkVariable(left) : !ChkExpression(left)) {
return 0; return 0;
@ -454,7 +455,6 @@ getarg(argp, bases, designator, edf)
} }
} }
*argp = arg;
return left; return left;
} }
@ -470,6 +470,8 @@ getname(argp, kinds, bases, edf)
register struct node *arg = *argp; register struct node *arg = *argp;
register struct node *left; register struct node *left;
*argp = arg->nd_right;
if (!arg->nd_right) { if (!arg->nd_right) {
Xerror(arg, "too few arguments supplied", edf); Xerror(arg, "too few arguments supplied", edf);
return 0; return 0;
@ -496,7 +498,6 @@ getname(argp, kinds, bases, edf)
} }
} }
*argp = arg;
return left; return left;
} }
@ -539,7 +540,7 @@ ChkProcCall(expp)
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
TryToString(left, TypeOfParam(param)); TryToString(left, TypeOfParam(param));
} }
if (! TstParCompat(RemoveEqual(TypeOfParam(param)), else if (! TstParCompat(RemoveEqual(TypeOfParam(param)),
left->nd_type, left->nd_type,
IsVarParam(param), IsVarParam(param),
left)) { left)) {
@ -552,6 +553,9 @@ ChkProcCall(expp)
if (expp->nd_right) { if (expp->nd_right) {
Xerror(expp->nd_right, "too many parameters supplied", edf); Xerror(expp->nd_right, "too many parameters supplied", edf);
while (expp->nd_right) {
getarg(&expp, 0, 0, edf);
}
return 0; return 0;
} }
@ -581,7 +585,7 @@ ChkCall(expp)
return ChkCast(expp, left); return ChkCast(expp, left);
} }
if (IsProcCall(left)) { if (IsProcCall(left) || left->nd_type == error_type) {
/* A procedure call. /* A procedure call.
It may also be a call to a standard procedure It may also be a call to a standard procedure
*/ */

View file

@ -86,7 +86,6 @@ CodePadString(nd, sz)
C_loi(sizearg); C_loi(sizearg);
} }
CodeExpr(nd, ds, true_label, false_label) CodeExpr(nd, ds, true_label, false_label)
register struct node *nd; register struct node *nd;
register struct desig *ds; register struct desig *ds;
@ -365,27 +364,37 @@ CodeParameters(param, arg)
left = arg->nd_left; left = arg->nd_left;
left_type = left->nd_type; left_type = left->nd_type;
if (IsConformantArray(tp)) { if (IsConformantArray(tp)) {
register struct type *elem = tp->arr_elem;
C_loc(tp->arr_elsize); C_loc(tp->arr_elsize);
if (IsConformantArray(left_type)) { if (IsConformantArray(left_type)) {
DoHIGH(left); DoHIGH(left);
if (tp->arr_elem->tp_size != if (elem->tp_size != left_type->arr_elem->tp_size) {
left_type->arr_elem->tp_size) {
/* This can only happen if the formal type is /* This can only happen if the formal type is
ARRAY OF WORD ARRAY OF (WORD|BYTE)
*/ */
assert(tp->arr_elem == word_type);
C_loc(left_type->arr_elem->tp_size); C_loc(left_type->arr_elem->tp_size);
C_cal("_wa"); C_mli(word_size);
C_asp(dword_size); if (elem == word_type) {
C_lfr(word_size); C_loc(word_size - 1);
C_adi(word_size);
C_loc(word_size);
C_dvi(word_size);
}
else {
assert(elem == byte_type);
}
} }
} }
else if (left->nd_symb == STRING) { else if (left->nd_symb == STRING) {
C_loc(left->nd_SLE); C_loc(left->nd_SLE - 1);
} }
else if (tp->arr_elem == word_type) { else if (elem == word_type) {
C_loc((left_type->tp_size+word_size-1) / word_size - 1); C_loc((left_type->tp_size+word_size-1) / word_size - 1);
} }
else if (elem == byte_type) {
C_loc(left_type->tp_size - 1);
}
else { else {
arith lb, ub; arith lb, ub;
getbounds(IndexType(left_type), &lb, &ub); getbounds(IndexType(left_type), &lb, &ub);
@ -395,20 +404,30 @@ CodeParameters(param, arg)
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
CodeString(left); CodeString(left);
} }
else if (left->nd_class == Call) {
/* ouch! forgot about this one! */
arith tmp, TmpSpace();
CodePExpr(left);
tmp = TmpSpace(left->nd_type->tp_size, left->nd_type->tp_align);
C_lal(tmp);
C_sti(WA(left->nd_type->tp_size));
C_lal(tmp);
}
else CodeDAddress(left); else CodeDAddress(left);
return;
} }
else if (IsVarParam(param)) { if (IsVarParam(param)) {
CodeDAddress(left); CodeDAddress(left);
return;
} }
else {
if (left_type->tp_fund == T_STRING) { if (left_type->tp_fund == T_STRING) {
CodePadString(left, tp->tp_size); CodePadString(left, tp->tp_size);
return;
} }
else {
CodePExpr(left); CodePExpr(left);
RangeCheck(left_type, tp); RangeCheck(tp, left_type);
} CodeCoercion(left_type, tp);
}
} }
CodeStd(nd) CodeStd(nd)
@ -538,33 +557,6 @@ CodeStd(nd)
} }
} }
CodeAssign(nd, dss, dst)
register struct node *nd;
struct desig *dst, *dss;
{
/* Generate code for an assignment. Testing of type
compatibility and the like is already done.
*/
register struct type *tp = nd->nd_right->nd_type;
arith size = nd->nd_left->nd_type->tp_size;
if (dss->dsg_kind == DSG_LOADED) {
if (tp->tp_fund == T_STRING) {
CodeAddress(dst);
C_loc(tp->tp_size);
C_loc(size);
C_cal("_StringAssign");
C_asp((int_size << 1) + (pointer_size << 1));
return;
}
CodeStore(dst, size);
return;
}
CodeAddress(dss);
CodeAddress(dst);
C_blm(size);
}
RangeCheck(tpl, tpr) RangeCheck(tpl, tpr)
register struct type *tpl, *tpr; register struct type *tpl, *tpr;
{ {
@ -800,32 +792,30 @@ CodeOper(expr, true_label, false_label)
case OR: case OR:
case AND: case AND:
case '&': { case '&': {
label l_true, l_false, l_maybe = ++text_label, l_end; label l_maybe = ++text_label, l_end;
struct desig Des; struct desig Des;
int genlabels = 0;
if (true_label == 0) { if (true_label == 0) {
l_true = ++text_label; genlabels = 1;
l_false = ++text_label; true_label = ++text_label;
false_label = ++text_label;
l_end = ++text_label; l_end = ++text_label;
} }
else {
l_true = true_label;
l_false = false_label;
}
Des = InitDesig; Des = InitDesig;
if (expr->nd_symb == OR) { if (expr->nd_symb == OR) {
CodeExpr(leftop, &Des, l_true, l_maybe); CodeExpr(leftop, &Des, true_label, l_maybe);
} }
else CodeExpr(leftop, &Des, l_maybe, l_false); else CodeExpr(leftop, &Des, l_maybe, false_label);
C_df_ilb(l_maybe); C_df_ilb(l_maybe);
Des = InitDesig; Des = InitDesig;
CodeExpr(rightop, &Des, l_true, l_false); CodeExpr(rightop, &Des, true_label, false_label);
if (true_label == 0) { if (genlabels) {
C_df_ilb(l_true); C_df_ilb(true_label);
C_loc((arith)1); C_loc((arith)1);
C_bra(l_end); C_bra(l_end);
C_df_ilb(l_false); C_df_ilb(false_label);
C_loc((arith)0); C_loc((arith)0);
C_df_ilb(l_end); C_df_ilb(l_end);
} }

View file

@ -102,10 +102,11 @@ FormalType(struct type **ptp;)
} : } :
ARRAY OF qualtype(ptp) ARRAY OF qualtype(ptp)
{ register struct type *tp = construct_type(T_ARRAY, NULLTYPE); { register struct type *tp = construct_type(T_ARRAY, NULLTYPE);
tp->arr_elem = *ptp; tp->arr_elem = *ptp;
*ptp = tp; *ptp = tp;
tp->arr_elsize = ArrayElSize(tp->arr_elem); tp->arr_elsize = ArrayElSize(tp->arr_elem);
tp->tp_align = lcm(word_align, pointer_align); tp->tp_align = tp->arr_elem->tp_align;
} }
| |
qualtype(ptp) qualtype(ptp)
@ -160,16 +161,18 @@ enumeration(struct type **ptp;)
struct node *EnumList; struct node *EnumList;
} : } :
'(' IdentList(&EnumList) ')' '(' IdentList(&EnumList) ')'
{ { register struct type *tp =
*ptp = standard_type(T_ENUMERATION, int_align, int_size); standard_type(T_ENUMERATION, int_align, int_size);
EnterEnumList(EnumList, *ptp);
if (ufit((*ptp)->enm_ncst-1, 1)) { *ptp = tp;
(*ptp)->tp_size = 1; EnterEnumList(EnumList, tp);
(*ptp)->tp_align = 1; if (ufit(tp->enm_ncst-1, 1)) {
tp->tp_size = 1;
tp->tp_align = 1;
} }
else if (ufit((*ptp)->enm_ncst-1, short_size)) { else if (ufit(tp->enm_ncst-1, short_size)) {
(*ptp)->tp_size = short_size; tp->tp_size = short_size;
(*ptp)->tp_align = short_align; tp->tp_align = short_align;
} }
} }
; ;
@ -234,7 +237,6 @@ RecordType(struct type **ptp;)
{ open_scope(OPENSCOPE); /* scope for fields of record */ { open_scope(OPENSCOPE); /* scope for fields of record */
scope = CurrentScope; scope = CurrentScope;
close_scope(0); close_scope(0);
size = 0;
} }
FieldListSequence(scope, &size, &xalign) FieldListSequence(scope, &size, &xalign)
{ *ptp = standard_type(T_RECORD, xalign, WA(size)); { *ptp = standard_type(T_RECORD, xalign, WA(size));

View file

@ -63,13 +63,20 @@ struct dforward {
#define for_name df_value.df_forward.fo_name #define for_name df_value.df_forward.fo_name
}; };
struct forwtype {
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
};
struct def { /* list of definitions for a name */ struct def { /* list of definitions for a name */
struct def *next; /* next definition in definitions chain */ struct def *next; /* next definition in definitions chain */
struct def *df_nextinscope; struct def *df_nextinscope;
/* link all definitions in a scope */ /* link all definitions in a scope */
struct idf *df_idf; /* link back to the name */ struct idf *df_idf; /* link back to the name */
struct scope *df_scope; /* scope in which this definition resides */ struct scope *df_scope; /* scope in which this definition resides */
short df_kind; /* the kind of this definition: */ unsigned short df_kind; /* the kind of this definition: */
#define D_MODULE 0x0001 /* a module */ #define D_MODULE 0x0001 /* a module */
#define D_PROCEDURE 0x0002 /* procedure of function */ #define D_PROCEDURE 0x0002 /* procedure of function */
#define D_VARIABLE 0x0004 /* a variable */ #define D_VARIABLE 0x0004 /* a variable */
@ -82,20 +89,22 @@ struct def { /* list of definitions for a name */
#define D_HIDDEN 0x0200 /* a hidden type */ #define D_HIDDEN 0x0200 /* a hidden type */
#define D_FORWARD 0x0400 /* not yet defined */ #define D_FORWARD 0x0400 /* not yet defined */
#define D_FORWMODULE 0x0800 /* module must be declared later */ #define D_FORWMODULE 0x0800 /* module must be declared later */
#define D_ERROR 0x1000 /* a compiler generated definition for an #define D_FORWTYPE 0x1000 /* forward type */
#define D_FTYPE 0x2000 /* resolved forward type */
#define D_ERROR 0x4000 /* a compiler generated definition for an
undefined variable undefined variable
*/ */
#define D_VALUE (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD) #define D_VALUE (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD)
#define D_ISTYPE (D_HIDDEN|D_TYPE) #define D_ISTYPE (D_HIDDEN|D_TYPE|D_FTYPE)
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE) #define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
char df_flags; char df_flags;
#define D_NOREG 0x01 /* set if it may not reside in a register */ #define D_NOREG 0x01 /* set if it may not reside in a register */
#define D_USED 0x02 /* set if used (future use ???) */ #define D_USED 0x02 /* set if used (future use ???) */
#define D_DEFINED 0x04 /* set if it is assigned a value (future use ???) */ #define D_DEFINED 0x04 /* set if it is assigned a value (future use ???) */
#define D_VARPAR 0x10 /* set if it is a VAR parameter */ #define D_VARPAR 0x08 /* set if it is a VAR parameter */
#define D_VALPAR 0x20 /* set if it is a value parameter */ #define D_VALPAR 0x10 /* set if it is a value parameter */
#define D_EXPORTED 0x40 /* set if exported */ #define D_EXPORTED 0x20 /* set if exported */
#define D_QEXPORTED 0x80 /* set if qualified exported */ #define D_QEXPORTED 0x40 /* set if qualified exported */
struct type *df_type; struct type *df_type;
union { union {
struct module df_module; struct module df_module;
@ -106,6 +115,7 @@ struct def { /* list of definitions for a name */
struct import df_import; struct import df_import;
struct dfproc df_proc; struct dfproc df_proc;
struct dforward df_forward; struct dforward df_forward;
struct forwtype df_fortype;
int df_stdname; /* define for standard name */ int df_stdname; /* define for standard name */
} df_value; } df_value;
}; };

View file

@ -21,6 +21,8 @@ struct def *h_def; /* pointer to free list of def structures */
int cnt_def; /* count number of allocated ones */ int cnt_def; /* count number of allocated ones */
#endif #endif
extern int (*c_inp)();
STATIC STATIC
DefInFront(df) DefInFront(df)
register struct def *df; register struct def *df;
@ -129,6 +131,18 @@ define(id, scope, kind)
} }
break; break;
case D_FORWTYPE:
if (kind == D_FORWTYPE) return df;
if (kind == D_TYPE) {
df->df_kind = D_FTYPE;
FreeNode(df->df_forw_node);
}
else {
error("identifier \"%s\" must be a type",
id->id_text);
}
return df;
case D_FORWARD: case D_FORWARD:
/* A forward reference, for which we may now have /* A forward reference, for which we may now have
found a definition. found a definition.
@ -247,7 +261,7 @@ DeclProc(type, id)
df = define(id, CurrentScope, type); df = define(id, CurrentScope, type);
sprint(buf,"_%d_%s",++nmcount,id->id_text); sprint(buf,"_%d_%s",++nmcount,id->id_text);
name = Salloc(buf, (unsigned)(strlen(buf)+1)); name = Salloc(buf, (unsigned)(strlen(buf)+1));
C_inp(buf); (*c_inp)(buf);
} }
open_scope(OPENSCOPE); open_scope(OPENSCOPE);
scope = CurrentScope; scope = CurrentScope;
@ -311,13 +325,13 @@ DefineLocalModule(id)
/* Create a type for it /* Create a type for it
*/ */
df->df_type = standard_type(T_RECORD, 0, (arith) 0); df->df_type = standard_type(T_RECORD, 1, (arith) 0);
df->df_type->rec_scope = sc; df->df_type->rec_scope = sc;
/* Generate code that indicates that the initialization procedure /* Generate code that indicates that the initialization procedure
for this module is local. for this module is local.
*/ */
C_inp(buf); (*c_inp)(buf);
return df; return df;
} }

View file

@ -36,7 +36,7 @@ GetFile(name)
buf[10] = '\0'; /* maximum length */ buf[10] = '\0'; /* maximum length */
strcat(buf, ".def"); strcat(buf, ".def");
if (! InsertFile(buf, DEFPATH, &(FileName))) { if (! InsertFile(buf, DEFPATH, &(FileName))) {
error("could'nt find a DEFINITION MODULE for \"%s\"", name); error("could not find a DEFINITION MODULE for \"%s\"", name);
return 0; return 0;
} }
LineNumber = 1; LineNumber = 1;
@ -56,6 +56,7 @@ GetDefinitionModule(id, incr)
struct def *df; struct def *df;
static int level; static int level;
struct scopelist *vis; struct scopelist *vis;
int didread = 0;
level += incr; level += incr;
df = lookup(id, GlobalScope, 1); df = lookup(id, GlobalScope, 1);
@ -68,6 +69,7 @@ GetDefinitionModule(id, incr)
else { else {
open_scope(CLOSEDSCOPE); open_scope(CLOSEDSCOPE);
if (!is_anon_idf(id) && GetFile(id->id_text)) { if (!is_anon_idf(id) && GetFile(id->id_text)) {
didread = 1;
DefModule(); DefModule();
if (level == 1) { if (level == 1) {
/* The module is directly imported by /* The module is directly imported by
@ -93,6 +95,9 @@ GetDefinitionModule(id, incr)
} }
df = lookup(id, GlobalScope, 1); df = lookup(id, GlobalScope, 1);
if (! df) { if (! df) {
if (didread) {
error("did not read a DEFINITION MODULE for \"%s\"", id->id_text);
}
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;

View file

@ -50,7 +50,7 @@ ExpList(struct node **pnd;)
register struct node *nd; register struct node *nd;
} : } :
expression(pnd) { *pnd = nd = MkNode(Link,*pnd,NULLNODE,&dot); expression(pnd) { *pnd = nd = MkNode(Link,*pnd,NULLNODE,&dot);
(*pnd)->nd_symb = ','; nd->nd_symb = ',';
} }
[ [
',' { nd->nd_right = MkLeaf(Link, &dot); ',' { nd->nd_right = MkLeaf(Link, &dot);
@ -60,20 +60,26 @@ ExpList(struct node **pnd;)
]* ]*
; ;
ConstExpression(struct node **pnd;): ConstExpression(struct node **pnd;)
{
register struct node *nd;
}:
expression(pnd) expression(pnd)
/* /*
* Changed rule in new Modula-2. * Changed rule in new Modula-2.
* Check that the expression is a constant expression and evaluate! * Check that the expression is a constant expression and evaluate!
*/ */
{ DO_DEBUG(options['X'], print("CONSTANT EXPRESSION\n")); { nd = *pnd;
DO_DEBUG(options['X'], PrNode(*pnd, 0)); DO_DEBUG(options['X'], print("CONSTANT EXPRESSION\n"));
if (ChkExpression(*pnd) && DO_DEBUG(options['X'], PrNode(nd, 0));
((*pnd)->nd_class != Set && (*pnd)->nd_class != Value)) {
if (ChkExpression(nd) &&
((nd)->nd_class != Set && (nd)->nd_class != Value)) {
error("constant expression expected"); error("constant expression expected");
} }
DO_DEBUG(options['X'], print("RESULTS IN\n")); DO_DEBUG(options['X'], print("RESULTS IN\n"));
DO_DEBUG(options['X'], PrNode(*pnd, 0)); DO_DEBUG(options['X'], PrNode(nd, 0));
} }
; ;
@ -102,6 +108,7 @@ SimpleExpression(struct node **pnd;)
[ '+' | '-' ] [ '+' | '-' ]
{ *pnd = MkLeaf(Uoper, &dot); { *pnd = MkLeaf(Uoper, &dot);
pnd = &((*pnd)->nd_right); pnd = &((*pnd)->nd_right);
/* priority of unary operator ??? */
} }
]? ]?
term(pnd) term(pnd)

View file

@ -29,6 +29,9 @@ struct def *Defined;
extern int err_occurred; extern int err_occurred;
extern int fp_used; /* set if floating point used */ extern int fp_used; /* set if floating point used */
extern C_inp(), C_exp();
int (*c_inp)() = C_inp;
main(argc, argv) main(argc, argv)
register char **argv; register char **argv;
{ {
@ -49,6 +52,7 @@ main(argc, argv)
fprint(STDERR, "%s: Use a file argument\n", ProgName); fprint(STDERR, "%s: Use a file argument\n", ProgName);
return 1; return 1;
} }
if (options['x']) c_inp = C_exp;
return !Compile(Nargv[1], Nargv[2]); return !Compile(Nargv[1], Nargv[2]);
} }
@ -197,6 +201,7 @@ do_SYSTEM()
*/ */
open_scope(CLOSEDSCOPE); open_scope(CLOSEDSCOPE);
(void) Enter("WORD", D_TYPE, word_type, 0); (void) Enter("WORD", D_TYPE, word_type, 0);
(void) Enter("BYTE", D_TYPE, byte_type, 0);
(void) Enter("ADDRESS", D_TYPE, address_type, 0); (void) Enter("ADDRESS", D_TYPE, address_type, 0);
(void) Enter("ADR", D_PROCEDURE, std_type, S_ADR); (void) Enter("ADR", D_PROCEDURE, std_type, S_ADR);
(void) Enter("TSIZE", D_PROCEDURE, std_type, S_TSIZE); (void) Enter("TSIZE", D_PROCEDURE, std_type, S_TSIZE);
@ -215,14 +220,14 @@ Info()
{ {
extern int cnt_def, cnt_node, cnt_paramlist, cnt_type, extern int cnt_def, cnt_node, cnt_paramlist, cnt_type,
cnt_switch_hdr, cnt_case_entry, cnt_switch_hdr, cnt_case_entry,
cnt_scope, cnt_scopelist, cnt_forwards, cnt_tmpvar; cnt_scope, cnt_scopelist, cnt_tmpvar;
print("\ print("\
%6d def\n%6d node\n%6d paramlist\n%6d type\n%6d switch_hdr\n\ %6d def\n%6d node\n%6d paramlist\n%6d type\n%6d switch_hdr\n\
%6d case_entry\n%6d scope\n%6d scopelist\n%6d forwards\n%6d tmpvar\n", %6d case_entry\n%6d scope\n%6d scopelist\n%6d tmpvar\n",
cnt_def, cnt_node, cnt_paramlist, cnt_type, cnt_def, cnt_node, cnt_paramlist, cnt_type,
cnt_switch_hdr, cnt_case_entry, cnt_switch_hdr, cnt_case_entry,
cnt_scope, cnt_scopelist, cnt_forwards, cnt_tmpvar); cnt_scope, cnt_scopelist, cnt_tmpvar);
print("\nNumber of lines read: %d\n", cntlines); print("\nNumber of lines read: %d\n", cntlines);
} }
#endif #endif

View file

@ -59,10 +59,12 @@ ModuleDeclaration
priority(arith *pprio;) priority(arith *pprio;)
{ {
struct node *nd; register struct node *nd;
struct node *nd1; /* &nd is illegal */
} : } :
'[' ConstExpression(&nd) ']' '[' ConstExpression(&nd1) ']'
{ if (!(nd->nd_type->tp_fund & T_CARDINAL)) { { nd = nd1;
if (!(nd->nd_type->tp_fund & T_CARDINAL)) {
node_error(nd, "illegal priority"); node_error(nd, "illegal priority");
} }
*pprio = nd->nd_INT; *pprio = nd->nd_INT;
@ -70,9 +72,7 @@ priority(arith *pprio;)
} }
; ;
export(int *QUALflag; struct node **ExportList;) export(int *QUALflag; struct node **ExportList;):
{
} :
EXPORT EXPORT
[ [
QUALIFIED QUALIFIED
@ -86,7 +86,7 @@ export(int *QUALflag; struct node **ExportList;)
import(int local;) import(int local;)
{ {
struct node *ImportList; struct node *ImportList;
struct node *FromId = 0; register struct node *FromId = 0;
register struct def *df; register struct def *df;
extern struct def *GetDefinitionModule(); extern struct def *GetDefinitionModule();
} : } :
@ -121,7 +121,7 @@ DefinitionModule
if (!Defined) Defined = df; if (!Defined) Defined = df;
CurrentScope->sc_name = df->df_idf->id_text; CurrentScope->sc_name = df->df_idf->id_text;
df->mod_vis = CurrVis; df->mod_vis = CurrVis;
df->df_type = standard_type(T_RECORD, 0, (arith) 0); df->df_type = standard_type(T_RECORD, 1, (arith) 0);
df->df_type->rec_scope = df->mod_vis->sc_scope; df->df_type->rec_scope = df->mod_vis->sc_scope;
DefinitionModule++; DefinitionModule++;
} }
@ -210,12 +210,9 @@ ProgramModule
; ;
Module: Module:
{ open_scope(CLOSEDSCOPE); DEFINITION
warning(W_ORDINARY, "Compiling a definition module"); { fatal("Compiling a definition module"); }
} | %default
DefinitionModule
{ close_scope(SC_CHKFORW); }
|
[ [
IMPLEMENTATION { state = IMPLEMENTATION; } IMPLEMENTATION { state = IMPLEMENTATION; }
| |

View file

@ -50,7 +50,6 @@ InitScope()
register struct scopelist *ls = new_scopelist(); register struct scopelist *ls = new_scopelist();
sc->sc_scopeclosed = 0; sc->sc_scopeclosed = 0;
sc->sc_forw = 0;
sc->sc_def = 0; sc->sc_def = 0;
sc->sc_level = proclevel; sc->sc_level = proclevel;
PervasiveScope = sc; PervasiveScope = sc;
@ -61,14 +60,6 @@ InitScope()
CurrVis = ls; CurrVis = ls;
} }
struct forwards {
struct forwards *next;
struct node *fo_tok;
struct type *fo_ptyp;
};
/* STATICALLOCDEF "forwards" 5 */
Forward(tk, ptp) Forward(tk, ptp)
struct node *tk; struct node *tk;
struct type *ptp; struct type *ptp;
@ -78,13 +69,10 @@ Forward(tk, ptp)
may have forward references that must howewer be declared in the may have forward references that must howewer be declared in the
same scope. same scope.
*/ */
register struct forwards *f = new_forwards(); register struct def *df = define(tk->nd_IDF, CurrentScope, D_FORWTYPE);
register struct scope *sc = CurrentScope;
f->fo_tok = tk; df->df_forw_type = ptp;
f->fo_ptyp = ptp; df->df_forw_node = tk;
f->next = sc->sc_forw;
sc->sc_forw = f;
} }
STATIC STATIC
@ -117,7 +105,15 @@ chk_forw(pdf)
register struct def *df; register struct def *df;
while (df = *pdf) { while (df = *pdf) {
if (df->df_kind & (D_FORWARD|D_FORWMODULE)) { if (df->df_kind == D_FORWTYPE) {
node_error(df->df_forw_node, "type \"%s\" not declared", df->df_idf->id_text);
FreeNode(df->df_forw_node);
}
else if (df->df_kind == D_FTYPE) {
df->df_kind = D_TYPE;
df->df_forw_type->next = df->df_type;
}
else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
/* These definitions must be found in /* These definitions must be found in
the enclosing closed scope, which of course the enclosing closed scope, which of course
may be the scope that is now closed! may be the scope that is now closed!
@ -126,7 +122,7 @@ chk_forw(pdf)
/* Indeed, the scope was a closed /* Indeed, the scope was a closed
scope, so give error message scope, so give error message
*/ */
node_error(df->for_node, "identifier \"%s\" has not been declared", node_error(df->for_node, "identifier \"%s\" not declared",
df->df_idf->id_text); df->df_idf->id_text);
FreeNode(df->for_node); FreeNode(df->for_node);
} }
@ -153,25 +149,6 @@ df->df_idf->id_text);
} }
} }
STATIC
rem_forwards(fo)
register struct forwards *fo;
{
/* When closing a scope, all forward references must be resolved
*/
register struct def *df;
if (fo->next) rem_forwards(fo->next);
df = lookfor(fo->fo_tok, CurrVis, 0);
if (! is_type(df)) {
node_error(fo->fo_tok,
"identifier \"%s\" does not represent a type",
df->df_idf->id_text);
}
fo->fo_ptyp->next = df->df_type;
free_forwards(fo);
}
Reverse(pdf) Reverse(pdf)
struct def **pdf; struct def **pdf;
{ {
@ -210,7 +187,6 @@ close_scope(flag)
assert(sc != 0); assert(sc != 0);
if (flag) { if (flag) {
if (sc->sc_forw) rem_forwards(sc->sc_forw);
DO_DEBUG(options['S'], PrScopeDef(sc->sc_def)); DO_DEBUG(options['S'], PrScopeDef(sc->sc_def));
if (flag & SC_CHKPROC) chk_proc(sc->sc_def); if (flag & SC_CHKPROC) chk_proc(sc->sc_def);
if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def)); if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def));

View file

@ -15,7 +15,6 @@
struct scope { struct scope {
struct scope *next; struct scope *next;
struct forwards *sc_forw;
char *sc_name; /* name of this scope */ char *sc_name; /* name of this scope */
struct def *sc_def; /* list of definitions in this scope */ struct def *sc_def; /* list of definitions in this scope */
arith sc_off; /* offsets of variables in this scope */ arith sc_off; /* offsets of variables in this scope */

View file

@ -40,6 +40,16 @@ TmpOpen(sc) struct scope *sc;
ProcScope = sc; ProcScope = sc;
} }
arith
TmpSpace(sz, al)
arith sz;
{
register struct scope *sc = ProcScope;
sc->sc_off = - WA(align(sz - sc->sc_off, al));
return sc->sc_off;
}
arith arith
NewInt() NewInt()
{ {
@ -47,8 +57,7 @@ NewInt()
register struct tmpvar *tmp; register struct tmpvar *tmp;
if (!TmpInts) { if (!TmpInts) {
offset = - WA(align(int_size - ProcScope->sc_off, int_align)); offset = TmpSpace(int_size, int_align);
ProcScope->sc_off = offset;
if (! options['n']) C_ms_reg(offset, int_size, reg_any, 0); if (! options['n']) C_ms_reg(offset, int_size, reg_any, 0);
} }
else { else {
@ -67,8 +76,7 @@ NewPtr()
register struct tmpvar *tmp; register struct tmpvar *tmp;
if (!TmpPtrs) { if (!TmpPtrs) {
offset = - WA(align(pointer_size - ProcScope->sc_off, pointer_align)); offset = TmpSpace(pointer_size, pointer_align);
ProcScope->sc_off = offset;
if (! options['n']) C_ms_reg(offset, pointer_size, reg_pointer, 0); if (! options['n']) C_ms_reg(offset, pointer_size, reg_pointer, 0);
} }
else { else {

View file

@ -95,6 +95,7 @@ extern struct type
*real_type, *real_type,
*longreal_type, *longreal_type,
*word_type, *word_type,
*byte_type,
*address_type, *address_type,
*intorcard_type, *intorcard_type,
*bitset_type, *bitset_type,

View file

@ -48,6 +48,7 @@ struct type
*real_type, *real_type,
*longreal_type, *longreal_type,
*word_type, *word_type,
*byte_type,
*address_type, *address_type,
*intorcard_type, *intorcard_type,
*bitset_type, *bitset_type,
@ -123,7 +124,7 @@ standard_type(fund, align, size)
register struct type *tp = new_type(); register struct type *tp = new_type();
tp->tp_fund = fund; tp->tp_fund = fund;
tp->tp_align = align; tp->tp_align = align ? align : 1;
tp->tp_size = size; tp->tp_size = size;
return tp; return tp;
@ -179,6 +180,7 @@ InitTypes()
/* SYSTEM types /* SYSTEM types
*/ */
word_type = standard_type(T_WORD, word_align, word_size); word_type = standard_type(T_WORD, word_align, word_size);
byte_type = standard_type(T_WORD, 1, (arith) 1);
address_type = construct_type(T_POINTER, word_type); address_type = construct_type(T_POINTER, word_type);
/* create BITSET type /* create BITSET type
@ -407,11 +409,11 @@ ArrayElSize(tp)
if (tp->tp_fund == T_ARRAY) ArraySizes(tp); if (tp->tp_fund == T_ARRAY) ArraySizes(tp);
algn = align(tp->tp_size, tp->tp_align); algn = align(tp->tp_size, tp->tp_align);
if (algn && word_size % algn != 0) { if (word_size % algn != 0) {
/* algn is not a dividor of the word size, so make sure it /* algn is not a dividor of the word size, so make sure it
is a multiple is a multiple
*/ */
algn = WA(algn); return WA(algn);
} }
return algn; return algn;
} }
@ -432,13 +434,13 @@ ArraySizes(tp)
*/ */
if (! bounded(index_type)) { if (! bounded(index_type)) {
error("illegal index type"); error("illegal index type");
tp->tp_size = 0; tp->tp_size = tp->arr_elsize;
return; return;
} }
getbounds(index_type, &lo, &hi); getbounds(index_type, &lo, &hi);
tp->tp_size = WA((hi - lo + 1) * tp->arr_elsize); tp->tp_size = (hi - lo + 1) * tp->arr_elsize;
/* generate descriptor and remember label. /* generate descriptor and remember label.
*/ */

View file

@ -177,7 +177,7 @@ TstParCompat(formaltype, actualtype, VARflag, nd)
/* Check type compatibility for a parameter in a procedure call. /* Check type compatibility for a parameter in a procedure call.
Assignment compatibility may do if the parameter is Assignment compatibility may do if the parameter is
a value parameter. a value parameter.
Otherwise, a conformant array may do, or an ARRAY OF WORD Otherwise, a conformant array may do, or an ARRAY OF (WORD|BYTE)
may do too. may do too.
Or: a WORD may do. Or: a WORD may do.
*/ */
@ -201,10 +201,15 @@ TstParCompat(formaltype, actualtype, VARflag, nd)
) )
) )
) )
||
( formaltype == byte_type
&& actualtype->tp_size == (arith) 1
)
|| ||
( IsConformantArray(formaltype) ( IsConformantArray(formaltype)
&& &&
( formaltype->arr_elem == word_type ( formaltype->arr_elem == word_type
|| formaltype->arr_elem == byte_type
|| ||
( actualtype->tp_fund == T_ARRAY ( actualtype->tp_fund == T_ARRAY
&& TstTypeEquiv(formaltype->arr_elem,actualtype->arr_elem) && TstTypeEquiv(formaltype->arr_elem,actualtype->arr_elem)

View file

@ -44,13 +44,15 @@ DoProfil()
static label filename_label = 0; static label filename_label = 0;
if (! options['L']) { if (! options['L']) {
if (!filename_label) { register label fn_label = filename_label;
filename_label = ++data_label;
C_df_dlb(filename_label); if (!fn_label) {
filename_label = fn_label = ++data_label;
C_df_dlb(fn_label);
C_rom_scon(FileName, (arith) (strlen(FileName) + 1)); C_rom_scon(FileName, (arith) (strlen(FileName) + 1));
} }
C_fil_dlb(filename_label, (arith) 0); C_fil_dlb(fn_label, (arith) 0);
} }
} }
@ -126,7 +128,7 @@ WalkProcedure(procedure)
local definitions, checking and generating code. local definitions, checking and generating code.
*/ */
struct scopelist *savevis = CurrVis; struct scopelist *savevis = CurrVis;
register struct scope *sc; register struct scope *sc = procedure->prc_vis->sc_scope;
register struct type *tp; register struct type *tp;
register struct paramlist *param; register struct paramlist *param;
label func_res_label = 0; label func_res_label = 0;
@ -136,7 +138,6 @@ WalkProcedure(procedure)
proclevel++; proclevel++;
CurrVis = procedure->prc_vis; CurrVis = procedure->prc_vis;
sc = CurrentScope;
/* Generate code for all local modules and procedures /* Generate code for all local modules and procedures
*/ */
@ -390,7 +391,7 @@ WalkCall(nd)
} }
WalkStat(nd, exit_label) WalkStat(nd, exit_label)
struct node *nd; register struct node *nd;
label exit_label; label exit_label;
{ {
/* Walk through a statement, generating code for it. /* Walk through a statement, generating code for it.
@ -468,10 +469,11 @@ WalkStat(nd, exit_label)
{ {
arith tmp = 0; arith tmp = 0;
register struct node *fnd; register struct node *fnd;
int good_forvar;
label l1 = ++text_label; label l1 = ++text_label;
label l2 = ++text_label; label l2 = ++text_label;
if (! DoForInit(nd, left)) break; good_forvar = DoForInit(nd, left);
fnd = left->nd_right; fnd = left->nd_right;
if (fnd->nd_class != Value) { if (fnd->nd_class != Value) {
/* Upperbound not constant. /* Upperbound not constant.
@ -489,15 +491,19 @@ WalkStat(nd, exit_label)
C_bgt(l2); C_bgt(l2);
} }
else C_blt(l2); else C_blt(l2);
if (good_forvar) {
RangeCheck(nd->nd_type, int_type); RangeCheck(nd->nd_type, int_type);
CodeDStore(nd); CodeDStore(nd);
}
WalkNode(right, exit_label); WalkNode(right, exit_label);
if (good_forvar) {
CodePExpr(nd); CodePExpr(nd);
C_loc(left->nd_INT); C_loc(left->nd_INT);
C_adi(int_size); C_adi(int_size);
C_bra(l1); C_bra(l1);
C_df_ilb(l2); C_df_ilb(l2);
C_asp(int_size); C_asp(int_size);
}
if (tmp) FreeInt(tmp); if (tmp) FreeInt(tmp);
} }
break; break;
@ -545,14 +551,23 @@ WalkStat(nd, exit_label)
case RETURN: case RETURN:
if (right) { if (right) {
if (! WalkExpr(right)) break; if (! ChkExpression(right)) break;
/* The type of the return-expression must be /* The type of the return-expression must be
assignment compatible with the result type of the assignment compatible with the result type of the
function procedure (See Rep. 9.11). function procedure (See Rep. 9.11).
*/ */
if (!TstAssCompat(func_type, right->nd_type)) { if (!TstAssCompat(func_type, right->nd_type)) {
node_error(right, "type incompatibility in RETURN statement"); node_error(right, "type incompatibility in RETURN statement");
break;
} }
if (right->nd_type->tp_fund == T_STRING) {
arith strsize = WA(right->nd_type->tp_size);
C_zer(WA(func_type->tp_size) - strsize);
CodePExpr(right);
C_loi(strsize);
}
else CodePExpr(right);
} }
C_bra(RETURN_LABEL); C_bra(RETURN_LABEL);
break; break;
@ -644,12 +659,12 @@ DoForInit(nd, left)
if (df->df_kind == D_FIELD) { if (df->df_kind == D_FIELD) {
node_error(nd, node_error(nd,
"FOR-loop variable may not be a field of a record"); "FOR-loop variable may not be a field of a record");
return 0; return 1;
} }
if (!df->var_name && df->var_off >= 0) { if (!df->var_name && df->var_off >= 0) {
node_error(nd, "FOR-loop variable may not be a parameter"); node_error(nd, "FOR-loop variable may not be a parameter");
return 0; return 1;
} }
if (df->df_scope != CurrentScope) { if (df->df_scope != CurrentScope) {
@ -659,7 +674,7 @@ DoForInit(nd, left)
if (!sc) { if (!sc) {
node_error(nd, node_error(nd,
"FOR-loop variable may not be imported"); "FOR-loop variable may not be imported");
return 0; return 1;
} }
if (sc->sc_scope == df->df_scope) break; if (sc->sc_scope == df->df_scope) break;
sc = nextvisible(sc); sc = nextvisible(sc);
@ -669,7 +684,7 @@ DoForInit(nd, left)
if (df->df_type->tp_size > word_size || if (df->df_type->tp_size > word_size ||
!(df->df_type->tp_fund & T_DISCRETE)) { !(df->df_type->tp_fund & T_DISCRETE)) {
node_error(nd, "illegal type of FOR loop variable"); node_error(nd, "illegal type of FOR loop variable");
return 0; return 1;
} }
if (!TstCompat(df->df_type, left->nd_left->nd_type) || if (!TstCompat(df->df_type, left->nd_left->nd_type) ||
@ -677,7 +692,7 @@ DoForInit(nd, left)
if (!TstAssCompat(df->df_type, left->nd_left->nd_type) || if (!TstAssCompat(df->df_type, left->nd_left->nd_type) ||
!TstAssCompat(df->df_type, left->nd_right->nd_type)) { !TstAssCompat(df->df_type, left->nd_right->nd_type)) {
node_error(nd, "type incompatibility in FOR statement"); node_error(nd, "type incompatibility in FOR statement");
return 0; return 1;
} }
node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement"); node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
} }
@ -695,29 +710,48 @@ DoAssign(nd, left, right)
DAMN THE BOOK! DAMN THE BOOK!
*/ */
struct desig dsl, dsr; struct desig dsl, dsr;
register struct type *rtp, *ltp;
if (! (ChkExpression(right) & ChkVariable(left))) return; if (! (ChkExpression(right) & ChkVariable(left))) return;
rtp = right->nd_type;
ltp = left->nd_type;
if (right->nd_symb == STRING) TryToString(right, left->nd_type); if (right->nd_symb == STRING) TryToString(right, ltp);
dsr = InitDesig; dsr = InitDesig;
if (! TstAssCompat(left->nd_type, right->nd_type)) { if (! TstAssCompat(ltp, rtp)) {
node_error(nd, "type incompatibility in assignment"); node_error(nd, "type incompatibility in assignment");
return; return;
} }
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL); CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);
if (complex(right->nd_type)) { if (complex(rtp)) CodeAddress(&dsr);
CodeAddress(&dsr);
}
else { else {
CodeValue(&dsr, right->nd_type->tp_size); CodeValue(&dsr, rtp->tp_size);
RangeCheck(left->nd_type, right->nd_type); RangeCheck(ltp, rtp);
CodeCoercion(rtp, ltp);
} }
dsl = InitDesig; dsl = InitDesig;
CodeDesig(left, &dsl); CodeDesig(left, &dsl);
CodeAssign(nd, &dsr, &dsl); /* Generate code for an assignment. Testing of type
compatibility and the like is already done.
*/
if (dsr.dsg_kind == DSG_LOADED) {
if (rtp->tp_fund == T_STRING) {
CodeAddress(&dsl);
C_loc(rtp->tp_size);
C_loc(ltp->tp_size);
C_cal("_StringAssign");
C_asp((int_size << 1) + (pointer_size << 1));
return;
}
CodeStore(&dsl, ltp->tp_size);
return;
}
CodeAddress(&dsl);
C_blm(ltp->tp_size);
} }
RegisterMessages(df) RegisterMessages(df)