newer version with bug fixes
This commit is contained in:
parent
e1c67b1fba
commit
a0db745586
14 changed files with 452 additions and 320 deletions
|
@ -1,16 +1,16 @@
|
||||||
# make modula-2 "compiler"
|
# make modula-2 "compiler"
|
||||||
# $Header$
|
# $Header$
|
||||||
EMDIR = /usr/em
|
EMDIR = /usr/ceriel/em
|
||||||
MHDIR = $(EMDIR)/modules/h
|
MHDIR = $(EMDIR)/modules/h
|
||||||
PKGDIR = $(EMDIR)/modules/pkg
|
PKGDIR = $(EMDIR)/modules/pkg
|
||||||
LIBDIR = $(EMDIR)/modules/lib
|
LIBDIR = $(EMDIR)/modules/lib
|
||||||
LLGEN = $(EMDIR)/util/LLgen/src/LLgen
|
LLGEN = $(EMDIR)/bin/LLgen
|
||||||
|
|
||||||
INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR)
|
INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR)
|
||||||
|
|
||||||
LSRC = tokenfile.g program.g declar.g expression.g statement.g
|
LSRC = tokenfile.g program.g declar.g expression.g statement.g
|
||||||
CC = cc
|
CC = cc
|
||||||
LLGENOPTIONS = -d
|
LLGENOPTIONS =
|
||||||
PROFILE =
|
PROFILE =
|
||||||
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
|
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
|
||||||
LINTFLAGS = -DSTATIC= -DNORCSID
|
LINTFLAGS = -DSTATIC= -DNORCSID
|
||||||
|
@ -23,7 +23,7 @@ COBJ = LLlex.o LLmessage.o char.o error.o main.o \
|
||||||
code.o tmpvar.o lookup.o
|
code.o tmpvar.o lookup.o
|
||||||
OBJ = $(COBJ) $(LOBJ) Lpars.o
|
OBJ = $(COBJ) $(LOBJ) Lpars.o
|
||||||
|
|
||||||
# Keep the next three entries up to date!
|
# Keep the next entries up to date!
|
||||||
GENCFILES= tokenfile.c \
|
GENCFILES= tokenfile.c \
|
||||||
program.c declar.c expression.c statement.c \
|
program.c declar.c expression.c statement.c \
|
||||||
symbol2str.c char.c Lpars.c casestat.c tmpvar.c scope.c
|
symbol2str.c char.c Lpars.c casestat.c tmpvar.c scope.c
|
||||||
|
@ -32,12 +32,42 @@ GENHFILES= errout.h\
|
||||||
idfsize.h numsize.h strsize.h target_sizes.h debug.h\
|
idfsize.h numsize.h strsize.h target_sizes.h debug.h\
|
||||||
inputtype.h maxset.h ndir.h density.h\
|
inputtype.h maxset.h ndir.h density.h\
|
||||||
def.h type.h Lpars.h node.h
|
def.h type.h Lpars.h node.h
|
||||||
|
HFILES= LLlex.h\
|
||||||
|
chk_expr.h class.h const.h desig.h f_info.h idf.h\
|
||||||
|
input.h main.h misc.h scope.h standards.h tokenname.h\
|
||||||
|
walk.h $(GENHFILES)
|
||||||
#
|
#
|
||||||
GENFILES = $(GENGFILES) $(GENCFILES) $(GENHFILES)
|
GENFILES = $(GENGFILES) $(GENCFILES) $(GENHFILES)
|
||||||
all:
|
|
||||||
make hfiles
|
all: Cfiles
|
||||||
make LLfiles
|
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make main ; else sh Resolve main ; fi'
|
||||||
make main
|
@rm -f nmclash.o a.out
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab cclash.o cid.o cclash cid
|
||||||
|
(cd .. ; rm -rf Xsrc)
|
||||||
|
|
||||||
|
lint: Cfiles
|
||||||
|
sh -c `if $(CC) nmclash.c > /dev/null 2>&1 ; then make Xlint ; else sh Resolve Xlint ; fi'
|
||||||
|
@rm -f nmclash.o a.out
|
||||||
|
|
||||||
|
mkdep: mkdep.o
|
||||||
|
$(CC) -o mkdep mkdep.o
|
||||||
|
|
||||||
|
cclash: cclash.o
|
||||||
|
$(CC) -o cclash cclash.o
|
||||||
|
|
||||||
|
cid: cid.o
|
||||||
|
$(CC) -o cid cid.o
|
||||||
|
|
||||||
|
# entry points not to be used directly
|
||||||
|
|
||||||
|
Xlint:
|
||||||
|
lint $(INCLUDES) $(LINTFLAGS) `./sources $(OBJ)`
|
||||||
|
|
||||||
|
Cfiles: hfiles LLfiles $(GENHFILES) $(GENCFILES)
|
||||||
|
./sources $(OBJ) > Cfiles
|
||||||
|
sh -c 'for i in $(HFILES) ; do echo $$i ; done >> Cfiles'
|
||||||
|
|
||||||
LLfiles: $(LSRC)
|
LLfiles: $(LSRC)
|
||||||
$(LLGEN) $(LLGENOPTIONS) $(LSRC)
|
$(LLGEN) $(LLGENOPTIONS) $(LSRC)
|
||||||
|
@ -47,47 +77,48 @@ hfiles: Parameters make.hfiles
|
||||||
make.hfiles Parameters
|
make.hfiles Parameters
|
||||||
touch hfiles
|
touch hfiles
|
||||||
|
|
||||||
main: $(OBJ) Makefile
|
main: $(OBJ) ../src/Makefile
|
||||||
$(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(LIBDIR)/libeme.a $(LIBDIR)/input.a $(LIBDIR)/assert.a $(LIBDIR)/alloc.a $(LIBDIR)/malloc.o $(LIBDIR)/libprint.a $(LIBDIR)/libstr.a $(LIBDIR)/libsystem.a -o main
|
$(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(LIBDIR)/libemk.a $(LIBDIR)/input.a $(LIBDIR)/assert.a $(LIBDIR)/alloc.a $(LIBDIR)/malloc.o $(LIBDIR)/libprint.a $(LIBDIR)/libstr.a $(LIBDIR)/libsystem.a -o ../src/main
|
||||||
size main
|
size ../src/main
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ) $(GENFILES) LLfiles hfiles
|
|
||||||
|
|
||||||
lint: LLfiles hfiles
|
|
||||||
lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)`
|
|
||||||
|
|
||||||
tokenfile.g: tokenname.c make.tokfile
|
tokenfile.g: tokenname.c make.tokfile
|
||||||
make.tokfile <tokenname.c >tokenfile.g
|
make.tokfile <tokenname.c >tokenfile.g
|
||||||
|
|
||||||
symbol2str.c: tokenname.c make.tokcase
|
symbol2str.c: ../src/tokenname.c ../src/make.tokcase
|
||||||
make.tokcase <tokenname.c >symbol2str.c
|
../src/make.tokcase <../src/tokenname.c >symbol2str.c
|
||||||
|
|
||||||
def.h: def.H make.allocd
|
def.h: ../src/def.H ../src/make.allocd
|
||||||
type.h: type.H make.allocd
|
../src/make.allocd < ../src/def.H > def.h
|
||||||
node.h: node.H make.allocd
|
|
||||||
scope.c: scope.C make.allocd
|
|
||||||
tmpvar.c: tmpvar.C make.allocd
|
|
||||||
casestat.c: casestat.C make.allocd
|
|
||||||
|
|
||||||
char.c: char.tab tab
|
type.h: ../src/type.H ../src/make.allocd
|
||||||
./tab -fchar.tab >char.c
|
../src/make.allocd < ../src/type.H > type.h
|
||||||
|
|
||||||
tab:
|
node.h: ../src/node.H ../src/make.allocd
|
||||||
$(CC) tab.c -o tab
|
../src/make.allocd < ../src/node.H > node.h
|
||||||
|
|
||||||
depend:
|
scope.c: ../src/scope.C ../src/make.allocd
|
||||||
|
../src/make.allocd < ../src/scope.C > scope.c
|
||||||
|
|
||||||
|
tmpvar.c: ../src/tmpvar.C ../src/make.allocd
|
||||||
|
../src/make.allocd < ../src/tmpvar.C > tmpvar.c
|
||||||
|
|
||||||
|
casestat.c: ../src/casestat.C ../src/make.allocd
|
||||||
|
../src/make.allocd < ../src/casestat.C > casestat.c
|
||||||
|
|
||||||
|
char.c: ../src/char.tab ../src/tab
|
||||||
|
../src/tab -fchar.tab >char.c
|
||||||
|
|
||||||
|
../src/tab:
|
||||||
|
$(CC) ../src/tab.c -o ../src/tab
|
||||||
|
|
||||||
|
depend: mkdep
|
||||||
sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
|
sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
|
||||||
echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
|
echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
|
||||||
/user1/erikb/bin/mkdep `sources $(OBJ)` |\
|
./mkdep `./sources $(OBJ)` |\
|
||||||
sed 's/\.c:/\.o:/' >> Makefile.new
|
sed 's/\.c:/\.o:/' >> Makefile.new
|
||||||
mv Makefile Makefile.old
|
mv Makefile Makefile.old
|
||||||
mv Makefile.new Makefile
|
mv Makefile.new Makefile
|
||||||
|
|
||||||
.SUFFIXES: .H .h .C
|
|
||||||
.H.h .C.c :
|
|
||||||
make.allocd < $< > $@
|
|
||||||
|
|
||||||
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
||||||
LLlex.o: LLlex.h Lpars.h class.h const.h debug.h f_info.h idf.h idfsize.h input.h inputtype.h numsize.h strsize.h type.h
|
LLlex.o: LLlex.h Lpars.h class.h const.h debug.h f_info.h idf.h idfsize.h input.h inputtype.h numsize.h strsize.h type.h
|
||||||
LLmessage.o: LLlex.h Lpars.h idf.h
|
LLmessage.o: LLlex.h Lpars.h idf.h
|
||||||
|
@ -116,7 +147,7 @@ code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h
|
||||||
tmpvar.o: debug.h def.h main.h scope.h type.h
|
tmpvar.o: debug.h def.h main.h scope.h type.h
|
||||||
lookup.o: LLlex.h debug.h def.h idf.h node.h scope.h
|
lookup.o: LLlex.h debug.h def.h idf.h node.h scope.h
|
||||||
tokenfile.o: Lpars.h
|
tokenfile.o: Lpars.h
|
||||||
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
|
program.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h main.h node.h scope.h type.h
|
||||||
declar.o: LLlex.h Lpars.h chk_expr.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h
|
declar.o: LLlex.h Lpars.h chk_expr.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h
|
||||||
expression.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h type.h
|
expression.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h type.h
|
||||||
statement.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.h
|
statement.o: LLlex.h Lpars.h def.h idf.h node.h scope.h type.h
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
|
|
||||||
!File: idfsize.h
|
!File: idfsize.h
|
||||||
#define IDFSIZE 30 /* maximum significant length of an identifier */
|
#define IDFSIZE 128 /* maximum significant length of an identifier */
|
||||||
|
|
||||||
|
|
||||||
!File: numsize.h
|
!File: numsize.h
|
||||||
|
|
|
@ -132,6 +132,8 @@ ChkLinkOrName(expp)
|
||||||
{
|
{
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
||||||
|
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 = lookfor(expp, CurrVis, 1);
|
||||||
expp->nd_class = Def;
|
expp->nd_class = Def;
|
||||||
|
@ -183,7 +185,7 @@ df->df_idf->id_text);
|
||||||
assert(expp->nd_class == Def);
|
assert(expp->nd_class == Def);
|
||||||
|
|
||||||
df = expp->nd_def;
|
df = expp->nd_def;
|
||||||
if (df == ill_df) return 0;
|
if (df->df_kind == D_ERROR) return 0;
|
||||||
|
|
||||||
if (df->df_kind & (D_ENUM | D_CONST)) {
|
if (df->df_kind & (D_ENUM | D_CONST)) {
|
||||||
if (df->df_kind == D_ENUM) {
|
if (df->df_kind == D_ENUM) {
|
||||||
|
@ -855,7 +857,7 @@ ChkStandard(expp, left)
|
||||||
case S_MIN:
|
case S_MIN:
|
||||||
if (!(left = getname(&arg, D_ISTYPE))) return 0;
|
if (!(left = getname(&arg, D_ISTYPE))) return 0;
|
||||||
if (!(left->nd_type->tp_fund & (T_DISCRETE))) {
|
if (!(left->nd_type->tp_fund & (T_DISCRETE))) {
|
||||||
node_error(left, "illegal type in MIN or MAX");
|
node_error(left, "illegal type in %s", std == S_MAX ? "MAX" : "MIN");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
expp->nd_type = left->nd_type;
|
expp->nd_type = left->nd_type;
|
||||||
|
@ -961,7 +963,7 @@ ChkStandard(expp, left)
|
||||||
expp->nd_type = 0;
|
expp->nd_type = 0;
|
||||||
if (! (left = getvariable(&arg))) return 0;
|
if (! (left = getvariable(&arg))) return 0;
|
||||||
if (! (left->nd_type->tp_fund & T_DISCRETE)) {
|
if (! (left->nd_type->tp_fund & T_DISCRETE)) {
|
||||||
node_error(left, "illegal type in argument of INC or DEC");
|
node_error(left,"illegal type in argument of %s",std == S_INC ? "INC" : "DEC");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (arg->nd_right) {
|
if (arg->nd_right) {
|
||||||
|
@ -982,7 +984,7 @@ node_error(left, "illegal type in argument of INC or DEC");
|
||||||
if (!(left = getvariable(&arg))) return 0;
|
if (!(left = getvariable(&arg))) return 0;
|
||||||
tp = left->nd_type;
|
tp = left->nd_type;
|
||||||
if (tp->tp_fund != T_SET) {
|
if (tp->tp_fund != T_SET) {
|
||||||
node_error(arg, "EXCL and INCL expect a SET parameter");
|
node_error(arg, "%s expects a SET parameter", std == S_EXCL ? "EXCL" : "INCL");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(left = getarg(&arg, T_DISCRETE, 0))) return 0;
|
if (!(left = getarg(&arg, T_DISCRETE, 0))) return 0;
|
||||||
|
|
|
@ -201,7 +201,6 @@ CodeCoercion(t1, t2)
|
||||||
if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER;
|
if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER;
|
||||||
switch(fund1) {
|
switch(fund1) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_INTORCARD:
|
|
||||||
switch(fund2) {
|
switch(fund2) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
if (t2->tp_size != t1->tp_size) {
|
if (t2->tp_size != t1->tp_size) {
|
||||||
|
@ -232,11 +231,13 @@ CodeCoercion(t1, t2)
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
switch(fund2) {
|
switch(fund2) {
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_INTORCARD:
|
||||||
if (t2->tp_size > word_size) {
|
if (t2->tp_size > word_size) {
|
||||||
C_loc(word_size);
|
C_loc(word_size);
|
||||||
C_loc(t2->tp_size);
|
C_loc(t2->tp_size);
|
||||||
|
@ -313,16 +314,25 @@ CodeCall(nd)
|
||||||
CodeParameters(ParamList(left->nd_type), nd->nd_right);
|
CodeParameters(ParamList(left->nd_type), nd->nd_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) {
|
switch(left->nd_class) {
|
||||||
if (left->nd_def->df_scope->sc_level > 0) {
|
case Def: {
|
||||||
C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level);
|
register struct def *df = left->nd_def;
|
||||||
|
|
||||||
|
if (df->df_kind == D_PROCEDURE) {
|
||||||
|
arith level = df->df_scope->sc_level;
|
||||||
|
|
||||||
|
if (level > 0) {
|
||||||
|
C_lxl((arith) proclevel - level);
|
||||||
}
|
}
|
||||||
C_cal(NameOfProc(left->nd_def));
|
C_cal(NameOfProc(df));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) {
|
else if (df->df_kind == D_PROCHEAD) {
|
||||||
C_cal(left->nd_def->for_name);
|
C_cal(df->for_name);
|
||||||
}
|
break;
|
||||||
else {
|
}}
|
||||||
|
/* Fall through */
|
||||||
|
default:
|
||||||
CodePExpr(left);
|
CodePExpr(left);
|
||||||
C_cai();
|
C_cai();
|
||||||
}
|
}
|
||||||
|
@ -342,6 +352,7 @@ CodeParameters(param, arg)
|
||||||
{
|
{
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
register struct node *left;
|
register struct node *left;
|
||||||
|
register struct type *left_type;
|
||||||
|
|
||||||
assert(param != 0 && arg != 0);
|
assert(param != 0 && arg != 0);
|
||||||
|
|
||||||
|
@ -351,25 +362,31 @@ CodeParameters(param, arg)
|
||||||
|
|
||||||
tp = TypeOfParam(param);
|
tp = TypeOfParam(param);
|
||||||
left = arg->nd_left;
|
left = arg->nd_left;
|
||||||
|
left_type = left->nd_type;
|
||||||
if (IsConformantArray(tp)) {
|
if (IsConformantArray(tp)) {
|
||||||
C_loc(tp->arr_elsize);
|
C_loc(tp->arr_elsize);
|
||||||
if (IsConformantArray(left->nd_type)) {
|
if (IsConformantArray(left_type)) {
|
||||||
DoHIGH(left);
|
DoHIGH(left);
|
||||||
if (tp->arr_elem->tp_size != left->nd_type->arr_elem->tp_size) {
|
if (tp->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
|
||||||
*/
|
*/
|
||||||
/* ??? */
|
assert(tp->arr_elem == word_type);
|
||||||
|
C_loc(left_type->arr_elem->tp_size);
|
||||||
|
C_cal("_wa");
|
||||||
|
C_asp(dword_size);
|
||||||
|
C_lfr(word_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (left->nd_symb == STRING) {
|
else if (left->nd_symb == STRING) {
|
||||||
C_loc(left->nd_SLE);
|
C_loc(left->nd_SLE);
|
||||||
}
|
}
|
||||||
else if (tp->arr_elem == word_type) {
|
else if (tp->arr_elem == word_type) {
|
||||||
C_loc(left->nd_type->tp_size / word_size - 1);
|
C_loc((left_type->tp_size+word_size-1) / word_size - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tp = IndexType(left->nd_type);
|
tp = IndexType(left_type);
|
||||||
if (tp->tp_fund == T_SUBRANGE) {
|
if (tp->tp_fund == T_SUBRANGE) {
|
||||||
C_loc(tp->sub_ub - tp->sub_lb);
|
C_loc(tp->sub_ub - tp->sub_lb);
|
||||||
}
|
}
|
||||||
|
@ -385,11 +402,11 @@ CodeParameters(param, arg)
|
||||||
CodeDAddress(left);
|
CodeDAddress(left);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (left->nd_type->tp_fund == T_STRING) {
|
if (left_type->tp_fund == T_STRING) {
|
||||||
CodePadString(left, tp->tp_size);
|
CodePadString(left, tp->tp_size);
|
||||||
}
|
}
|
||||||
else CodePExpr(left);
|
else CodePExpr(left);
|
||||||
CheckAssign(left->nd_type, tp);
|
CheckAssign(left_type, tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +439,7 @@ CodeStd(nd)
|
||||||
}
|
}
|
||||||
else C_cal("_absd");
|
else C_cal("_absd");
|
||||||
}
|
}
|
||||||
|
C_asp(tp->tp_size);
|
||||||
C_lfr(tp->tp_size);
|
C_lfr(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -447,6 +465,7 @@ CodeStd(nd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ODD:
|
case S_ODD:
|
||||||
|
CodePExpr(left);
|
||||||
if (tp->tp_size == word_size) {
|
if (tp->tp_size == word_size) {
|
||||||
C_loc((arith) 1);
|
C_loc((arith) 1);
|
||||||
C_and(word_size);
|
C_and(word_size);
|
||||||
|
@ -584,45 +603,39 @@ CheckAssign(tpl, tpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Operands(leftop, rightop)
|
Operands(leftop, rightop, tp)
|
||||||
register struct node *leftop, *rightop;
|
register struct node *leftop, *rightop;
|
||||||
|
struct type *tp;
|
||||||
{
|
{
|
||||||
|
|
||||||
CodePExpr(leftop);
|
CodePExpr(leftop);
|
||||||
|
CodeCoercion(leftop->nd_type, tp);
|
||||||
if (rightop->nd_type->tp_fund == T_POINTER &&
|
|
||||||
leftop->nd_type->tp_size != pointer_size) {
|
|
||||||
CodeCoercion(leftop->nd_type, rightop->nd_type);
|
|
||||||
leftop->nd_type = rightop->nd_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodePExpr(rightop);
|
CodePExpr(rightop);
|
||||||
|
CodeCoercion(rightop->nd_type, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOper(expr, true_label, false_label)
|
CodeOper(expr, true_label, false_label)
|
||||||
struct node *expr; /* the expression tree itself */
|
register struct node *expr; /* the expression tree itself */
|
||||||
label true_label;
|
label true_label;
|
||||||
label false_label; /* labels to jump to in logical expr's */
|
label false_label; /* labels to jump to in logical expr's */
|
||||||
{
|
{
|
||||||
register int oper = expr->nd_symb;
|
|
||||||
register struct node *leftop = expr->nd_left;
|
register struct node *leftop = expr->nd_left;
|
||||||
register struct node *rightop = expr->nd_right;
|
register struct node *rightop = expr->nd_right;
|
||||||
register struct type *tp = expr->nd_type;
|
register struct type *tp = expr->nd_type;
|
||||||
|
|
||||||
switch (oper) {
|
switch (expr->nd_symb) {
|
||||||
case '+':
|
case '+':
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_adi(tp->tp_size);
|
C_adi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
|
||||||
C_ads(rightop->nd_type->tp_size);
|
|
||||||
break;
|
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
C_adf(tp->tp_size);
|
C_adf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
|
case T_POINTER:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_adu(tp->tp_size);
|
C_adu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_SET:
|
case T_SET:
|
||||||
|
@ -633,24 +646,17 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_sbi(tp->tp_size);
|
C_sbi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
|
||||||
if (rightop->nd_type->tp_fund == T_POINTER) {
|
|
||||||
C_sbs(pointer_size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
C_ngi(rightop->nd_type->tp_size);
|
|
||||||
C_ads(rightop->nd_type->tp_size);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
C_sbf(tp->tp_size);
|
C_sbf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
|
case T_POINTER:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_sbu(tp->tp_size);
|
C_sbu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_SET:
|
case T_SET:
|
||||||
|
@ -662,15 +668,14 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_mli(tp->tp_size);
|
C_mli(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
CodeCoercion(rightop->nd_type, tp);
|
|
||||||
/* Fall through */
|
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_mlu(tp->tp_size);
|
C_mlu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
|
@ -684,7 +689,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
C_dvf(tp->tp_size);
|
C_dvf(tp->tp_size);
|
||||||
|
@ -697,15 +702,14 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV:
|
case DIV:
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch(tp->tp_fund) {
|
switch(tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_dvi(tp->tp_size);
|
C_dvi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
CodeCoercion(rightop->nd_type, tp);
|
|
||||||
/* Fall through */
|
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_dvu(tp->tp_size);
|
C_dvu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -713,15 +717,14 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MOD:
|
case MOD:
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop, tp);
|
||||||
switch(tp->tp_fund) {
|
switch(tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_rmi(tp->tp_size);
|
C_rmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
CodeCoercion(rightop->nd_type, tp);
|
|
||||||
/* Fall through */
|
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_rmu(tp->tp_size);
|
C_rmu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -734,18 +737,17 @@ CodeOper(expr, true_label, false_label)
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
case '=':
|
case '=':
|
||||||
case '#':
|
case '#':
|
||||||
Operands(leftop, rightop);
|
tp = BaseType(leftop->nd_type);
|
||||||
CodeCoercion(rightop->nd_type, leftop->nd_type);
|
if (tp == intorcard_type) tp = BaseType(rightop->nd_type);
|
||||||
tp = BaseType(leftop->nd_type); /* Not the result type! */
|
Operands(leftop, rightop, tp);
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_cmi(tp->tp_size);
|
C_cmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_HIDDEN:
|
case T_HIDDEN:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
C_cmp();
|
|
||||||
break;
|
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
|
case T_INTORCARD:
|
||||||
C_cmu(tp->tp_size);
|
C_cmu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
|
@ -756,19 +758,18 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_cmf(tp->tp_size);
|
C_cmf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_SET:
|
case T_SET:
|
||||||
if (oper == GREATEREQUAL) {
|
if (expr->nd_symb == GREATEREQUAL) {
|
||||||
/* A >= B is the same as A equals A + B
|
/* A >= B is the same as A equals A + B
|
||||||
*/
|
*/
|
||||||
C_dup(2*tp->tp_size);
|
C_dup(2*tp->tp_size);
|
||||||
C_asp(tp->tp_size);
|
C_asp(tp->tp_size);
|
||||||
C_zer(tp->tp_size);
|
C_ior(tp->tp_size);
|
||||||
}
|
}
|
||||||
else if (oper == LESSEQUAL) {
|
else if (expr->nd_symb == LESSEQUAL) {
|
||||||
/* A <= B is the same as A - B = {}
|
/* A <= B is the same as A - B = {}
|
||||||
*/
|
*/
|
||||||
C_com(tp->tp_size);
|
C_com(tp->tp_size);
|
||||||
C_and(tp->tp_size);
|
C_and(tp->tp_size);
|
||||||
C_ior(tp->tp_size);
|
|
||||||
C_zer(tp->tp_size);
|
C_zer(tp->tp_size);
|
||||||
}
|
}
|
||||||
C_cms(tp->tp_size);
|
C_cms(tp->tp_size);
|
||||||
|
@ -777,11 +778,11 @@ CodeOper(expr, true_label, false_label)
|
||||||
crash("bad type COMPARE");
|
crash("bad type COMPARE");
|
||||||
}
|
}
|
||||||
if (true_label != 0) {
|
if (true_label != 0) {
|
||||||
compare(oper, true_label);
|
compare(expr->nd_symb, true_label);
|
||||||
C_bra(false_label);
|
C_bra(false_label);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
truthvalue(oper);
|
truthvalue(expr->nd_symb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IN:
|
case IN:
|
||||||
|
@ -789,7 +790,8 @@ CodeOper(expr, true_label, false_label)
|
||||||
INN instruction expects the bit number on top of the
|
INN instruction expects the bit number on top of the
|
||||||
stack
|
stack
|
||||||
*/
|
*/
|
||||||
Operands(rightop, leftop);
|
CodePExpr(rightop);
|
||||||
|
CodePExpr(leftop);
|
||||||
CodeCoercion(leftop->nd_type, word_type);
|
CodeCoercion(leftop->nd_type, word_type);
|
||||||
C_inn(rightop->nd_type->tp_size);
|
C_inn(rightop->nd_type->tp_size);
|
||||||
if (true_label != 0) {
|
if (true_label != 0) {
|
||||||
|
@ -798,19 +800,26 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
case '&':
|
case '&': {
|
||||||
if (true_label == 0) {
|
label l_true, l_false, l_maybe = ++text_label, l_end;
|
||||||
label l_true = ++text_label;
|
|
||||||
label l_false = ++text_label;
|
|
||||||
label l_maybe = ++text_label;
|
|
||||||
label l_end = ++text_label;
|
|
||||||
struct desig Des;
|
struct desig Des;
|
||||||
|
|
||||||
|
if (true_label == 0) {
|
||||||
|
l_true = ++text_label;
|
||||||
|
l_false = ++text_label;
|
||||||
|
l_end = ++text_label;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l_true = true_label;
|
||||||
|
l_false = false_label;
|
||||||
|
}
|
||||||
|
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(leftop, &Des, l_maybe, l_false);
|
CodeExpr(leftop, &Des, l_maybe, l_false);
|
||||||
C_df_ilb(l_maybe);
|
C_df_ilb(l_maybe);
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(rightop, &Des, l_true, l_false);
|
CodeExpr(rightop, &Des, l_true, l_false);
|
||||||
|
if (true_label == 0) {
|
||||||
C_df_ilb(l_true);
|
C_df_ilb(l_true);
|
||||||
C_loc((arith)1);
|
C_loc((arith)1);
|
||||||
C_bra(l_end);
|
C_bra(l_end);
|
||||||
|
@ -818,30 +827,27 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_loc((arith)0);
|
C_loc((arith)0);
|
||||||
C_df_ilb(l_end);
|
C_df_ilb(l_end);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
label l_maybe = ++text_label;
|
|
||||||
struct desig Des;
|
|
||||||
|
|
||||||
Des = InitDesig;
|
|
||||||
CodeExpr(leftop, &Des, l_maybe, false_label);
|
|
||||||
Des = InitDesig;
|
|
||||||
C_df_ilb(l_maybe);
|
|
||||||
CodeExpr(rightop, &Des, true_label, false_label);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OR:
|
}
|
||||||
if (true_label == 0) {
|
case OR: {
|
||||||
label l_true = ++text_label;
|
label l_true, l_false, l_maybe = ++text_label, l_end;
|
||||||
label l_false = ++text_label;
|
|
||||||
label l_maybe = ++text_label;
|
|
||||||
label l_end = ++text_label;
|
|
||||||
struct desig Des;
|
struct desig Des;
|
||||||
|
|
||||||
|
if (true_label == 0) {
|
||||||
|
l_true = ++text_label;
|
||||||
|
l_false = ++text_label;
|
||||||
|
l_end = ++text_label;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l_true = true_label;
|
||||||
|
l_false = false_label;
|
||||||
|
}
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(leftop, &Des, l_true, l_maybe);
|
CodeExpr(leftop, &Des, l_true, l_maybe);
|
||||||
C_df_ilb(l_maybe);
|
C_df_ilb(l_maybe);
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(rightop, &Des, l_true, l_false);
|
CodeExpr(rightop, &Des, l_true, l_false);
|
||||||
|
if (true_label == 0) {
|
||||||
C_df_ilb(l_false);
|
C_df_ilb(l_false);
|
||||||
C_loc((arith)0);
|
C_loc((arith)0);
|
||||||
C_bra(l_end);
|
C_bra(l_end);
|
||||||
|
@ -849,19 +855,10 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_loc((arith)1);
|
C_loc((arith)1);
|
||||||
C_df_ilb(l_end);
|
C_df_ilb(l_end);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
label l_maybe = ++text_label;
|
|
||||||
struct desig Des;
|
|
||||||
|
|
||||||
Des = InitDesig;
|
|
||||||
CodeExpr(leftop, &Des, true_label, l_maybe);
|
|
||||||
C_df_ilb(l_maybe);
|
|
||||||
Des = InitDesig;
|
|
||||||
CodeExpr(rightop, &Des, true_label, false_label);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
crash("(CodeOper) Bad operator %s\n", symbol2str(oper));
|
crash("(CodeOper) Bad operator %s\n",symbol2str(expr->nd_symb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,6 +933,7 @@ CodeUoper(nd)
|
||||||
case '-':
|
case '-':
|
||||||
switch(tp->tp_fund) {
|
switch(tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
|
case T_INTORCARD:
|
||||||
C_ngi(tp->tp_size);
|
C_ngi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
|
@ -977,7 +975,7 @@ CodeEl(nd, tp)
|
||||||
C_loc(eltype->sub_ub);
|
C_loc(eltype->sub_ub);
|
||||||
}
|
}
|
||||||
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, word_type);
|
||||||
C_cal("_LtoUset"); /* library routine to fill set */
|
C_cal("_LtoUset"); /* library routine to fill set */
|
||||||
C_asp(4 * word_size);
|
C_asp(4 * word_size);
|
||||||
}
|
}
|
||||||
|
@ -1032,13 +1030,20 @@ CodeDStore(nd)
|
||||||
DoHIGH(nd)
|
DoHIGH(nd)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
{
|
{
|
||||||
|
/* Get the high index of a conformant array, indicated by "nd".
|
||||||
|
The high index is the second field in the descriptor of
|
||||||
|
the array, so it is easily found.
|
||||||
|
*/
|
||||||
register struct def *df = nd->nd_def;
|
register struct def *df = nd->nd_def;
|
||||||
register arith highoff;
|
register arith highoff;
|
||||||
|
|
||||||
assert(nd->nd_class == Def);
|
assert(nd->nd_class == Def);
|
||||||
assert(df->df_kind == D_VARIABLE);
|
assert(df->df_kind == D_VARIABLE);
|
||||||
|
assert(IsConformantArray(df->df_type));
|
||||||
|
|
||||||
highoff = df->var_off + pointer_size + word_size;
|
highoff = df->var_off /* base address and descriptor */
|
||||||
|
+ pointer_size /* skip base address */
|
||||||
|
+ word_size; /* skip first field of descriptor */
|
||||||
if (df->df_scope->sc_level < proclevel) {
|
if (df->df_scope->sc_level < proclevel) {
|
||||||
C_lxa((arith) (proclevel - df->df_scope->sc_level));
|
C_lxa((arith) (proclevel - df->df_scope->sc_level));
|
||||||
C_lof(highoff);
|
C_lof(highoff);
|
||||||
|
|
|
@ -248,6 +248,7 @@ cstset(expp)
|
||||||
assert(expp->nd_left->nd_class == Value);
|
assert(expp->nd_left->nd_class == Value);
|
||||||
|
|
||||||
i = expp->nd_left->nd_INT;
|
i = expp->nd_left->nd_INT;
|
||||||
|
expp->nd_class = Value;
|
||||||
expp->nd_INT = (i >= 0 && set2 != 0 &&
|
expp->nd_INT = (i >= 0 && set2 != 0 &&
|
||||||
i < setsize * wrd_bits &&
|
i < setsize * wrd_bits &&
|
||||||
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
||||||
|
|
|
@ -108,9 +108,7 @@ declaration:
|
||||||
FormalParameters(struct paramlist **pr;
|
FormalParameters(struct paramlist **pr;
|
||||||
struct type **ptp;
|
struct type **ptp;
|
||||||
arith *parmaddr;)
|
arith *parmaddr;)
|
||||||
{
|
:
|
||||||
struct def *df;
|
|
||||||
} :
|
|
||||||
'('
|
'('
|
||||||
[
|
[
|
||||||
FPSection(pr, parmaddr)
|
FPSection(pr, parmaddr)
|
||||||
|
@ -128,74 +126,38 @@ FPSection(struct paramlist **ppr; arith *parmaddr;)
|
||||||
struct node *FPList;
|
struct node *FPList;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
int VARp;
|
int VARp;
|
||||||
struct paramlist *p = 0;
|
|
||||||
} :
|
} :
|
||||||
var(&VARp) IdentList(&FPList) ':' FormalType(&p, 0)
|
var(&VARp) IdentList(&FPList) ':' FormalType(&tp)
|
||||||
{ EnterParamList(ppr, FPList, p->par_def->df_type,
|
{ EnterParamList(ppr, FPList, tp, VARp, parmaddr); }
|
||||||
VARp, parmaddr);
|
|
||||||
free_def(p->par_def);
|
|
||||||
free_paramlist(p);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
FormalType(struct paramlist **ppr; int VARp;)
|
FormalType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
register struct def *df;
|
|
||||||
int ARRAYflag;
|
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
struct type *tp1;
|
|
||||||
register struct paramlist *p = new_paramlist();
|
|
||||||
extern arith ArrayElSize();
|
extern arith ArrayElSize();
|
||||||
} :
|
} :
|
||||||
[ ARRAY OF { ARRAYflag = 1; }
|
ARRAY OF qualtype(ptp)
|
||||||
| { ARRAYflag = 0; }
|
{ tp = construct_type(T_ARRAY, NULLTYPE);
|
||||||
]
|
tp->arr_elem = *ptp; *ptp = tp;
|
||||||
qualtype(&tp1)
|
tp->arr_elsize = ArrayElSize(tp->arr_elem);
|
||||||
{ if (ARRAYflag) {
|
|
||||||
tp = construct_type(T_ARRAY, NULLTYPE);
|
|
||||||
tp->arr_elem = tp1;
|
|
||||||
tp->arr_elsize = ArrayElSize(tp1);
|
|
||||||
tp->tp_align = lcm(word_align, pointer_align);
|
tp->tp_align = lcm(word_align, pointer_align);
|
||||||
}
|
}
|
||||||
else tp = tp1;
|
|
|
||||||
p->next = *ppr;
|
qualtype(ptp)
|
||||||
*ppr = p;
|
|
||||||
p->par_def = df = new_def();
|
|
||||||
df->df_type = tp;
|
|
||||||
df->df_flags = VARp;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
TypeDeclaration
|
TypeDeclaration
|
||||||
{
|
{
|
||||||
register struct def *df;
|
struct def *df;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
}:
|
}:
|
||||||
IDENT { df = define(dot.TOK_IDF,CurrentScope,D_TYPE); }
|
IDENT { df = define(dot.TOK_IDF,CurrentScope,D_TYPE); }
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
|
{ DeclareType(df, tp); }
|
||||||
if (tp->tp_fund != T_POINTER) {
|
|
||||||
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
|
||||||
}
|
|
||||||
/* Careful now ... we might have declarations
|
|
||||||
referring to the hidden type.
|
|
||||||
*/
|
|
||||||
*(df->df_type) = *tp;
|
|
||||||
if (! tp->next) {
|
|
||||||
/* It also contains a forward
|
|
||||||
reference, so update the forward-
|
|
||||||
list
|
|
||||||
*/
|
|
||||||
ChForward(tp, df->df_type);
|
|
||||||
}
|
|
||||||
free_type(tp);
|
|
||||||
}
|
|
||||||
else df->df_type = tp;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
type(struct type **ptp;):
|
type(struct type **ptp;):
|
||||||
SimpleType(ptp)
|
%default SimpleType(ptp)
|
||||||
|
|
|
|
||||||
ArrayType(ptp)
|
ArrayType(ptp)
|
||||||
|
|
|
|
||||||
|
@ -247,7 +209,7 @@ IdentList(struct node **p;)
|
||||||
register struct node *q;
|
register struct node *q;
|
||||||
} :
|
} :
|
||||||
IDENT { *p = q = MkLeaf(Value, &dot); }
|
IDENT { *p = q = MkLeaf(Value, &dot); }
|
||||||
[
|
[ %persistent
|
||||||
',' IDENT
|
',' IDENT
|
||||||
{ q->next = MkLeaf(Value, &dot);
|
{ q->next = MkLeaf(Value, &dot);
|
||||||
q = q->next;
|
q = q->next;
|
||||||
|
@ -460,11 +422,12 @@ PointerType(struct type **ptp;)
|
||||||
*/
|
*/
|
||||||
qualtype(&((*ptp)->next))
|
qualtype(&((*ptp)->next))
|
||||||
| %if ( nd = new_node(), nd->nd_token = dot,
|
| %if ( nd = new_node(), nd->nd_token = dot,
|
||||||
df = lookfor(nd, CurrVis, 0), free_node(nd),
|
df = lookfor(nd, CurrVis, 0),
|
||||||
df->df_kind == D_MODULE)
|
df->df_kind == D_MODULE)
|
||||||
type(&((*ptp)->next))
|
type(&((*ptp)->next))
|
||||||
|
{ free_node(nd); }
|
||||||
|
|
|
|
||||||
IDENT { Forward(&dot, (*ptp)); }
|
IDENT { Forward(nd, (*ptp)); }
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -486,24 +449,28 @@ ProcedureType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct paramlist *pr = 0;
|
struct paramlist *pr = 0;
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
|
arith nbytes = 0;
|
||||||
} :
|
} :
|
||||||
{ *ptp = 0; }
|
{ *ptp = 0; }
|
||||||
PROCEDURE FormalTypeList(&pr, ptp)?
|
PROCEDURE FormalTypeList(&pr, ptp, &nbytes)?
|
||||||
{ *ptp = tp = construct_type(T_PROCEDURE, *ptp);
|
{ *ptp = tp = construct_type(T_PROCEDURE, *ptp);
|
||||||
tp->prc_params = pr;
|
tp->prc_params = pr;
|
||||||
|
tp->prc_nbpar = nbytes;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
FormalTypeList(struct paramlist **ppr; struct type **ptp;)
|
FormalTypeList(struct paramlist **ppr; struct type **ptp; arith *parmaddr;)
|
||||||
{
|
{
|
||||||
struct def *df;
|
|
||||||
int VARp;
|
int VARp;
|
||||||
|
struct type *tp;
|
||||||
} :
|
} :
|
||||||
'(' { *ppr = 0; }
|
'(' { *ppr = 0; }
|
||||||
[
|
[
|
||||||
var(&VARp) FormalType(ppr, VARp)
|
var(&VARp) FormalType(&tp)
|
||||||
|
{ EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); }
|
||||||
[
|
[
|
||||||
',' var(&VARp) FormalType(ppr, VARp)
|
',' var(&VARp) FormalType(&tp)
|
||||||
|
{ EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); }
|
||||||
]*
|
]*
|
||||||
]?
|
]?
|
||||||
')'
|
')'
|
||||||
|
@ -535,7 +502,7 @@ VariableDeclaration
|
||||||
} :
|
} :
|
||||||
IdentAddr(&VarList)
|
IdentAddr(&VarList)
|
||||||
{ nd = VarList; }
|
{ nd = VarList; }
|
||||||
[
|
[ %persistent
|
||||||
',' IdentAddr(&(nd->nd_right))
|
',' IdentAddr(&(nd->nd_right))
|
||||||
{ nd = nd->nd_right; }
|
{ nd = nd->nd_right; }
|
||||||
]*
|
]*
|
||||||
|
|
|
@ -290,7 +290,6 @@ DefineLocalModule(id)
|
||||||
a name to be used for code generation.
|
a name to be used for code generation.
|
||||||
*/
|
*/
|
||||||
register struct def *df = define(id, CurrentScope, D_MODULE);
|
register struct def *df = define(id, CurrentScope, D_MODULE);
|
||||||
register struct type *tp;
|
|
||||||
register struct scope *sc;
|
register struct scope *sc;
|
||||||
static int modulecount = 0;
|
static int modulecount = 0;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
@ -316,8 +315,8 @@ DefineLocalModule(id)
|
||||||
|
|
||||||
/* Create a type for it
|
/* Create a type for it
|
||||||
*/
|
*/
|
||||||
df->df_type = tp = standard_type(T_RECORD, 0, (arith) 0);
|
df->df_type = standard_type(T_RECORD, 0, (arith) 0);
|
||||||
tp->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.
|
||||||
|
|
|
@ -74,7 +74,7 @@ GetDefinitionModule(id)
|
||||||
}
|
}
|
||||||
df = lookup(id, GlobalScope);
|
df = lookup(id, GlobalScope);
|
||||||
}
|
}
|
||||||
assert(df != 0 && df->df_kind == D_MODULE);
|
assert(df && df->df_kind == D_MODULE);
|
||||||
level--;
|
level--;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,8 +168,12 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
register struct paramlist *pr;
|
register struct paramlist *pr;
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
register struct node *idlist = Idlist;
|
register struct node *idlist = Idlist;
|
||||||
|
struct node *dummy = 0;
|
||||||
static struct paramlist *last;
|
static struct paramlist *last;
|
||||||
|
|
||||||
|
if (! idlist) {
|
||||||
|
dummy = Idlist = idlist = MkLeaf(Name, &dot);
|
||||||
|
}
|
||||||
for ( ; idlist; idlist = idlist->next) {
|
for ( ; idlist; idlist = idlist->next) {
|
||||||
pr = new_paramlist();
|
pr = new_paramlist();
|
||||||
pr->next = 0;
|
pr->next = 0;
|
||||||
|
@ -178,11 +182,17 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
}
|
}
|
||||||
else last->next = pr;
|
else last->next = pr;
|
||||||
last = pr;
|
last = pr;
|
||||||
|
if (idlist != dummy) {
|
||||||
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
|
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
|
||||||
|
df->var_off = *off;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
df = new_def();
|
||||||
|
}
|
||||||
pr->par_def = df;
|
pr->par_def = df;
|
||||||
df->df_type = type;
|
df->df_type = type;
|
||||||
df->var_off = *off;
|
|
||||||
df->df_flags = VARp;
|
df->df_flags = VARp;
|
||||||
|
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
@ -347,49 +357,38 @@ node_error(idlist, "opaque type \"%s\" is not a pointer type", df->df_idf->id_te
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterFromImportList(Idlist, Fromid, local)
|
EnterFromImportList(Idlist, FromDef)
|
||||||
struct node *Idlist;
|
struct node *Idlist;
|
||||||
register struct node *Fromid;
|
register struct def *FromDef;
|
||||||
{
|
{
|
||||||
/* Import the list Idlist from the module indicated by Fromid.
|
/* Import the list Idlist from the module indicated by Fromdef.
|
||||||
An exception must be made for imports of the Compilation Unit,
|
|
||||||
because in this case the definition module for Fromid must
|
|
||||||
be read.
|
|
||||||
This case is indicated by the value 0 of the flag "local".
|
|
||||||
*/
|
*/
|
||||||
register struct node *idlist = Idlist;
|
register struct node *idlist = Idlist;
|
||||||
|
register struct scopelist *vis;
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct scopelist *vis = enclosing(CurrVis);
|
|
||||||
int forwflag = 0;
|
int forwflag = 0;
|
||||||
extern struct def *GetDefinitionModule();
|
|
||||||
|
|
||||||
if (local) {
|
switch(FromDef->df_kind) {
|
||||||
df = lookfor(Fromid, vis, 0);
|
|
||||||
switch(df->df_kind) {
|
|
||||||
case D_ERROR:
|
case D_ERROR:
|
||||||
/* The module from which the import was done
|
/* The module from which the import was done
|
||||||
is not yet declared. I'm not sure if I must
|
is not yet declared. I'm not sure if I must
|
||||||
accept this, but for the time being I will.
|
accept this, but for the time being I will.
|
||||||
???
|
???
|
||||||
*/
|
*/
|
||||||
vis = ForwModule(df, Fromid);
|
vis = ForwModule(FromDef, FromDef->df_idf);
|
||||||
forwflag = 1;
|
forwflag = 1;
|
||||||
break;
|
break;
|
||||||
case D_FORWMODULE:
|
case D_FORWMODULE:
|
||||||
vis = df->for_vis;
|
vis = FromDef->for_vis;
|
||||||
break;
|
break;
|
||||||
case D_MODULE:
|
case D_MODULE:
|
||||||
vis = df->mod_vis;
|
vis = FromDef->mod_vis;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
node_error(Fromid, "identifier \"%s\" does not represent a module",
|
error("identifier \"%s\" does not represent a module",
|
||||||
Fromid->nd_IDF->id_text);
|
FromDef->df_idf->id_text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else vis = GetDefinitionModule(Fromid->nd_IDF)->mod_vis;
|
|
||||||
|
|
||||||
FreeNode(Fromid);
|
|
||||||
|
|
||||||
for (; idlist; idlist = idlist->next) {
|
for (; idlist; idlist = idlist->next) {
|
||||||
if (forwflag) {
|
if (forwflag) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "f_info.h"
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -91,12 +92,22 @@ export(int *QUALflag; struct node **ExportList;)
|
||||||
import(int local;)
|
import(int local;)
|
||||||
{
|
{
|
||||||
struct node *ImportList;
|
struct node *ImportList;
|
||||||
register struct node *id;
|
register struct def *df;
|
||||||
|
int fromid;
|
||||||
|
extern struct def *GetDefinitionModule();
|
||||||
} :
|
} :
|
||||||
[ FROM
|
[ FROM
|
||||||
IDENT { id = MkLeaf(Value, &dot); }
|
IDENT { fromid = 1;
|
||||||
|
if (local) {
|
||||||
|
struct node *nd = MkLeaf(Name, &dot);
|
||||||
|
|
||||||
|
df = lookfor(nd,enclosing(CurrVis),0);
|
||||||
|
FreeNode(nd);
|
||||||
|
}
|
||||||
|
else df = GetDefinitionModule(dot.TOK_IDF);
|
||||||
|
}
|
||||||
|
|
|
|
||||||
{ id = 0; }
|
{ fromid = 0; }
|
||||||
]
|
]
|
||||||
IMPORT IdentList(&ImportList) ';'
|
IMPORT IdentList(&ImportList) ';'
|
||||||
/*
|
/*
|
||||||
|
@ -105,7 +116,7 @@ import(int local;)
|
||||||
If the FROM clause is present, the identifier in it is a module
|
If the FROM clause is present, the identifier in it is a module
|
||||||
name, otherwise the names in the import list are module names.
|
name, otherwise the names in the import list are module names.
|
||||||
*/
|
*/
|
||||||
{ if (id) EnterFromImportList(ImportList, id, local);
|
{ if (fromid) EnterFromImportList(ImportList, df);
|
||||||
else EnterImportList(ImportList, local);
|
else EnterImportList(ImportList, local);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -67,14 +67,14 @@ InitScope()
|
||||||
|
|
||||||
struct forwards {
|
struct forwards {
|
||||||
struct forwards *next;
|
struct forwards *next;
|
||||||
struct node fo_tok;
|
struct node *fo_tok;
|
||||||
struct type *fo_ptyp;
|
struct type *fo_ptyp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* STATICALLOCDEF "forwards" */
|
/* STATICALLOCDEF "forwards" */
|
||||||
|
|
||||||
Forward(tk, ptp)
|
Forward(tk, ptp)
|
||||||
struct token *tk;
|
struct node *tk;
|
||||||
struct type *ptp;
|
struct type *ptp;
|
||||||
{
|
{
|
||||||
/* Enter a forward reference into a list belonging to the
|
/* Enter a forward reference into a list belonging to the
|
||||||
|
@ -84,7 +84,7 @@ Forward(tk, ptp)
|
||||||
*/
|
*/
|
||||||
register struct forwards *f = new_forwards();
|
register struct forwards *f = new_forwards();
|
||||||
|
|
||||||
f->fo_tok.nd_token = *tk;
|
f->fo_tok = tk;
|
||||||
f->fo_ptyp = ptp;
|
f->fo_ptyp = ptp;
|
||||||
f->next = CurrentScope->sc_forw;
|
f->next = CurrentScope->sc_forw;
|
||||||
CurrentScope->sc_forw = f;
|
CurrentScope->sc_forw = f;
|
||||||
|
@ -168,23 +168,24 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared",
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
rem_forwards(fo)
|
rem_forwards(fo)
|
||||||
struct forwards *fo;
|
register struct forwards *fo;
|
||||||
{
|
{
|
||||||
/* When closing a scope, all forward references must be resolved
|
/* When closing a scope, all forward references must be resolved
|
||||||
*/
|
*/
|
||||||
register struct forwards *f;
|
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
||||||
while (f = fo) {
|
if (fo->next) rem_forwards(fo->next);
|
||||||
df = lookfor(&(f->fo_tok), CurrVis, 1);
|
df = lookfor(fo->fo_tok, CurrVis, 0);
|
||||||
if (!(df->df_kind & (D_TYPE|D_ERROR))) {
|
if (df->df_kind == D_ERROR) {
|
||||||
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
|
node_error(fo->fo_tok, "identifier \"%s\" not declared",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
f->fo_ptyp->next = df->df_type;
|
else if (df->df_kind != D_TYPE) {
|
||||||
fo = f->next;
|
node_error(fo->fo_tok, "identifier \"%s\" not a type",
|
||||||
free_forwards(f);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
fo->fo_ptyp->next = df->df_type;
|
||||||
|
free_forwards(fo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reverse(pdf)
|
Reverse(pdf)
|
||||||
|
|
|
@ -104,10 +104,11 @@ construct_type(fund, tp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
dtp->tp_align = tp->tp_align;
|
if (tp) dtp->tp_align = tp->tp_align;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_SUBRANGE:
|
case T_SUBRANGE:
|
||||||
|
assert(tp != 0);
|
||||||
dtp->tp_align = tp->tp_align;
|
dtp->tp_align = tp->tp_align;
|
||||||
dtp->tp_size = tp->tp_size;
|
dtp->tp_size = tp->tp_size;
|
||||||
break;
|
break;
|
||||||
|
@ -386,7 +387,7 @@ 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 (word_size % algn != 0) {
|
if (algn && 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
|
||||||
*/
|
*/
|
||||||
|
@ -449,6 +450,36 @@ FreeType(tp)
|
||||||
free_type(tp);
|
free_type(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeclareType(df, tp)
|
||||||
|
register struct def *df;
|
||||||
|
register struct type *tp;
|
||||||
|
{
|
||||||
|
/* A type with type-description "tp" is declared and must
|
||||||
|
be bound to definition "df".
|
||||||
|
This routine also handles the case that the type-field of
|
||||||
|
"df" is already bound. In that case, it is either an opaque
|
||||||
|
type, or an error message was given when "df" was created.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
|
||||||
|
if (tp->tp_fund != T_POINTER) {
|
||||||
|
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
|
}
|
||||||
|
/* Careful now ... we might have declarations
|
||||||
|
referring to the hidden type.
|
||||||
|
*/
|
||||||
|
*(df->df_type) = *tp;
|
||||||
|
if (! tp->next) {
|
||||||
|
/* It also contains a forward reference,
|
||||||
|
so update the forwardlist
|
||||||
|
*/
|
||||||
|
ChForward(tp, df->df_type);
|
||||||
|
}
|
||||||
|
free_type(tp);
|
||||||
|
}
|
||||||
|
else df->df_type = tp;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gcd(m, n)
|
gcd(m, n)
|
||||||
register int m, n;
|
register int m, n;
|
||||||
|
|
|
@ -81,6 +81,9 @@ TstProcEquiv(tp1, tp2)
|
||||||
p2 = p2->next;
|
p2 = p2->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Here, at least one of the parameterlists is exhausted.
|
||||||
|
Check that they are both.
|
||||||
|
*/
|
||||||
return p1 == p2;
|
return p1 == p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,18 +104,17 @@ TstCompat(tp1, tp2)
|
||||||
||
|
||
|
||||||
( tp1 == intorcard_type
|
( tp1 == intorcard_type
|
||||||
&&
|
&&
|
||||||
(tp2 == int_type || tp2 == card_type)
|
(tp2 == int_type || tp2 == card_type || tp2 == address_type)
|
||||||
)
|
)
|
||||||
||
|
||
|
||||||
( tp2 == intorcard_type
|
( tp2 == intorcard_type
|
||||||
&&
|
&&
|
||||||
(tp1 == int_type || tp1 == card_type)
|
(tp1 == int_type || tp1 == card_type || tp1 == address_type)
|
||||||
)
|
)
|
||||||
||
|
||
|
||||||
( tp1 == address_type
|
( tp1 == address_type
|
||||||
&&
|
&&
|
||||||
( tp2 == card_type
|
( tp2 == card_type
|
||||||
|| tp2 == intorcard_type
|
|
||||||
|| tp2->tp_fund == T_POINTER
|
|| tp2->tp_fund == T_POINTER
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -120,7 +122,6 @@ TstCompat(tp1, tp2)
|
||||||
( tp2 == address_type
|
( tp2 == address_type
|
||||||
&&
|
&&
|
||||||
( tp1 == card_type
|
( tp1 == card_type
|
||||||
|| tp1 == intorcard_type
|
|
||||||
|| tp1->tp_fund == T_POINTER
|
|| tp1->tp_fund == T_POINTER
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -173,7 +174,7 @@ TstAssCompat(tp1, tp2)
|
||||||
|
|
||||||
int
|
int
|
||||||
TstParCompat(formaltype, actualtype, VARflag, nd)
|
TstParCompat(formaltype, actualtype, VARflag, nd)
|
||||||
struct type *formaltype, *actualtype;
|
register struct type *formaltype, *actualtype;
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
{
|
{
|
||||||
/* Check type compatibility for a parameter in a procedure call.
|
/* Check type compatibility for a parameter in a procedure call.
|
||||||
|
@ -218,19 +219,12 @@ TstParCompat(formaltype, actualtype, VARflag, nd)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
||
|
||
|
||||||
( VARflag && OldCompat(formaltype, actualtype, nd))
|
( VARflag
|
||||||
|
&& ( TstCompat(formaltype, actualtype)
|
||||||
|
&&
|
||||||
|
(node_warning(nd, "oldfashioned! types of formal and actual must be identical"),
|
||||||
|
1)
|
||||||
|
)
|
||||||
|
)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
OldCompat(ft, at, nd)
|
|
||||||
struct type *ft, *at;
|
|
||||||
struct node *nd;
|
|
||||||
{
|
|
||||||
if (TstCompat(ft, at)) {
|
|
||||||
node_warning(nd, "oldfashioned! types of formal and actual must be identical");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ WalkProcedure(procedure)
|
||||||
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;
|
||||||
|
arith tmpvar1 = 0;
|
||||||
|
arith retsav = 0;
|
||||||
|
|
||||||
proclevel++;
|
proclevel++;
|
||||||
CurrVis = procedure->prc_vis;
|
CurrVis = procedure->prc_vis;
|
||||||
|
@ -147,6 +149,14 @@ WalkProcedure(procedure)
|
||||||
DoProfil();
|
DoProfil();
|
||||||
TmpOpen(sc);
|
TmpOpen(sc);
|
||||||
|
|
||||||
|
func_type = tp = ResultType(procedure->df_type);
|
||||||
|
|
||||||
|
if (tp && IsConstructed(tp)) {
|
||||||
|
func_res_label = ++data_label;
|
||||||
|
C_df_dlb(func_res_label);
|
||||||
|
C_bss_cst(tp->tp_size, (arith) 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate calls to initialization routines of modules defined within
|
/* Generate calls to initialization routines of modules defined within
|
||||||
this procedure
|
this procedure
|
||||||
*/
|
*/
|
||||||
|
@ -154,6 +164,7 @@ WalkProcedure(procedure)
|
||||||
|
|
||||||
/* 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.
|
||||||
|
Also make copies of conformant arrays when neccessary.
|
||||||
*/
|
*/
|
||||||
for (param = ParamList(procedure->df_type);
|
for (param = ParamList(procedure->df_type);
|
||||||
param;
|
param;
|
||||||
|
@ -161,37 +172,114 @@ WalkProcedure(procedure)
|
||||||
if (! IsVarParam(param)) {
|
if (! IsVarParam(param)) {
|
||||||
tp = TypeOfParam(param);
|
tp = TypeOfParam(param);
|
||||||
|
|
||||||
if (!IsConformantArray(tp) && tp->tp_size < word_size) {
|
if (! IsConformantArray(tp)) {
|
||||||
|
if (tp->tp_size < word_size) {
|
||||||
C_lol(param->par_def->var_off);
|
C_lol(param->par_def->var_off);
|
||||||
C_lal(param->par_def->var_off);
|
C_lal(param->par_def->var_off);
|
||||||
C_sti(tp->tp_size);
|
C_sti(tp->tp_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* Here, we have to make a copy of the
|
||||||
|
array. We must also remember how much
|
||||||
|
room is reserved for copies, because
|
||||||
|
we have to adjust the stack pointer before
|
||||||
|
a RET is done. This is even more complicated
|
||||||
|
when the procedure returns a value.
|
||||||
|
Then, the value must be saved (in retval),
|
||||||
|
the stack adjusted, the return value pushed
|
||||||
|
again, and then RET
|
||||||
|
*/
|
||||||
|
arith tmpvar = NewInt();
|
||||||
|
|
||||||
|
if (! tmpvar1) {
|
||||||
|
if (tp && !func_res_label) {
|
||||||
|
/* Some local space, only
|
||||||
|
needed if the value itself
|
||||||
|
is returned
|
||||||
|
*/
|
||||||
|
sc->sc_off -= WA(tp->tp_size);
|
||||||
|
retsav = sc->sc_off;
|
||||||
|
}
|
||||||
|
tmpvar1 = NewInt();
|
||||||
|
C_loc((arith) 0);
|
||||||
|
C_stl(tmpvar1);
|
||||||
|
}
|
||||||
|
/* First compute the size */
|
||||||
|
C_lol(param->par_def->var_off +
|
||||||
|
pointer_size + word_size);
|
||||||
|
C_inc(); /* gives number of elements */
|
||||||
|
C_loc(tp->arr_elem->tp_size);
|
||||||
|
C_cal("_wa");
|
||||||
|
C_asp(dword_size);
|
||||||
|
C_lfr(word_size);
|
||||||
|
/* size in words */
|
||||||
|
C_loc(word_size);
|
||||||
|
C_mli(word_size);
|
||||||
|
/* size in bytes */
|
||||||
|
C_stl(tmpvar);
|
||||||
|
C_lol(tmpvar);
|
||||||
|
C_dup(word_size);
|
||||||
|
C_lol(tmpvar1);
|
||||||
|
C_adi(word_size);
|
||||||
|
C_stl(tmpvar1); /* remember all stack adjustments */
|
||||||
|
C_ngi(word_size);
|
||||||
|
C_ass(word_size);
|
||||||
|
/* adjusted stack pointer */
|
||||||
|
C_lor((arith) 1);
|
||||||
|
/* destination address */
|
||||||
|
C_lal(param->par_def->var_off);
|
||||||
|
C_loi(pointer_size);
|
||||||
|
/* push source address */
|
||||||
|
C_exg(pointer_size);
|
||||||
|
/* exchange them */
|
||||||
|
C_lol(tmpvar); /* push size */
|
||||||
|
C_bls(word_size);
|
||||||
|
/* copy */
|
||||||
|
C_lor((arith) 1);
|
||||||
|
/* push new address of array */
|
||||||
|
C_lal(param->par_def->var_off);
|
||||||
|
C_sti(pointer_size);
|
||||||
|
FreeInt(tmpvar);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text_label = 1;
|
text_label = 1;
|
||||||
func_type = tp = ResultType(procedure->df_type);
|
|
||||||
|
|
||||||
if (IsConstructed(tp)) {
|
|
||||||
func_res_label = ++data_label;
|
|
||||||
C_df_dlb(func_res_label);
|
|
||||||
C_bss_cst(tp->tp_size, (arith) 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
||||||
WalkNode(procedure->prc_body, (label) 0);
|
WalkNode(procedure->prc_body, (label) 0);
|
||||||
C_ret((arith) 0);
|
|
||||||
if (tp) {
|
|
||||||
C_df_ilb((label) 1);
|
C_df_ilb((label) 1);
|
||||||
|
tp = func_type;
|
||||||
if (func_res_label) {
|
if (func_res_label) {
|
||||||
C_lae_dlb(func_res_label, (arith) 0);
|
C_lae_dlb(func_res_label, (arith) 0);
|
||||||
C_sti(tp->tp_size);
|
C_sti(tp->tp_size);
|
||||||
|
if (tmpvar1) {
|
||||||
|
C_lol(tmpvar1);
|
||||||
|
C_ass(word_size);
|
||||||
|
}
|
||||||
C_lae_dlb(func_res_label, (arith) 0);
|
C_lae_dlb(func_res_label, (arith) 0);
|
||||||
C_ret(pointer_size);
|
C_ret(pointer_size);
|
||||||
}
|
}
|
||||||
else C_ret(WA(tp->tp_size));
|
else if (tp) {
|
||||||
|
if (tmpvar1) {
|
||||||
|
C_lal(retsav);
|
||||||
|
C_sti(WA(tp->tp_size));
|
||||||
|
C_lol(tmpvar1);
|
||||||
|
C_ass(word_size);
|
||||||
|
C_lal(retsav);
|
||||||
|
C_loi(WA(tp->tp_size));
|
||||||
}
|
}
|
||||||
|
C_ret(WA(tp->tp_size));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (tmpvar1) {
|
||||||
|
C_lol(tmpvar1);
|
||||||
|
C_ass(word_size);
|
||||||
|
}
|
||||||
|
C_ret((arith) 0);
|
||||||
|
}
|
||||||
|
if (tmpvar1) FreeInt(tmpvar1);
|
||||||
if (! options['n']) RegisterMessages(sc->sc_def);
|
if (! options['n']) RegisterMessages(sc->sc_def);
|
||||||
C_end(-sc->sc_off);
|
C_end(-sc->sc_off);
|
||||||
TmpClose();
|
TmpClose();
|
||||||
|
@ -394,7 +482,7 @@ WalkStat(nd, lab)
|
||||||
struct desig ds;
|
struct desig ds;
|
||||||
arith tmp = 0;
|
arith tmp = 0;
|
||||||
|
|
||||||
WalkDesignator(left, &ds);
|
if (! WalkDesignator(left, &ds)) 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;
|
||||||
|
@ -432,7 +520,7 @@ WalkStat(nd, lab)
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
if (right) {
|
if (right) {
|
||||||
WalkExpr(right);
|
if (! WalkExpr(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).
|
||||||
|
@ -440,9 +528,8 @@ WalkStat(nd, lab)
|
||||||
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");
|
||||||
}
|
}
|
||||||
C_bra((label) 1);
|
|
||||||
}
|
}
|
||||||
else C_ret((arith) 0);
|
C_bra((label) 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -487,17 +574,20 @@ ExpectBool(nd, true_label, false_label)
|
||||||
CodeExpr(nd, &ds, true_label, false_label);
|
CodeExpr(nd, &ds, true_label, false_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
WalkExpr(nd)
|
WalkExpr(nd)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
{
|
{
|
||||||
/* Check an expression and generate code for it
|
/* Check an expression and generate code for it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (! ChkExpression(nd)) return;
|
if (! ChkExpression(nd)) return 0;
|
||||||
|
|
||||||
CodePExpr(nd);
|
CodePExpr(nd);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
WalkDesignator(nd, ds)
|
WalkDesignator(nd, ds)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
struct desig *ds;
|
struct desig *ds;
|
||||||
|
@ -505,10 +595,11 @@ WalkDesignator(nd, ds)
|
||||||
/* Check designator and generate code for it
|
/* Check designator and generate code for it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (! ChkVariable(nd)) return;
|
if (! ChkVariable(nd)) return 0;
|
||||||
|
|
||||||
*ds = InitDesig;
|
*ds = InitDesig;
|
||||||
CodeDesig(nd, ds);
|
CodeDesig(nd, ds);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoForInit(nd, left)
|
DoForInit(nd, left)
|
||||||
|
|
Loading…
Add table
Reference in a new issue