newer version

This commit is contained in:
ceriel 1986-10-06 20:36:30 +00:00
parent f3bf7cd5bc
commit 3030eb8cae
50 changed files with 839 additions and 924 deletions

View file

@ -1,9 +1,5 @@
/* L E X I C A L A N A L Y S E R F O R M O D U L A - 2 */ /* L E X I C A L A N A L Y S E R F O R M O D U L A - 2 */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include "idfsize.h" #include "idfsize.h"
#include "numsize.h" #include "numsize.h"
@ -40,9 +36,10 @@ SkipComment()
Note that comments may be nested (par. 3.5). Note that comments may be nested (par. 3.5).
*/ */
register int ch; register int ch;
register int CommentLevel = 0;
LoadChar(ch);
for (;;) { for (;;) {
LoadChar(ch);
if (class(ch) == STNL) { if (class(ch) == STNL) {
LineNumber++; LineNumber++;
#ifdef DEBUG #ifdef DEBUG
@ -51,12 +48,22 @@ SkipComment()
} }
else if (ch == '(') { else if (ch == '(') {
LoadChar(ch); LoadChar(ch);
if (ch == '*') SkipComment(); if (ch == '*') CommentLevel++;
else continue;
} }
else if (ch == '*') { else if (ch == '*') {
LoadChar(ch); LoadChar(ch);
if (ch == ')') break; if (ch == ')') {
CommentLevel--;
if (CommentLevel < 0) break;
}
else continue;
} }
else if (ch == EOI) {
lexerror("unterminated comment");
break;
}
LoadChar(ch);
} }
} }
@ -69,7 +76,8 @@ GetString(upto)
register struct string *str = (struct string *) Malloc(sizeof(struct string)); register struct string *str = (struct string *) Malloc(sizeof(struct string));
register char *p; register char *p;
str->s_str = p = Malloc((unsigned int) (str->s_length = ISTRSIZE)); str->s_length = ISTRSIZE;
str->s_str = p = Malloc((unsigned int) ISTRSIZE);
while (LoadChar(ch), ch != upto) { while (LoadChar(ch), ch != upto) {
if (class(ch) == STNL) { if (class(ch) == STNL) {
lexerror("newline in string"); lexerror("newline in string");
@ -394,6 +402,7 @@ lexwarning("Character constant out of range");
case STCHAR: case STCHAR:
default: default:
crash("(LLlex) Impossible character class"); crash("(LLlex) Impossible character class");
/*NOTREACHED*/
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }

View file

@ -1,7 +1,5 @@
/* T O K E N D E S C R I P T O R D E F I N I T I O N */ /* T O K E N D E S C R I P T O R D E F I N I T I O N */
/* $Header$ */
/* Structure to store a string constant /* Structure to store a string constant
*/ */
struct string { struct string {

View file

@ -1,9 +1,5 @@
/* S Y N T A X E R R O R R E P O R T I N G */ /* S Y N T A X E R R O R R E P O R T I N G */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Defines the LLmessage routine. LLgen-generated parsers require the /* Defines the LLmessage routine. LLgen-generated parsers require the
existence of a routine of that name. existence of a routine of that name.
The routine must do syntax-error reporting and must be able to The routine must do syntax-error reporting and must be able to
@ -39,24 +35,28 @@ LLmessage(tk)
insert_token(tk) insert_token(tk)
int tk; int tk;
{ {
aside = dot; register struct token *dotp = &dot;
dot.tk_symb = tk; aside = *dotp;
dotp->tk_symb = tk;
switch (tk) { switch (tk) {
/* The operands need some body */ /* The operands need some body */
case IDENT: case IDENT:
dot.TOK_IDF = gen_anon_idf(); dotp->TOK_IDF = gen_anon_idf();
break; break;
case STRING: case STRING:
dot.TOK_SLE = 1; dotp->tk_data.tk_str = (struct string *)
dot.TOK_STR = Salloc("", 1); Malloc(sizeof (struct string));
dotp->TOK_SLE = 1;
dotp->TOK_STR = Salloc("", 1);
break; break;
case INTEGER: case INTEGER:
dot.TOK_INT = 1; dotp->TOK_INT = 1;
break; break;
case REAL: case REAL:
dot.TOK_REL = Salloc("0.0", 4); dotp->TOK_REL = Salloc("0.0", 4);
break; break;
} }
} }

View file

@ -1,5 +1,4 @@
# make modula-2 "compiler" # make modula-2 "compiler"
# $Header$
EMDIR = /usr/ceriel/em EMDIR = /usr/ceriel/em
MHDIR = $(EMDIR)/modules/h MHDIR = $(EMDIR)/modules/h
PKGDIR = $(EMDIR)/modules/pkg PKGDIR = $(EMDIR)/modules/pkg
@ -8,19 +7,26 @@ 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 GFILES = tokenfile.g program.g declar.g expression.g statement.g
CC = cc CC = cc
LLGENOPTIONS = LLGENOPTIONS =
PROFILE = PROFILE =
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC= CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
LINTFLAGS = -DSTATIC= -DNORCSID LINTFLAGS = -DSTATIC= -DNORCSID
LFLAGS = $(PROFILE) LFLAGS = $(PROFILE)
LSRC = tokenfile.c program.c declar.c expression.c statement.c
LOBJ = tokenfile.o program.o declar.o expression.o statement.o LOBJ = tokenfile.o program.o declar.o expression.o statement.o
CSRC = LLlex.c LLmessage.c char.c error.c main.c \
symbol2str.c tokenname.c idf.c input.c type.c def.c \
scope.c misc.c enter.c defmodule.c typequiv.c node.c \
cstoper.c chk_expr.c options.c walk.c casestat.c desig.c \
code.c tmpvar.c lookup.c Version.c
COBJ = LLlex.o LLmessage.o char.o error.o main.o \ COBJ = LLlex.o LLmessage.o char.o error.o main.o \
symbol2str.o tokenname.o idf.o input.o type.o def.o \ symbol2str.o tokenname.o idf.o input.o type.o def.o \
scope.o misc.o enter.o defmodule.o typequiv.o node.o \ scope.o misc.o enter.o defmodule.o typequiv.o node.o \
cstoper.o chk_expr.o options.o walk.o casestat.o desig.o \ cstoper.o chk_expr.o options.o walk.o casestat.o desig.o \
code.o tmpvar.o lookup.o code.o tmpvar.o lookup.o Version.o
SRC = $(CSRC) $(LSRC) Lpars.c
OBJ = $(COBJ) $(LOBJ) Lpars.o OBJ = $(COBJ) $(LOBJ) Lpars.o
# Keep the next entries up to date! # Keep the next entries up to date!
@ -44,11 +50,11 @@ all: Cfiles
@rm -f nmclash.o a.out @rm -f nmclash.o a.out
clean: clean:
rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab cclash.o cid.o cclash cid rm -f $(OBJ) $(GENFILES) LLfiles hfiles Cfiles tab cclash.o cid.o cclash cid clashes
(cd .. ; rm -rf Xsrc) (cd .. ; rm -rf Xsrc)
lint: Cfiles lint: Cfiles
sh -c `if $(CC) nmclash.c > /dev/null 2>&1 ; then make Xlint ; else sh Resolve Xlint ; fi' sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make Xlint ; else sh Resolve Xlint ; fi'
@rm -f nmclash.o a.out @rm -f nmclash.o a.out
mkdep: mkdep.o mkdep: mkdep.o
@ -57,20 +63,22 @@ mkdep: mkdep.o
cclash: cclash.o cclash: cclash.o
$(CC) $(LFLAGS) -o cclash cclash.o $(CC) $(LFLAGS) -o cclash cclash.o
clashes: $(SRC) $(HFILES)
sh -c 'if test -f clashes ; then ./cclash -l7 clashes $? > Xclashes ; mv Xclashes clashes ; else ./cclash -l7 $? > clashes ; fi'
cid: cid.o cid: cid.o
$(CC) $(LFLAGS) -o cid cid.o $(CC) $(LFLAGS) -o cid cid.o
# entry points not to be used directly # entry points not to be used directly
Xlint: Xlint:
lint $(INCLUDES) $(LINTFLAGS) `./sources $(OBJ)` lint $(INCLUDES) $(LINTFLAGS) $(SRC)
Cfiles: hfiles LLfiles $(GENHFILES) $(GENCFILES) Cfiles: hfiles LLfiles $(GENCFILES) $(GENHFILES)
./sources $(OBJ) > Cfiles echo $(SRC) $(HFILES) > Cfiles
sh -c 'for i in $(HFILES) ; do echo $$i ; done >> Cfiles'
LLfiles: $(LSRC) LLfiles: $(GFILES)
$(LLGEN) $(LLGENOPTIONS) $(LSRC) $(LLGEN) $(LLGENOPTIONS) $(GFILES)
@touch LLfiles @touch LLfiles
hfiles: Parameters make.hfiles hfiles: Parameters make.hfiles
@ -78,7 +86,7 @@ hfiles: Parameters make.hfiles
touch hfiles touch hfiles
main: $(OBJ) ../src/Makefile main: $(OBJ) ../src/Makefile
$(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 $(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libem_mes.a $(LIBDIR)/libemk.a $(LIBDIR)/input.a $(LIBDIR)/assert.a $(LIBDIR)/alloc.a $(LIBDIR)/dickmalloc.o $(LIBDIR)/libprint.a $(LIBDIR)/libstr.a $(LIBDIR)/libsystem.a -o ../src/main
size ../src/main size ../src/main
tokenfile.g: tokenname.c make.tokfile tokenfile.g: tokenname.c make.tokfile
@ -114,7 +122,7 @@ char.c: ../src/char.tab ../src/tab
depend: mkdep depend: mkdep
sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
./mkdep `./sources $(OBJ)` |\ ./mkdep $(SRC) |\
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
@ -128,13 +136,13 @@ main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h inputtype.h ndir.h
symbol2str.o: Lpars.h symbol2str.o: Lpars.h
tokenname.o: Lpars.h idf.h tokenname.h tokenname.o: Lpars.h idf.h tokenname.h
idf.o: idf.h idf.o: idf.h
input.o: f_info.h input.h inputtype.h input.o: def.h f_info.h idf.h input.h inputtype.h scope.h
type.o: LLlex.h const.h debug.h def.h idf.h maxset.h node.h scope.h target_sizes.h type.h walk.h type.o: LLlex.h const.h debug.h def.h idf.h maxset.h node.h scope.h target_sizes.h type.h walk.h
def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
scope.o: LLlex.h debug.h def.h idf.h node.h scope.h type.h scope.o: LLlex.h debug.h def.h idf.h node.h scope.h type.h
misc.o: LLlex.h f_info.h idf.h misc.h node.h misc.o: LLlex.h f_info.h idf.h misc.h node.h
enter.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h enter.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h
defmodule.o: LLlex.h debug.h def.h f_info.h idf.h input.h inputtype.h main.h scope.h defmodule.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h inputtype.h main.h node.h scope.h
typequiv.o: LLlex.h debug.h def.h node.h type.h typequiv.o: LLlex.h debug.h def.h node.h type.h
node.o: LLlex.h debug.h def.h node.h type.h node.o: LLlex.h debug.h def.h node.h type.h
cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h
@ -145,7 +153,7 @@ casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h walk.h
desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h
code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h walk.h code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h walk.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 type.h
tokenfile.o: Lpars.h tokenfile.o: Lpars.h
program.o: LLlex.h Lpars.h debug.h def.h f_info.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

View file

@ -34,13 +34,13 @@
/* target machine alignment requirements */ /* target machine alignment requirements */
#define AL_CHAR 1 #define AL_CHAR 1
#define AL_SHORT SZ_SHORT #define AL_SHORT (int)SZ_SHORT
#define AL_WORD SZ_WORD #define AL_WORD (int)SZ_WORD
#define AL_INT SZ_WORD #define AL_INT (int)SZ_WORD
#define AL_LONG SZ_WORD #define AL_LONG (int)SZ_WORD
#define AL_FLOAT SZ_WORD #define AL_FLOAT (int)SZ_WORD
#define AL_DOUBLE SZ_WORD #define AL_DOUBLE (int)SZ_WORD
#define AL_POINTER SZ_WORD #define AL_POINTER (int)SZ_WORD
#define AL_STRUCT 1 #define AL_STRUCT 1
#define AL_UNION 1 #define AL_UNION 1
@ -55,7 +55,7 @@ extern char options[];
#endif DEBUG #endif DEBUG
!File: inputtype.h !File: inputtype.h
#undef INP_READ_IN_ONE 1 /* read input file in one */ #define INP_READ_IN_ONE 1 /* read input file in one */
!File: maxset.h !File: maxset.h

View file

@ -19,10 +19,10 @@ then
: :
else mkdir ../Xsrc else mkdir ../Xsrc
fi fi
make cclash make cclash clashes cid
make cid sed '/^C_/d' < clashes > tmp$$
./cclash -c -l7 `cat Cfiles` > clashes ./cclash -c -l7 tmp$$ > ../Xsrc/Xclashes
sed '/^C_/d' < clashes > ../Xsrc/Xclashes rm -f tmp$$
cd ../Xsrc cd ../Xsrc
if cmp -s Xclashes clashes if cmp -s Xclashes clashes
then then

1
lang/m2/comp/Version.c Normal file
View file

@ -0,0 +1 @@
char Version[] = "Version 0.5";

View file

@ -1,8 +1,11 @@
/* C A S E S T A T E M E N T C O D E G E N E R A T I O N */ /* C A S E S T A T E M E N T C O D E G E N E R A T I O N */
#ifndef NORCSID /* Generation of case statements is done by first creating a
static char *RcsId = "$Header$"; description structure for the statement, build a list of the
#endif case-labels, then generating a case description in the code,
and generating either CSA or CSB, and then generating code for the
cases themselves.
*/
#include "debug.h" #include "debug.h"
@ -22,30 +25,32 @@ static char *RcsId = "$Header$";
#include "density.h" #include "density.h"
struct switch_hdr { struct switch_hdr {
struct switch_hdr *next; struct switch_hdr *next; /* in the free list */
label sh_break; label sh_break; /* label of statement after this one */
label sh_default; label sh_default; /* label of ELSE part, or 0 */
int sh_nrofentries; int sh_nrofentries; /* number of cases */
struct type *sh_type; struct type *sh_type; /* type of case expression */
arith sh_lowerbd; arith sh_lowerbd; /* lowest case label */
arith sh_upperbd; arith sh_upperbd; /* highest case label */
struct case_entry *sh_entries; struct case_entry *sh_entries; /* the cases with their generated
labels
*/
}; };
/* STATICALLOCDEF "switch_hdr" */ /* STATICALLOCDEF "switch_hdr" 5 */
struct case_entry { struct case_entry {
struct case_entry *next; struct case_entry *next; /* next in list */
label ce_label; label ce_label; /* generated label */
arith ce_value; arith ce_value; /* value of case label */
}; };
/* STATICALLOCDEF "case_entry" */ /* STATICALLOCDEF "case_entry" 20 */
/* The constant DENSITY determines when CSA and when CSB instructions /* The constant DENSITY determines when CSA and when CSB instructions
are generated. Reasonable values are: 2, 3, 4. are generated. Reasonable values are: 2, 3, 4.
On machines that have lots of address space and memory, higher values On machines that have lots of address space and memory, higher values
are also reasonable. On these machines the density of jump tables might also be reasonable. On these machines the density of jump tables
may be lower. may be lower.
*/ */
#define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY) #define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY)
@ -56,30 +61,36 @@ CaseCode(nd, exitlabel)
{ {
/* Check the expression, stack a new case header and /* Check the expression, stack a new case header and
fill in the necessary fields. fill in the necessary fields.
"exitlabel" is the exit-label of the closest enclosing
LOOP-statement, or 0.
*/ */
register struct switch_hdr *sh = new_switch_hdr(); register struct switch_hdr *sh = new_switch_hdr();
register struct node *pnode = nd; register struct node *pnode = nd;
register struct case_entry *ce; register struct case_entry *ce;
register arith val; register arith val;
label tablabel; label CaseDescrLab;
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE); assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
clear((char *) sh, sizeof(*sh)); WalkExpr(pnode->nd_left); /* evaluate case expression */
WalkExpr(pnode->nd_left);
sh->sh_type = pnode->nd_left->nd_type; sh->sh_type = pnode->nd_left->nd_type;
sh->sh_break = ++text_label; sh->sh_break = ++text_label;
/* Now, create case label list /* Now, create case label list
*/ */
while (pnode && pnode->nd_right) { while (pnode->nd_right) {
pnode = pnode->nd_right; pnode = pnode->nd_right;
if (pnode->nd_class == Link && pnode->nd_symb == '|') { if (pnode->nd_class == Link && pnode->nd_symb == '|') {
if (pnode->nd_left) { if (pnode->nd_left) {
/* non-empty case
*/
pnode->nd_lab = ++text_label; pnode->nd_lab = ++text_label;
if (! AddCases(sh, if (! AddCases(sh, /* to descriptor */
pnode->nd_left->nd_left, pnode->nd_left->nd_left,
pnode->nd_lab)) { /* of case labels */
pnode->nd_lab
/* and code label */
)) {
FreeSh(sh); FreeSh(sh);
return; return;
} }
@ -90,19 +101,20 @@ CaseCode(nd, exitlabel)
*/ */
sh->sh_default = ++text_label; sh->sh_default = ++text_label;
pnode = 0; break;
} }
} }
/* Now generate code for the switch itself /* Now generate code for the switch itself
First the part that CSA and CSB descriptions have in common.
*/ */
tablabel = ++data_label; /* the rom must have a label */ CaseDescrLab = ++data_label; /* the rom must have a label */
C_df_dlb(tablabel); C_df_dlb(CaseDescrLab);
if (sh->sh_default) C_rom_ilb(sh->sh_default); if (sh->sh_default) C_rom_ilb(sh->sh_default);
else C_rom_ucon("0", pointer_size); else C_rom_ucon("0", pointer_size);
if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) { if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
/* CSA */ /* CSA
*/
C_rom_cst(sh->sh_lowerbd); C_rom_cst(sh->sh_lowerbd);
C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd); C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
ce = sh->sh_entries; ce = sh->sh_entries;
@ -115,24 +127,27 @@ CaseCode(nd, exitlabel)
else if (sh->sh_default) C_rom_ilb(sh->sh_default); else if (sh->sh_default) C_rom_ilb(sh->sh_default);
else C_rom_ucon("0", pointer_size); else C_rom_ucon("0", pointer_size);
} }
C_lae_dlb(tablabel, (arith)0); /* perform the switch */ C_lae_dlb(CaseDescrLab, (arith)0); /* perform the switch */
C_csa(word_size); C_csa(word_size);
} }
else { /* CSB */ else {
/* CSB
*/
C_rom_cst((arith)sh->sh_nrofentries); C_rom_cst((arith)sh->sh_nrofentries);
for (ce = sh->sh_entries; ce; ce = ce->next) { for (ce = sh->sh_entries; ce; ce = ce->next) {
/* generate the entries: value + prog.label */ /* generate the entries: value + prog.label
*/
C_rom_cst(ce->ce_value); C_rom_cst(ce->ce_value);
C_rom_ilb(ce->ce_label); C_rom_ilb(ce->ce_label);
} }
C_lae_dlb(tablabel, (arith)0); /* perform the switch */ C_lae_dlb(CaseDescrLab, (arith)0); /* perform the switch */
C_csb(word_size); C_csb(word_size);
} }
/* Now generate code for the cases /* Now generate code for the cases
*/ */
pnode = nd; pnode = nd;
while (pnode && pnode->nd_right) { while (pnode->nd_right) {
pnode = pnode->nd_right; pnode = pnode->nd_right;
if (pnode->nd_class == Link && pnode->nd_symb == '|') { if (pnode->nd_class == Link && pnode->nd_symb == '|') {
if (pnode->nd_left) { if (pnode->nd_left) {
@ -148,7 +163,7 @@ CaseCode(nd, exitlabel)
C_df_ilb(sh->sh_default); C_df_ilb(sh->sh_default);
WalkNode(pnode, exitlabel); WalkNode(pnode, exitlabel);
pnode = 0; break;
} }
} }
@ -157,7 +172,7 @@ CaseCode(nd, exitlabel)
} }
FreeSh(sh) FreeSh(sh)
struct switch_hdr *sh; register struct switch_hdr *sh;
{ {
/* free the allocated switch structure /* free the allocated switch structure
*/ */
@ -176,7 +191,7 @@ FreeSh(sh)
AddCases(sh, node, lbl) AddCases(sh, node, lbl)
struct switch_hdr *sh; struct switch_hdr *sh;
struct node *node; register struct node *node;
label lbl; label lbl;
{ {
/* Add case labels to the case label list /* Add case labels to the case label list
@ -208,7 +223,7 @@ AddCases(sh, node, lbl)
AddOneCase(sh, node, lbl) AddOneCase(sh, node, lbl)
register struct switch_hdr *sh; register struct switch_hdr *sh;
struct node *node; register struct node *node;
label lbl; label lbl;
{ {
register struct case_entry *ce = new_case_entry(); register struct case_entry *ce = new_case_entry();
@ -222,15 +237,17 @@ AddOneCase(sh, node, lbl)
return 0; return 0;
} }
if (sh->sh_entries == 0) { if (sh->sh_entries == 0) {
/* first case entry */ /* first case entry
*/
ce->next = (struct case_entry *) 0; ce->next = (struct case_entry *) 0;
sh->sh_entries = ce; sh->sh_entries = ce;
sh->sh_lowerbd = sh->sh_upperbd = ce->ce_value; sh->sh_lowerbd = sh->sh_upperbd = ce->ce_value;
sh->sh_nrofentries = 1; sh->sh_nrofentries = 1;
} }
else { else {
/* second etc. case entry */ /* second etc. case entry
/* find the proper place to put ce into the list */ find the proper place to put ce into the list
*/
if (ce->ce_value < sh->sh_lowerbd) { if (ce->ce_value < sh->sh_lowerbd) {
sh->sh_lowerbd = ce->ce_value; sh->sh_lowerbd = ce->ce_value;

View file

@ -1,9 +1,5 @@
/* E X P R E S S I O N C H E C K I N G */ /* E X P R E S S I O N C H E C K I N G */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Check expressions, and try to evaluate them as far as possible. /* Check expressions, and try to evaluate them as far as possible.
*/ */
@ -31,6 +27,9 @@ int
ChkVariable(expp) ChkVariable(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check that "expp" indicates an item that can be
assigned to.
*/
if (! ChkDesignator(expp)) return 0; if (! ChkDesignator(expp)) return 0;
@ -47,6 +46,9 @@ STATIC int
ChkArrow(expp) ChkArrow(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check an application of the '^' operator.
The operand must be a variable of a pointer type.
*/
register struct type *tp; register struct type *tp;
assert(expp->nd_class == Arrow); assert(expp->nd_class == Arrow);
@ -59,8 +61,7 @@ ChkArrow(expp)
tp = expp->nd_right->nd_type; tp = expp->nd_right->nd_type;
if (tp->tp_fund != T_POINTER) { if (tp->tp_fund != T_POINTER) {
node_error(expp, "illegal operand for unary operator \"%s\"", node_error(expp, "illegal operand for unary operator \"^\"");
symbol2str(expp->nd_symb));
return 0; return 0;
} }
@ -72,6 +73,12 @@ STATIC int
ChkArr(expp) ChkArr(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check an array selection.
The left hand side must be a variable of an array type,
and the right hand side must be an expression that is
assignment compatible with the array-index.
*/
register struct type *tpl, *tpr; register struct type *tpl, *tpr;
assert(expp->nd_class == Arrsel); assert(expp->nd_class == Arrsel);
@ -91,7 +98,7 @@ ChkArr(expp)
tpr = expp->nd_right->nd_type; tpr = expp->nd_right->nd_type;
if (tpl->tp_fund != T_ARRAY) { if (tpl->tp_fund != T_ARRAY) {
node_error(expp, "array index not belonging to an ARRAY"); node_error(expp, "not indexing an ARRAY type");
return 0; return 0;
} }
@ -110,6 +117,7 @@ ChkArr(expp)
return 1; return 1;
} }
#ifdef DEBUG
STATIC int STATIC int
ChkValue(expp) ChkValue(expp)
struct node *expp; struct node *expp;
@ -125,11 +133,15 @@ ChkValue(expp)
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
#endif
STATIC int STATIC int
ChkLinkOrName(expp) ChkLinkOrName(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check either an ID or a construction of the form
ID.ID [ .ID ]*
*/
register struct def *df; register struct def *df;
expp->nd_type = error_type; expp->nd_type = error_type;
@ -140,6 +152,9 @@ ChkLinkOrName(expp)
expp->nd_type = RemoveEqual(expp->nd_def->df_type); expp->nd_type = RemoveEqual(expp->nd_def->df_type);
} }
else if (expp->nd_class == Link) { else if (expp->nd_class == Link) {
/* A selection from a record or a module.
Modules also have a record type.
*/
register struct node *left = expp->nd_left; register struct node *left = expp->nd_left;
assert(expp->nd_symb == '.'); assert(expp->nd_symb == '.');
@ -188,16 +203,17 @@ df->df_idf->id_text);
if (df->df_kind == D_ERROR) 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)) {
/* Replace an enum-literal or a CONST identifier by its value.
*/
if (df->df_kind == D_ENUM) { if (df->df_kind == D_ENUM) {
expp->nd_class = Value; expp->nd_class = Value;
expp->nd_INT = df->enm_val; expp->nd_INT = df->enm_val;
expp->nd_symb = INTEGER; expp->nd_symb = INTEGER;
} }
else { else {
unsigned int ln; unsigned int ln = expp->nd_lineno;
assert(df->df_kind == D_CONST); assert(df->df_kind == D_CONST);
ln = expp->nd_lineno;
*expp = *(df->con_const); *expp = *(df->con_const);
expp->nd_lineno = ln; expp->nd_lineno = ln;
} }
@ -210,25 +226,28 @@ STATIC int
ChkExLinkOrName(expp) ChkExLinkOrName(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check either an ID or an ID.ID [.ID]* occurring in an
expression.
*/
register struct def *df; register struct def *df;
if (! ChkLinkOrName(expp)) return 0; if (! ChkLinkOrName(expp)) return 0;
if (expp->nd_class != Def) return 1; if (expp->nd_class != Def) return 1;
df = expp->nd_def; df = expp->nd_def;
if (!(df->df_kind & (D_ENUM|D_CONST|D_PROCEDURE|D_FIELD|D_VARIABLE|D_PROCHEAD))) { if (!(df->df_kind & D_VALUE)) {
node_error(expp, "value expected"); node_error(expp, "value expected");
} }
if (df->df_kind == D_PROCEDURE) { if (df->df_kind == D_PROCEDURE) {
/* Check that this procedure is one that we /* Check that this procedure is one that we may take the
may take the address from. address from.
*/ */
if (df->df_type == std_type || df->df_scope->sc_level > 0) { if (df->df_type == std_type || df->df_scope->sc_level > 0) {
/* Address of standard or nested procedure /* Address of standard or nested procedure
taken. taken.
*/ */
node_error(expp, "it is illegal to take the address of a standard or local procedure"); node_error(expp, "standard or local procedures may not be assigned");
return 0; return 0;
} }
} }
@ -236,20 +255,6 @@ node_error(expp, "it is illegal to take the address of a standard or local proce
return 1; return 1;
} }
STATIC int
RemoveSet(set)
arith **set;
{
/* This routine is only used for error exits of ChkElement.
It frees the set indicated by "set", and returns 0.
*/
if (*set) {
free((char *) *set);
*set = 0;
}
return 0;
}
STATIC int STATIC int
ChkElement(expp, tp, set) ChkElement(expp, tp, set)
register struct node *expp; register struct node *expp;
@ -279,7 +284,7 @@ ChkElement(expp, tp, set)
if (left->nd_INT > right->nd_INT) { if (left->nd_INT > right->nd_INT) {
node_error(expp, "lower bound exceeds upper bound in range"); node_error(expp, "lower bound exceeds upper bound in range");
return RemoveSet(set); return 0;
} }
if (*set) { if (*set) {
@ -298,28 +303,24 @@ node_error(expp, "lower bound exceeds upper bound in range");
/* Here, a single element is checked /* Here, a single element is checked
*/ */
if (!ChkExpression(expp)) { if (!ChkExpression(expp)) return 0;
return RemoveSet(set);
}
if (!TstCompat(tp, expp->nd_type)) { if (!TstCompat(tp, expp->nd_type)) {
node_error(expp, "set element has incompatible type"); node_error(expp, "set element has incompatible type");
return RemoveSet(set); return 0;
} }
if (expp->nd_class == Value) { if (expp->nd_class == Value) {
/* a constant element /* a constant element
*/ */
i = expp->nd_INT; arith low, high;
if ((tp->tp_fund != T_ENUMERATION && i = expp->nd_INT;
(i < tp->sub_lb || i > tp->sub_ub)) getbounds(tp, &low, &high);
||
(tp->tp_fund == T_ENUMERATION && if (i < low || i > high) {
(i < 0 || i > tp->enm_ncst))
) {
node_error(expp, "set element out of range"); node_error(expp, "set element out of range");
return RemoveSet(set); return 0;
} }
if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits)); if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits));
@ -353,9 +354,11 @@ ChkSet(expp)
assert(nd->nd_class == Def); assert(nd->nd_class == Def);
df = nd->nd_def; df = nd->nd_def;
if (!(df->df_kind & (D_TYPE|D_ERROR)) || if (!is_type(df) ||
(df->df_type->tp_fund != T_SET)) { (df->df_type->tp_fund != T_SET)) {
node_error(expp, "specifier does not represent a set type"); if (df->df_kind != D_ERROR) {
node_error(expp, "type specifier does not represent a set type");
}
return 0; return 0;
} }
tp = df->df_type; tp = df->df_type;
@ -394,7 +397,8 @@ node_error(expp, "specifier does not represent a set type");
/* Yes, it was a constant set, and we managed to compute it! /* Yes, it was a constant set, and we managed to compute it!
Notice that at the moment there is no such thing as Notice that at the moment there is no such thing as
partial evaluation. Either we evaluate the set, or we partial evaluation. Either we evaluate the set, or we
don't (at all). Improvement not neccesary. (???) don't (at all). Improvement not neccesary (???)
??? sets have a contant part and a variable part ???
*/ */
expp->nd_class = Set; expp->nd_class = Set;
expp->nd_set = set; expp->nd_set = set;
@ -417,7 +421,6 @@ getarg(argp, bases, designator)
that it must be a designator and may not be a register that it must be a designator and may not be a register
variable. variable.
*/ */
struct type *tp;
register struct node *arg = (*argp)->nd_right; register struct node *arg = (*argp)->nd_right;
register struct node *left; register struct node *left;
@ -437,8 +440,7 @@ getarg(argp, bases, designator)
} }
if (bases) { if (bases) {
tp = BaseType(left->nd_type); if (!(BaseType(left->nd_type)->tp_fund & bases)) {
if (!(tp->tp_fund & bases)) {
node_error(arg, "unexpected type"); node_error(arg, "unexpected type");
return 0; return 0;
} }
@ -452,7 +454,12 @@ STATIC struct node *
getname(argp, kinds) getname(argp, kinds)
struct node **argp; struct node **argp;
{ {
/* Get the next argument from argument list "argp".
The argument must indicate a definition, and the
definition kind must be one of "kinds".
*/
register struct node *arg = *argp; register struct node *arg = *argp;
register struct node *left;
if (!arg->nd_right) { if (!arg->nd_right) {
node_error(arg, "too few arguments supplied"); node_error(arg, "too few arguments supplied");
@ -460,25 +467,26 @@ getname(argp, kinds)
} }
arg = arg->nd_right; arg = arg->nd_right;
if (! ChkDesignator(arg->nd_left)) return 0; left = arg->nd_left;
if (! ChkDesignator(left)) return 0;
if (arg->nd_left->nd_class != Def && arg->nd_left->nd_class != LinkDef) { if (left->nd_class != Def && left->nd_class != LinkDef) {
node_error(arg, "identifier expected"); node_error(arg, "identifier expected");
return 0; return 0;
} }
if (!(arg->nd_left->nd_def->df_kind & kinds)) { if (!(left->nd_def->df_kind & kinds)) {
node_error(arg, "unexpected type"); node_error(arg, "unexpected type");
return 0; return 0;
} }
*argp = arg; *argp = arg;
return arg->nd_left; return left;
} }
STATIC int STATIC int
ChkProcCall(expp) ChkProcCall(expp)
register struct node *expp; struct node *expp;
{ {
/* Check a procedure call /* Check a procedure call
*/ */
@ -487,11 +495,12 @@ ChkProcCall(expp)
register struct paramlist *param; register struct paramlist *param;
left = expp->nd_left; left = expp->nd_left;
arg = expp;
expp->nd_type = RemoveEqual(ResultType(left->nd_type)); expp->nd_type = RemoveEqual(ResultType(left->nd_type));
/* Check parameter list
*/
for (param = ParamList(left->nd_type); param; param = param->next) { for (param = ParamList(left->nd_type); param; param = param->next) {
if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0; if (!(left = getarg(&expp, 0, IsVarParam(param)))) return 0;
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
TryToString(left, TypeOfParam(param)); TryToString(left, TypeOfParam(param));
} }
@ -504,8 +513,8 @@ node_error(left, "type incompatibility in parameter");
} }
} }
if (arg->nd_right) { if (expp->nd_right) {
node_error(arg->nd_right, "too many parameters supplied"); node_error(expp->nd_right, "too many parameters supplied");
return 0; return 0;
} }
@ -517,7 +526,7 @@ ChkCall(expp)
register struct node *expp; register struct node *expp;
{ {
/* Check something that looks like a procedure or function call. /* Check something that looks like a procedure or function call.
Of course this does not have to be a call at all. Of course this does not have to be a call at all,
it may also be a cast or a standard procedure call. it may also be a cast or a standard procedure call.
*/ */
register struct node *left; register struct node *left;
@ -531,14 +540,14 @@ ChkCall(expp)
if (! ChkDesignator(left)) return 0; if (! ChkDesignator(left)) return 0;
if (IsCast(left)) { if (IsCast(left)) {
/* It was a type cast. This is of course not portable. /* It was a type cast.
*/ */
return ChkCast(expp, left); return ChkCast(expp, left);
} }
if (IsProcCall(left)) { if (IsProcCall(left)) {
/* A procedure call. it may also be a call to a /* A procedure call.
standard procedure It may also be a call to a standard procedure
*/ */
if (left->nd_type == std_type) { if (left->nd_type == std_type) {
/* A standard procedure /* A standard procedure
@ -559,6 +568,10 @@ STATIC struct type *
ResultOfOperation(operator, tp) ResultOfOperation(operator, tp)
struct type *tp; struct type *tp;
{ {
/* Return the result type of the binary operation "operator",
with operand type "tp".
*/
switch(operator) { switch(operator) {
case '=': case '=':
case '#': case '#':
@ -582,6 +595,10 @@ Boolean(operator)
STATIC int STATIC int
AllowedTypes(operator) AllowedTypes(operator)
{ {
/* Return a bit mask indicating the allowed operand types
for binary operator "operator".
*/
switch(operator) { switch(operator) {
case '+': case '+':
case '-': case '-':
@ -615,13 +632,17 @@ STATIC int
ChkAddress(tpl, tpr) ChkAddress(tpl, tpr)
register struct type *tpl, *tpr; register struct type *tpl, *tpr;
{ {
/* Check that either "tpl" or "tpr" are both of type
address_type, or that one of them is, but the other is
of type cardinal.
*/
if (tpl == address_type) { if (tpl == address_type) {
return tpr == address_type || tpr->tp_fund != T_POINTER; return tpr == address_type || (tpr->tp_fund & T_CARDINAL);
} }
if (tpr == address_type) { if (tpr == address_type) {
return tpl->tp_fund != T_POINTER; return (tpl->tp_fund & T_CARDINAL);
} }
return 0; return 0;
@ -656,21 +677,26 @@ ChkBinOper(expp)
} }
} }
expp->nd_type = ResultOfOperation(expp->nd_symb, tpl); expp->nd_type = ResultOfOperation(expp->nd_symb, tpr);
/* Check that the application of the operator is allowed on the type
of the operands.
There are three tricky parts:
- Boolean operators are only allowed on boolean operands, but
the "allowed-mask" of "AllowedTypes" can only indicate
an enumeration type.
- All operations that are allowed on CARDINALS are also allowed
on ADDRESS.
- The IN-operator has as right-hand-size operand a set.
*/
if (expp->nd_symb == IN) { if (expp->nd_symb == IN) {
/* Handle this one specially */
if (tpr->tp_fund != T_SET) {
node_error(expp, "RHS of IN operator not a SET type");
return 0;
}
if (!TstAssCompat(tpl, ElementType(tpr))) { if (!TstAssCompat(tpl, ElementType(tpr))) {
/* Assignment compatible ??? /* Assignment compatible ???
I don't know! Should we be allowed to check I don't know! Should we be allowed to check
if a CARDINAL is a member of a BITSET??? if a CARDINAL is a member of a BITSET???
*/ */
node_error(expp, "IN operator: type of LHS not compatible with element type of RHS"); node_error(expp, "incompatible types for operator \"IN\"");
return 0; return 0;
} }
if (left->nd_class == Value && right->nd_class == Set) { if (left->nd_class == Value && right->nd_class == Set) {
@ -679,6 +705,25 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
return 1; return 1;
} }
allowed = AllowedTypes(expp->nd_symb);
if (!(tpr->tp_fund & allowed) || !(tpl->tp_fund & allowed)) {
if (!((T_CARDINAL & allowed) &&
ChkAddress(tpl, tpr))) {
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
return 0;
}
if (expp->nd_type->tp_fund & T_CARDINAL) {
expp->nd_type = address_type;
}
}
if (Boolean(expp->nd_symb) && tpl != bool_type) {
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
return 0;
}
/* Operands must be compatible (distilled from Def 8.2) /* Operands must be compatible (distilled from Def 8.2)
*/ */
if (!TstCompat(tpl, tpr)) { if (!TstCompat(tpl, tpr)) {
@ -687,32 +732,6 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
return 0; return 0;
} }
allowed = AllowedTypes(expp->nd_symb);
/* Check that the application of the operator is allowed on the type
of the operands.
There are two tricky parts:
- Boolean operators are only allowed on boolean operands, but
the "allowed-mask" of "AllowedTypes" can only indicate
an enumeration type.
- All operations that are allowed on CARDINALS are also allowed
on ADDRESS.
*/
if (Boolean(expp->nd_symb) && tpl != bool_type) {
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
return 0;
}
if (!(tpl->tp_fund & allowed)) {
if (!(tpl->tp_fund == T_POINTER &&
(T_CARDINAL & allowed) &&
ChkAddress(tpl, tpr))) {
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
return 0;
}
if (expp->nd_type == card_type) expp->nd_type = address_type;
}
if (tpl->tp_fund == T_SET) { if (tpl->tp_fund == T_SET) {
if (left->nd_class == Set && right->nd_class == Set) { if (left->nd_class == Set && right->nd_class == Set) {
cstset(expp); cstset(expp);
@ -737,9 +756,8 @@ ChkUnOper(expp)
if (! ChkExpression(right)) return 0; if (! ChkExpression(right)) return 0;
tpr = BaseType(right->nd_type); expp->nd_type = tpr = BaseType(right->nd_type);
if (tpr == address_type) tpr = card_type; if (tpr == address_type) tpr = card_type;
expp->nd_type = tpr;
switch(expp->nd_symb) { switch(expp->nd_symb) {
case '+': case '+':
@ -799,6 +817,9 @@ STATIC struct node *
getvariable(argp) getvariable(argp)
struct node **argp; struct node **argp;
{ {
/* Get the next argument from argument list "argp".
It must obey the rules of "ChkVariable".
*/
register struct node *arg = *argp; register struct node *arg = *argp;
arg = arg->nd_right; arg = arg->nd_right;
@ -807,10 +828,11 @@ getvariable(argp)
return 0; return 0;
} }
if (! ChkVariable(arg->nd_left)) return 0;
*argp = arg; *argp = arg;
return arg->nd_left; arg = arg->nd_left;
if (! ChkVariable(arg)) return 0;
return arg;
} }
STATIC int STATIC int
@ -1104,7 +1126,11 @@ done_before(expp)
extern int NodeCrash(); extern int NodeCrash();
int (*ExprChkTable[])() = { int (*ExprChkTable[])() = {
#ifdef DEBUG
ChkValue, ChkValue,
#else
done_before,
#endif
ChkArr, ChkArr,
ChkBinOper, ChkBinOper,
ChkUnOper, ChkUnOper,
@ -1120,7 +1146,11 @@ int (*ExprChkTable[])() = {
}; };
int (*DesigChkTable[])() = { int (*DesigChkTable[])() = {
#ifdef DEBUG
ChkValue, ChkValue,
#else
done_before,
#endif
ChkArr, ChkArr,
no_desig, no_desig,
no_desig, no_desig,

View file

@ -1,7 +1,5 @@
/* E X P R E S S I O N C H E C K I N G */ /* E X P R E S S I O N C H E C K I N G */
/* $Header$ */
extern int (*ExprChkTable[])(); /* table of expression checking extern int (*ExprChkTable[])(); /* table of expression checking
functions, indexed by node class functions, indexed by node class
*/ */

View file

@ -1,7 +1,5 @@
/* U S E O F C H A R A C T E R C L A S S E S */ /* U S E O F C H A R A C T E R C L A S S E S */
/* $Header$ */
/* As a starter, chars are divided into classes, according to which /* As a starter, chars are divided into classes, according to which
token they can be the start of. token they can be the start of.
At present such a class number is supposed to fit in 4 bits. At present such a class number is supposed to fit in 4 bits.

View file

@ -1,9 +1,5 @@
/* C O D E G E N E R A T I O N R O U T I N E S */ /* C O D E G E N E R A T I O N R O U T I N E S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Code generation for expressions and coercions /* Code generation for expressions and coercions
*/ */
@ -34,7 +30,6 @@ CodeConst(cst, size)
{ {
/* Generate code to push constant "cst" with size "size" /* Generate code to push constant "cst" with size "size"
*/ */
label dlab;
if (size <= word_size) { if (size <= word_size) {
C_loc(cst); C_loc(cst);
@ -43,23 +38,28 @@ CodeConst(cst, size)
C_ldc(cst); C_ldc(cst);
} }
else { else {
C_df_dlb(dlab = ++data_label); crash("(CodeConst)");
/*
label dlab = ++data_label;
C_df_dlb(dlab);
C_rom_icon(long2str((long) cst), size); C_rom_icon(long2str((long) cst), size);
C_lae_dlb(dlab, (arith) 0); C_lae_dlb(dlab, (arith) 0);
C_loi(size); C_loi(size);
*/
} }
} }
CodeString(nd) CodeString(nd)
register struct node *nd; register struct node *nd;
{ {
label lab;
if (nd->nd_type->tp_fund != T_STRING) { if (nd->nd_type->tp_fund != T_STRING) {
C_loc(nd->nd_INT); C_loc(nd->nd_INT);
} }
else { else {
C_df_dlb(lab = ++data_label); label lab = ++data_label;
C_df_dlb(lab);
C_rom_scon(nd->nd_STR, WA(nd->nd_SLE + 1)); C_rom_scon(nd->nd_STR, WA(nd->nd_SLE + 1));
C_lae_dlb(lab, (arith) 0); C_lae_dlb(lab, (arith) 0);
} }
@ -85,16 +85,6 @@ CodePadString(nd, sz)
C_loi(sizearg); C_loi(sizearg);
} }
CodeReal(nd)
register struct node *nd;
{
label lab = ++data_label;
C_df_dlb(lab);
C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
C_lae_dlb(lab, (arith) 0);
C_loi(nd->nd_type->tp_size);
}
CodeExpr(nd, ds, true_label, false_label) CodeExpr(nd, ds, true_label, false_label)
register struct node *nd; register struct node *nd;
@ -136,8 +126,14 @@ CodeExpr(nd, ds, true_label, false_label)
case Value: case Value:
switch(nd->nd_symb) { switch(nd->nd_symb) {
case REAL: case REAL: {
CodeReal(nd); label lab = ++data_label;
C_df_dlb(lab);
C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
C_lae_dlb(lab, (arith) 0);
C_loi(nd->nd_type->tp_size);
}
break; break;
case STRING: case STRING:
CodeString(nd); CodeString(nd);
@ -157,8 +153,8 @@ CodeExpr(nd, ds, true_label, false_label)
break; break;
case Set: { case Set: {
arith *st; register arith *st = nd->nd_set;
int i; register int i;
st = nd->nd_set; st = nd->nd_set;
ds->dsg_kind = DSG_LOADED; ds->dsg_kind = DSG_LOADED;
@ -182,6 +178,8 @@ CodeExpr(nd, ds, true_label, false_label)
} }
if (true_label != 0) { if (true_label != 0) {
/* Only for boolean expressions
*/
CodeValue(ds, tp->tp_size); CodeValue(ds, tp->tp_size);
*ds = InitDesig; *ds = InitDesig;
C_zne(true_label); C_zne(true_label);
@ -293,6 +291,7 @@ CodeCall(nd)
and result is already done. and result is already done.
*/ */
register struct node *left = nd->nd_left; register struct node *left = nd->nd_left;
register struct node *right = nd->nd_right;
register struct type *result_tp; register struct type *result_tp;
if (left->nd_type == std_type) { if (left->nd_type == std_type) {
@ -303,16 +302,16 @@ CodeCall(nd)
if (IsCast(left)) { if (IsCast(left)) {
/* it was just a cast. Simply ignore it /* it was just a cast. Simply ignore it
*/ */
CodePExpr(nd->nd_right->nd_left); CodePExpr(right->nd_left);
*nd = *(nd->nd_right->nd_left); *nd = *(right->nd_left);
nd->nd_type = left->nd_def->df_type; nd->nd_type = left->nd_def->df_type;
return; return;
} }
assert(IsProcCall(left)); assert(IsProcCall(left));
if (nd->nd_right) { if (right) {
CodeParameters(ParamList(left->nd_type), nd->nd_right); CodeParameters(ParamList(left->nd_type), right);
} }
switch(left->nd_class) { switch(left->nd_class) {
@ -387,11 +386,9 @@ CodeParameters(param, arg)
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 { else {
tp = IndexType(left_type); arith lb, ub;
if (tp->tp_fund == T_SUBRANGE) { getbounds(IndexType(left_type), &lb, &ub);
C_loc(tp->sub_ub - tp->sub_lb); C_loc(ub - lb);
}
else C_loc((arith) (tp->enm_ncst - 1));
} }
C_loc((arith) 0); C_loc((arith) 0);
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
@ -417,7 +414,7 @@ CodeStd(nd)
register struct node *arg = nd->nd_right; register struct node *arg = nd->nd_right;
register struct node *left = 0; register struct node *left = 0;
register struct type *tp = 0; register struct type *tp = 0;
int std; int std = nd->nd_left->nd_def->df_value.df_stdname;
if (arg) { if (arg) {
left = arg->nd_left; left = arg->nd_left;
@ -425,7 +422,7 @@ CodeStd(nd)
arg = arg->nd_right; arg = arg->nd_right;
} }
switch(std = nd->nd_left->nd_def->df_value.df_stdname) { switch(std) {
case S_ABS: case S_ABS:
CodePExpr(left); CodePExpr(left);
if (tp->tp_fund == T_INTEGER) { if (tp->tp_fund == T_INTEGER) {
@ -446,7 +443,7 @@ CodeStd(nd)
case S_CAP: case S_CAP:
CodePExpr(left); CodePExpr(left);
C_loc((arith) 0137); C_loc((arith) 0137); /* ASCII assumed */
C_and(word_size); C_and(word_size);
break; break;
@ -498,34 +495,25 @@ CodeStd(nd)
break; break;
case S_DEC: case S_DEC:
case S_INC: case S_INC: {
register arith size = tp->tp_size;
if (size < word_size) size = word_size;
CodePExpr(left); CodePExpr(left);
if (arg) CodePExpr(arg->nd_left); if (arg) CodePExpr(arg->nd_left);
else C_loc((arith) 1); else C_loc((arith) 1);
if (tp->tp_size <= word_size) { if (std == S_DEC) {
if (std == S_DEC) { if (tp->tp_fund == T_INTEGER) C_sbi(size);
if (tp->tp_fund == T_INTEGER) C_sbi(word_size); else C_sbu(size);
else C_sbu(word_size);
}
else {
if (tp->tp_fund == T_INTEGER) C_adi(word_size);
else C_adu(word_size);
}
RangeCheck(tp, int_type);
} }
else { else {
CodeCoercion(int_type, tp); if (tp->tp_fund == T_INTEGER) C_adi(size);
if (std == S_DEC) { else C_adu(size);
if (tp->tp_fund==T_INTEGER) C_sbi(tp->tp_size);
else C_sbu(tp->tp_size);
}
else {
if (tp->tp_fund==T_INTEGER) C_adi(tp->tp_size);
else C_adu(tp->tp_size);
}
} }
if (size == word_size) RangeCheck(tp, int_type);
CodeDStore(left); CodeDStore(left);
break; break;
}
case S_HALT: case S_HALT:
C_cal("_halt"); C_cal("_halt");
@ -552,29 +540,30 @@ CodeStd(nd)
} }
CodeAssign(nd, dss, dst) CodeAssign(nd, dss, dst)
struct node *nd; register struct node *nd;
struct desig *dst, *dss; struct desig *dst, *dss;
{ {
/* Generate code for an assignment. Testing of type /* Generate code for an assignment. Testing of type
compatibility and the like is already done. compatibility and the like is already done.
*/ */
register struct type *tp = nd->nd_right->nd_type; 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 (dss->dsg_kind == DSG_LOADED) {
if (tp->tp_fund == T_STRING) { if (tp->tp_fund == T_STRING) {
CodeAddress(dst); CodeAddress(dst);
C_loc(tp->tp_size); C_loc(tp->tp_size);
C_loc(nd->nd_left->nd_type->tp_size); C_loc(size);
C_cal("_StringAssign"); C_cal("_StringAssign");
C_asp((int_size << 1) + (pointer_size << 1)); C_asp((int_size << 1) + (pointer_size << 1));
return; return;
} }
CodeStore(dst, nd->nd_left->nd_type->tp_size); CodeStore(dst, size);
return; return;
} }
CodeAddress(dss); CodeAddress(dss);
CodeAddress(dst); CodeAddress(dst);
C_blm(nd->nd_left->nd_type->tp_size); C_blm(size);
} }
RangeCheck(tpl, tpr) RangeCheck(tpl, tpr)
@ -593,7 +582,10 @@ RangeCheck(tpl, tpr)
} }
else { else {
/* both types are restricted. check the bounds /* both types are restricted. check the bounds
to see wether we need a range check to see wether we need a range check.
We don't need one if the range of values of the
right hand side is a subset of the range of values
of the left hand side.
*/ */
getbounds(tpl, &llo, &lhi); getbounds(tpl, &llo, &lhi);
getbounds(tpr, &rlo, &rhi); getbounds(tpr, &rlo, &rhi);
@ -806,6 +798,7 @@ CodeOper(expr, true_label, false_label)
C_bra(false_label); C_bra(false_label);
} }
break; break;
case OR:
case AND: case AND:
case '&': { case '&': {
label l_true, l_false, l_maybe = ++text_label, l_end; label l_true, l_false, l_maybe = ++text_label, l_end;
@ -822,7 +815,10 @@ CodeOper(expr, true_label, false_label)
} }
Des = InitDesig; Des = InitDesig;
CodeExpr(leftop, &Des, l_maybe, l_false); if (expr->nd_symb == OR) {
CodeExpr(leftop, &Des, l_true, l_maybe);
}
else 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);
@ -836,34 +832,6 @@ CodeOper(expr, true_label, false_label)
} }
break; break;
} }
case OR: {
label l_true, l_false, l_maybe = ++text_label, l_end;
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;
CodeExpr(leftop, &Des, l_true, l_maybe);
C_df_ilb(l_maybe);
Des = InitDesig;
CodeExpr(rightop, &Des, l_true, l_false);
if (true_label == 0) {
C_df_ilb(l_false);
C_loc((arith)0);
C_bra(l_end);
C_df_ilb(l_true);
C_loc((arith)1);
C_df_ilb(l_end);
}
break;
}
default: default:
crash("(CodeOper) Bad operator %s\n",symbol2str(expr->nd_symb)); crash("(CodeOper) Bad operator %s\n",symbol2str(expr->nd_symb));
} }
@ -958,9 +926,9 @@ CodeUoper(nd)
CodeSet(nd) CodeSet(nd)
register struct node *nd; register struct node *nd;
{ {
struct type *tp = nd->nd_type; register struct type *tp = nd->nd_type;
C_zer(nd->nd_type->tp_size); /* empty set */ C_zer(tp->tp_size); /* empty set */
nd = nd->nd_right; nd = nd->nd_right;
while (nd) { while (nd) {
assert(nd->nd_class == Link && nd->nd_symb == ','); assert(nd->nd_class == Link && nd->nd_symb == ',');

View file

@ -1,7 +1,5 @@
/* C O N S T A N T S F O R E X P R E S S I O N H A N D L I N G */ /* C O N S T A N T S F O R E X P R E S S I O N H A N D L I N G */
/* $Header$ */
extern long extern long
mach_long_sign; /* sign bit of the machine long */ mach_long_sign; /* sign bit of the machine long */
extern int extern int

View file

@ -1,9 +1,5 @@
/* C O N S T A N T E X P R E S S I O N H A N D L I N G */ /* C O N S T A N T E X P R E S S I O N H A N D L I N G */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include "target_sizes.h" #include "target_sizes.h"
@ -35,8 +31,10 @@ cstunary(expp)
register arith o1 = expp->nd_right->nd_INT; register arith o1 = expp->nd_right->nd_INT;
switch(expp->nd_symb) { switch(expp->nd_symb) {
/* Should not get here
case '+': case '+':
break; break;
*/
case '-': case '-':
o1 = -o1; o1 = -o1;
@ -71,7 +69,7 @@ cstbin(expp)
*/ */
register arith o1 = expp->nd_left->nd_INT; register arith o1 = expp->nd_left->nd_INT;
register arith o2 = expp->nd_right->nd_INT; register arith o2 = expp->nd_right->nd_INT;
int uns = expp->nd_type != int_type; register int uns = expp->nd_type != int_type;
assert(expp->nd_class == Oper); assert(expp->nd_class == Oper);
assert(expp->nd_left->nd_class == Value); assert(expp->nd_left->nd_class == Value);

View file

@ -1,10 +1,6 @@
/* D E C L A R A T I O N S */ /* D E C L A R A T I O N S */
{ {
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <em_arith.h> #include <em_arith.h>
@ -23,69 +19,38 @@ static char *RcsId = "$Header$";
#include "chk_expr.h" #include "chk_expr.h"
int proclevel = 0; /* nesting level of procedures */ int proclevel = 0; /* nesting level of procedures */
int return_occurred; /* set if a return occurred in a int return_occurred; /* set if a return occurs in a block */
procedure or function
*/
} }
ProcedureDeclaration ProcedureDeclaration
{ {
register struct def *df; struct def *df;
struct def *df1; /* only exists because &df is illegal */
} : } :
{ ++proclevel; { ++proclevel; }
return_occurred = 0; ProcedureHeading(&df, D_PROCEDURE)
} ';' block(&(df->prc_body))
ProcedureHeading(&df1, D_PROCEDURE) IDENT
{ CurrentScope->sc_definedby = df = df1; { EndProc(df, dot.TOK_IDF);
df->prc_vis = CurrVis;
}
';' block(&(df->prc_body)) IDENT
{ match_id(dot.TOK_IDF, df->df_idf);
close_scope(SC_CHKFORW|SC_REVERSE);
if (! return_occurred && ResultType(df->df_type)) {
error("function procedure %s does not return a value", df->df_idf->id_text);
}
--proclevel; --proclevel;
} }
; ;
ProcedureHeading(struct def **pdf; int type;) ProcedureHeading(struct def **pdf; int type;)
{ {
struct paramlist *params = 0; struct type *tp = 0;
register struct type *tp; #define needs_static_link() (proclevel > 1)
struct type *tp1 = 0; arith parmaddr = needs_static_link() ? pointer_size : 0;
register struct def *df; struct paramlist *pr = 0;
arith NBytesParams; /* parameter offset counter */
} : } :
PROCEDURE IDENT PROCEDURE IDENT
{ df = DeclProc(type); { *pdf = DeclProc(type, dot.TOK_IDF); }
if (proclevel > 1) { /* need room for static link */ FormalParameters(&pr, &parmaddr, &tp)?
NBytesParams = pointer_size; { CheckWithDef(*pdf, proc_type(tp, pr, parmaddr)); }
}
else NBytesParams = 0;
}
FormalParameters(&params, &tp1, &NBytesParams)?
{ tp = construct_type(T_PROCEDURE, tp1);
tp->prc_params = params;
tp->prc_nbpar = NBytesParams;
if (df->df_type) {
/* We already saw a definition of this type
in the definition module.
*/
if (!TstProcEquiv(tp, df->df_type)) {
error("inconsistent procedure declaration for \"%s\"", df->df_idf->id_text);
}
FreeType(df->df_type);
}
df->df_type = tp;
*pdf = df;
}
; ;
block(struct node **pnd;) : block(struct node **pnd;) :
declaration* declaration*
[ [ { return_occurred = 0; }
BEGIN BEGIN
StatementSequence(pnd) StatementSequence(pnd)
| |
@ -106,15 +71,12 @@ declaration:
ModuleDeclaration ';' ModuleDeclaration ';'
; ;
FormalParameters(struct paramlist **pr; FormalParameters(struct paramlist *ppr; arith *parmaddr; struct type **ptp;):
struct type **ptp;
arith *parmaddr;)
:
'(' '('
[ [
FPSection(pr, parmaddr) FPSection(ppr, parmaddr)
[ [
';' FPSection(pr, parmaddr) ';' FPSection(ppr, parmaddr)
]* ]*
]? ]?
')' ')'
@ -134,12 +96,12 @@ FPSection(struct paramlist **ppr; arith *parmaddr;)
FormalType(struct type **ptp;) FormalType(struct type **ptp;)
{ {
register struct type *tp;
extern arith ArrayElSize(); extern arith ArrayElSize();
} : } :
ARRAY OF qualtype(ptp) ARRAY OF qualtype(ptp)
{ tp = construct_type(T_ARRAY, NULLTYPE); { register struct type *tp = construct_type(T_ARRAY, NULLTYPE);
tp->arr_elem = *ptp; *ptp = tp; tp->arr_elem = *ptp;
*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 = lcm(word_align, pointer_align);
} }
@ -194,12 +156,12 @@ SimpleType(struct type **ptp;)
enumeration(struct type **ptp;) enumeration(struct type **ptp;)
{ {
struct node *EnumList; struct node *EnumList;
register struct type *tp;
} : } :
'(' IdentList(&EnumList) ')' '(' IdentList(&EnumList) ')'
{ *ptp = tp = standard_type(T_ENUMERATION, 1, (arith) 1); {
EnterEnumList(EnumList, tp); *ptp = standard_type(T_ENUMERATION, 1, (arith) 1);
if (tp->enm_ncst > 256) { /* ??? is this reasonable ??? */ EnterEnumList(EnumList, *ptp);
if ((*ptp)->enm_ncst > 256) { /* ??? is this reasonable ??? */
error("Too many enumeration literals"); error("Too many enumeration literals");
} }
} }
@ -230,7 +192,10 @@ SubrangeType(struct type **ptp;)
'[' ConstExpression(&nd1) '[' ConstExpression(&nd1)
UPTO ConstExpression(&nd2) UPTO ConstExpression(&nd2)
']' ']'
{ *ptp = subr_type(nd1, nd2); } { *ptp = subr_type(nd1, nd2);
free_node(nd1);
free_node(nd2);
}
; ;
ArrayType(struct type **ptp;) ArrayType(struct type **ptp;)
@ -254,18 +219,18 @@ ArrayType(struct type **ptp;)
RecordType(struct type **ptp;) RecordType(struct type **ptp;)
{ {
register struct scope *scope; register struct scope *scope;
arith count; arith size;
int xalign = struct_align; int xalign = struct_align;
} }
: :
RECORD RECORD
{ open_scope(OPENSCOPE); { open_scope(OPENSCOPE); /* scope for fields of record */
scope = CurrentScope; scope = CurrentScope;
close_scope(0); close_scope(0);
count = 0; size = 0;
} }
FieldListSequence(scope, &count, &xalign) FieldListSequence(scope, &size, &xalign)
{ *ptp = standard_type(T_RECORD, xalign, WA(count)); { *ptp = standard_type(T_RECORD, xalign, WA(size));
(*ptp)->rec_scope = scope; (*ptp)->rec_scope = scope;
} }
END END
@ -281,10 +246,10 @@ FieldListSequence(struct scope *scope; arith *cnt; int *palign;):
FieldList(struct scope *scope; arith *cnt; int *palign;) FieldList(struct scope *scope; arith *cnt; int *palign;)
{ {
struct node *FldList; struct node *FldList;
register struct idf *id = gen_anon_idf(); register struct idf *id = 0;
register struct def *df;
struct type *tp; struct type *tp;
struct node *nd; struct node *nd1;
register struct node *nd;
arith tcnt, max; arith tcnt, max;
} : } :
[ [
@ -294,77 +259,81 @@ FieldList(struct scope *scope; arith *cnt; int *palign;)
} }
| |
CASE CASE
/* Also accept old fashioned Modula-2 syntax, but give a warning /* Also accept old fashioned Modula-2 syntax, but give a warning.
Sorry for the complicated code.
*/ */
[ qualident(0, (struct def **) 0, (char *) 0, &nd) [ qualident(0, (struct def **) 0, (char *) 0, &nd1)
[ ':' qualtype(&tp) { nd = nd1; }
[ ':' qualtype(&tp)
/* This is correct, in both kinds of Modula-2, if /* This is correct, in both kinds of Modula-2, if
the first qualident is a single identifier. the first qualident is a single identifier.
*/ */
{ if (nd->nd_class != Name) { { if (nd->nd_class != Name) {
error("illegal variant tag"); error("illegal variant tag");
} }
else id = nd->nd_IDF; else id = nd->nd_IDF;
} FreeNode(nd);
| }
/* Old fashioned! the first qualident now represents | /* Old fashioned! the first qualident now represents
the type the type
*/ */
{ warning("Old fashioned Modula-2 syntax!"); { warning("Old fashioned Modula-2 syntax; ':' missing");
if (ChkDesignator(nd) && if (ChkDesignator(nd) &&
(nd->nd_class != Def || (nd->nd_class != Def ||
!(nd->nd_def->df_kind&(D_ERROR|D_ISTYPE)) || !(nd->nd_def->df_kind&(D_ERROR|D_ISTYPE)) ||
!nd->nd_def->df_type)) { !nd->nd_def->df_type)) {
node_error(nd, "type expected"); node_error(nd, "type expected");
tp = error_type; tp = error_type;
} }
else tp = nd->nd_def->df_type; else tp = nd->nd_def->df_type;
FreeNode(nd); FreeNode(nd);
} }
] ]
| | ':' qualtype(&tp)
/* Aha, third edition. Well done! */ /* Aha, third edition. Well done! */
':' qualtype(&tp)
] ]
{ if (!(tp->tp_fund & T_DISCRETE)) { { if (id) {
register struct def *df = define(id,
scope,
D_FIELD);
if (!(tp->tp_fund & T_DISCRETE)) {
error("Illegal type in variant"); error("Illegal type in variant");
} }
df = define(id, scope, D_FIELD); df->df_type = tp;
df->df_type = tp; df->fld_off = align(*cnt, tp->tp_align);
df->fld_off = align(*cnt, tp->tp_align); *cnt = tcnt = df->fld_off + tp->tp_size;
*cnt = tcnt = df->fld_off + tp->tp_size; df->df_flags |= D_QEXPORTED;
df->df_flags |= D_QEXPORTED; }
} }
OF variant(scope, &tcnt, tp, palign) OF variant(scope, &tcnt, tp, palign)
{ max = tcnt; tcnt = *cnt; } { max = tcnt; tcnt = *cnt; }
[ [
'|' variant(scope, &tcnt, tp, palign) '|' variant(scope, &tcnt, tp, palign)
{ if (tcnt > max) max = tcnt; tcnt = *cnt; } { if (tcnt > max) max = tcnt; tcnt = *cnt; }
]* ]*
[ ELSE FieldListSequence(scope, &tcnt, palign) [ ELSE FieldListSequence(scope, &tcnt, palign)
{ if (tcnt > max) max = tcnt; } { if (tcnt > max) max = tcnt; }
]? ]?
END END
{ *cnt = max; } { *cnt = max; }
]? ]?
; ;
variant(struct scope *scope; arith *cnt; struct type *tp; int *palign;) variant(struct scope *scope; arith *cnt; struct type *tp; int *palign;)
{ {
struct type *tp1 = tp;
struct node *nd; struct node *nd;
} : } :
[ [
CaseLabelList(&tp1, &nd) CaseLabelList(&tp, &nd)
{ /* Ignore the cases for the time being. { /* Ignore the cases for the time being.
Maybe a checking version will be supplied Maybe a checking version will be supplied
later ??? later ??? (Improbable)
*/ */
FreeNode(nd); FreeNode(nd);
} }
':' FieldListSequence(scope, cnt, palign) ':' FieldListSequence(scope, cnt, palign)
]? ]?
/* Changed rule in new modula-2 */ /* Changed rule in new modula-2 */
; ;
CaseLabelList(struct type **ptp; struct node **pnd;): CaseLabelList(struct type **ptp; struct node **pnd;):
@ -376,27 +345,29 @@ CaseLabelList(struct type **ptp; struct node **pnd;):
]* ]*
; ;
CaseLabels(struct type **ptp; struct node **pnd;) CaseLabels(struct type **ptp; register struct node **pnd;)
{ {
struct node *nd1, *nd2 = 0; register struct node *nd1;
}: }:
ConstExpression(&nd1) { *pnd = nd1; } ConstExpression(pnd)
{ nd1 = *pnd; }
[ [
UPTO { *pnd = MkNode(Link,nd1,NULLNODE,&dot); } UPTO { *pnd = MkNode(Link,nd1,NULLNODE,&dot); }
ConstExpression(&nd2) ConstExpression(&(*pnd)->nd_right)
{ if (!TstCompat(nd1->nd_type, nd2->nd_type)) { { if (!TstCompat(nd1->nd_type,
node_error(nd2,"type incompatibility in case label"); (*pnd)->nd_right->nd_type)) {
nd1->nd_type = error_type; node_error((*pnd)->nd_right,
} "type incompatibility in case label");
(*pnd)->nd_right = nd2; nd1->nd_type = error_type;
} }
}
]? ]?
{ if (*ptp != 0 && { if (*ptp != 0 && !TstCompat(*ptp, nd1->nd_type)) {
!TstCompat(*ptp, nd1->nd_type)) { node_error(nd1,
node_error(nd1,"type incompatibility in case label"); "type incompatibility in case label");
} }
*ptp = nd1->nd_type; *ptp = nd1->nd_type;
} }
; ;
SetType(struct type **ptp;) : SetType(struct type **ptp;) :
@ -410,7 +381,7 @@ SetType(struct type **ptp;) :
*/ */
PointerType(struct type **ptp;) PointerType(struct type **ptp;)
{ {
register struct node *nd; register struct node *nd = 0;
} : } :
POINTER TO POINTER TO
{ *ptp = construct_type(T_POINTER, NULLTYPE); } { *ptp = construct_type(T_POINTER, NULLTYPE); }
@ -418,49 +389,51 @@ PointerType(struct type **ptp;)
/* Either a Module or a Type, but in both cases defined /* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification in this scope, so this is the correct identification
*/ */
qualtype(&((*ptp)->next)) qualtype(&((*ptp)->next))
| %if ( nd = new_node(), nd->nd_token = dot, | %if ( nd = new_node(),
nd->nd_token = dot,
lookfor(nd, CurrVis, 0)->df_kind == D_MODULE) lookfor(nd, CurrVis, 0)->df_kind == D_MODULE)
{ if (dot.tk_symb == IDENT) free_node(nd); } type(&((*ptp)->next))
type(&((*ptp)->next)) { if (nd) free_node(nd); }
| |
IDENT { Forward(nd, (*ptp)); } IDENT { Forward(nd, (*ptp)); }
] ]
; ;
qualtype(struct type **ptp;) qualtype(struct type **ptp;)
{ {
struct def *df; struct def *df = 0;
} : } :
qualident(D_ISTYPE, &df, "type", (struct node **) 0) qualident(D_ISTYPE, &df, "type", (struct node **) 0)
{ if (!(*ptp = df->df_type)) { { if (df && !(*ptp = df->df_type)) {
error("type \"%s\" not declared", df->df_idf->id_text); error("type \"%s\" not declared",
*ptp = error_type; df->df_idf->id_text);
} *ptp = error_type;
} }
}
; ;
ProcedureType(struct type **ptp;) ProcedureType(struct type **ptp;)
{ {
struct paramlist *pr = 0; struct paramlist *pr = 0;
register struct type *tp; arith parmaddr = 0;
arith nbytes = 0; }
} : :
{ *ptp = 0; } { *ptp = 0; }
PROCEDURE FormalTypeList(&pr, ptp, &nbytes)? PROCEDURE
{ *ptp = tp = construct_type(T_PROCEDURE, *ptp); [
tp->prc_params = pr; FormalTypeList(&pr, &parmaddr, ptp)
tp->prc_nbpar = nbytes; ]?
} { *ptp = proc_type(*ptp, pr, parmaddr); }
; ;
FormalTypeList(struct paramlist **ppr; struct type **ptp; arith *parmaddr;) FormalTypeList(struct paramlist **ppr; arith *parmaddr; struct type **ptp;)
{ {
int VARp;
struct type *tp; struct type *tp;
int VARp;
} : } :
'(' { *ppr = 0; } '('
[ [
var(&VARp) FormalType(&tp) var(&VARp) FormalType(&tp)
{ EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); } { EnterParamList(ppr,NULLNODE,tp,VARp,parmaddr); }

View file

@ -1,7 +1,5 @@
/* I D E N T I F I E R D E S C R I P T O R S T R U C T U R E */ /* I D E N T I F I E R D E S C R I P T O R S T R U C T U R E */
/* $Header$ */
struct module { struct module {
arith mo_priority; /* priority of a module */ arith mo_priority; /* priority of a module */
struct scopelist *mo_vis;/* scope of this module */ struct scopelist *mo_vis;/* scope of this module */
@ -82,12 +80,12 @@ struct def { /* list of definitions for a name */
#define D_IMPORT 0x0080 /* an imported definition */ #define D_IMPORT 0x0080 /* an imported definition */
#define D_PROCHEAD 0x0100 /* a procedure heading in a definition module */ #define D_PROCHEAD 0x0100 /* a procedure heading in a definition module */
#define D_HIDDEN 0x0200 /* a hidden type */ #define D_HIDDEN 0x0200 /* a hidden type */
#define D_FORWARD 0x0800 /* not yet defined */ #define D_FORWARD 0x0400 /* not yet defined */
#define D_UNDEF_IMPORT 0x1000 /* imported from an undefined name */ #define D_FORWMODULE 0x0800 /* module must be declared later */
#define D_FORWMODULE 0x2000 /* module must be declared later */ #define D_ERROR 0x1000 /* a compiler generated definition for an
#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_ISTYPE (D_HIDDEN|D_TYPE) #define D_ISTYPE (D_HIDDEN|D_TYPE)
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE) #define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
char df_flags; char df_flags;
@ -115,14 +113,13 @@ struct def { /* list of definitions for a name */
#define SetUsed(df) ((df)->df_flags |= D_USED) #define SetUsed(df) ((df)->df_flags |= D_USED)
/* ALLOCDEF "def" */ /* ALLOCDEF "def" 50 */
extern struct def extern struct def
*define(), *define(),
*DefineLocalModule(), *DefineLocalModule(),
*MkDef(), *MkDef(),
*DeclProc(), *DeclProc();
*ill_df;
extern struct def extern struct def
*lookup(), *lookup(),

View file

@ -1,9 +1,5 @@
/* D E F I N I T I O N M E C H A N I S M */ /* D E F I N I T I O N M E C H A N I S M */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <alloc.h> #include <alloc.h>
@ -25,11 +21,42 @@ 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
struct def *ill_df; STATIC
DefInFront(df)
register struct def *df;
{
/* Put definition "df" in front of the list of definitions
in its scope.
This is neccessary because in some cases the order in this
list is important.
*/
register struct def *df1 = df->df_scope->sc_def;
if (df1 != df) {
/* Definition "df" is not in front of the list
*/
while (df1) {
/* Find definition "df"
*/
if (df1->df_nextinscope == df) {
/* It already was in the list. Remove it
*/
df1->df_nextinscope = df->df_nextinscope;
break;
}
df1 = df1->df_nextinscope;
}
/* Now put it in front
*/
df->df_nextinscope = df->df_scope->sc_def;
df->df_scope->sc_def = df;
}
}
struct def * struct def *
MkDef(id, scope, kind) MkDef(id, scope, kind)
struct idf *id; register struct idf *id;
register struct scope *scope; register struct scope *scope;
{ {
/* Create a new definition structure in scope "scope", with /* Create a new definition structure in scope "scope", with
@ -38,7 +65,6 @@ MkDef(id, scope, kind)
register struct def *df; register struct def *df;
df = new_def(); df = new_def();
clear((char *) df, sizeof (*df));
df->df_idf = id; df->df_idf = id;
df->df_scope = scope; df->df_scope = scope;
df->df_kind = kind; df->df_kind = kind;
@ -52,24 +78,16 @@ MkDef(id, scope, kind)
return df; return df;
} }
InitDef()
{
/* Initialize this module. Easy, the only thing to be initialized
is "ill_df".
*/
struct idf *gen_anon_idf();
ill_df = MkDef(gen_anon_idf(), CurrentScope, D_ERROR);
ill_df->df_type = error_type;
}
struct def * struct def *
define(id, scope, kind) define(id, scope, kind)
register struct idf *id; register struct idf *id;
register struct scope *scope; register struct scope *scope;
int kind;
{ {
/* Declare an identifier in a scope, but first check if it /* Declare an identifier in a scope, but first check if it
already has been defined. If so, error message. already has been defined.
If so, then check for the cases in which this is legal,
and otherwise give an error message.
*/ */
register struct def *df; register struct def *df;
@ -133,7 +151,8 @@ define(id, scope, kind)
if (kind != D_ERROR) { if (kind != D_ERROR) {
/* Avoid spurious error messages /* Avoid spurious error messages
*/ */
error("identifier \"%s\" already declared", id->id_text); error("identifier \"%s\" already declared",
id->id_text);
} }
return df; return df;
@ -143,7 +162,7 @@ error("identifier \"%s\" already declared", id->id_text);
} }
RemoveImports(pdf) RemoveImports(pdf)
struct def **pdf; register struct def **pdf;
{ {
/* Remove all imports from a definition module. This is /* Remove all imports from a definition module. This is
neccesary because the implementation module might import neccesary because the implementation module might import
@ -165,16 +184,15 @@ RemoveImports(pdf)
} }
RemoveFromIdList(df) RemoveFromIdList(df)
struct def *df; register struct def *df;
{ {
/* Remove definition "df" from the definition list /* Remove definition "df" from the definition list
*/ */
register struct idf *id = df->df_idf; register struct idf *id = df->df_idf;
register struct def *df1; register struct def *df1;
if (id->id_def == df) id->id_def = df->next; if ((df1 = id->id_def) == df) id->id_def = df->next;
else { else {
df1 = id->id_def;
while (df1->next != df) { while (df1->next != df) {
assert(df1->next != 0); assert(df1->next != 0);
df1 = df1->next; df1 = df1->next;
@ -184,13 +202,15 @@ RemoveFromIdList(df)
} }
struct def * struct def *
DeclProc(type) DeclProc(type, id)
register struct idf *id;
{ {
/* A procedure is declared, either in a definition or a program /* A procedure is declared, either in a definition or a program
module. Create a def structure for it (if neccessary). module. Create a def structure for it (if neccessary).
Also create a name for it. Also create a name for it.
*/ */
register struct def *df; register struct def *df;
register struct scope *scope;
extern char *sprint(); extern char *sprint();
static int nmcount; static int nmcount;
char buf[256]; char buf[256];
@ -200,85 +220,61 @@ DeclProc(type)
if (type == D_PROCHEAD) { if (type == D_PROCHEAD) {
/* In a definition module /* In a definition module
*/ */
df = define(dot.TOK_IDF, CurrentScope, type); df = define(id, CurrentScope, type);
df->for_node = MkLeaf(Name, &dot); df->for_node = MkLeaf(Name, &dot);
sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text); sprint(buf,"%s_%s",CurrentScope->sc_name,id->id_text);
df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1)); df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1));
if (CurrVis == Defined->mod_vis) C_exp(df->for_name); if (CurrVis == Defined->mod_vis) {
/* The current module will define this routine.
make sure the name is exported.
*/
C_exp(df->for_name);
}
} }
else { else {
df = lookup(dot.TOK_IDF, CurrentScope); char *name;
df = lookup(id, CurrentScope);
if (df && df->df_kind == D_PROCHEAD) { if (df && df->df_kind == D_PROCHEAD) {
/* C_exp already generated when we saw the definition /* C_exp already generated when we saw the definition
in the definition module in the definition module
*/ */
df->df_kind = D_PROCEDURE; df->df_kind = D_PROCEDURE;
open_scope(OPENSCOPE); name = df->for_name;
CurrentScope->sc_name = df->for_name;
df->prc_vis = CurrVis;
DefInFront(df); DefInFront(df);
} }
else { else {
df = define(dot.TOK_IDF, CurrentScope, type); df = define(id, CurrentScope, type);
open_scope(OPENSCOPE); sprint(buf,"_%d_%s",++nmcount,id->id_text);
df->prc_vis = CurrVis; name = Salloc(buf, (unsigned)(strlen(buf)+1));
sprint(buf,"_%d_%s",++nmcount,df->df_idf->id_text);
CurrentScope->sc_name =
Salloc(buf, (unsigned)(strlen(buf)+1));
C_inp(buf); C_inp(buf);
} }
open_scope(OPENSCOPE);
scope = CurrentScope;
scope->sc_name = name;
scope->sc_definedby = df;
df->prc_vis = CurrVis;
} }
return df; return df;
} }
AddModule(id) EndProc(df, id)
register struct def *df;
struct idf *id; struct idf *id;
{ {
/* Add the name of a module to the Module list. This list is /* The end of a procedure declaration.
maintained to create the initialization routine of the Check that the closing identifier matches the name of the
program/implementation module currently defined. procedure, close the scope, and check that a function
procedure has at least one RETURN statement.
*/ */
static struct node *nd_end; /* to remember end of list */ extern int return_occurred;
register struct node *n;
extern struct node *Modules;
n = MkLeaf(Name, &dot); match_id(id, df->df_idf);
n->nd_IDF = id; close_scope(SC_CHKFORW|SC_REVERSE);
n->nd_symb = IDENT; if (! return_occurred && ResultType(df->df_type)) {
if (nd_end) nd_end->next = n; error("function procedure %s does not return a value",
else Modules = n; df->df_idf->id_text);
nd_end = n;
}
DefInFront(df)
register struct def *df;
{
/* Put definition "df" in front of the list of definitions
in its scope.
This is neccessary because in some cases the order in this
list is important.
*/
register struct def *df1 = df->df_scope->sc_def;
if (df1 != df) {
/* Definition "df" is not in front of the list
*/
while (df1 && df1->df_nextinscope != df) {
/* Find definition "df"
*/
df1 = df1->df_nextinscope;
}
if (df1) {
/* It already was in the list. Remove it
*/
df1->df_nextinscope = df->df_nextinscope;
}
/* Now put it in front
*/
df->df_nextinscope = df->df_scope->sc_def;
df->df_scope->sc_def = df;
} }
} }
@ -326,6 +322,27 @@ DefineLocalModule(id)
return df; return df;
} }
CheckWithDef(df, tp)
register struct def *df;
struct type *tp;
{
/* Check the header of a procedure declaration against a
possible earlier definition in the definition module.
*/
if (df->df_type) {
/* We already saw a definition of this type
in the definition module.
*/
if (!TstProcEquiv(tp, df->df_type)) {
error("inconsistent procedure declaration for \"%s\"",
df->df_idf->id_text);
}
FreeType(df->df_type);
}
df->df_type = tp;
}
#ifdef DEBUG #ifdef DEBUG
PrDef(df) PrDef(df)
register struct def *df; register struct def *df;

View file

@ -1,9 +1,5 @@
/* D E F I N I T I O N M O D U L E S */ /* D E F I N I T I O N M O D U L E S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -15,23 +11,27 @@ static char *RcsId = "$Header$";
#include "scope.h" #include "scope.h"
#include "def.h" #include "def.h"
#include "LLlex.h" #include "LLlex.h"
#include "Lpars.h"
#include "f_info.h" #include "f_info.h"
#include "main.h" #include "main.h"
#include "node.h"
#ifdef DEBUG #ifdef DEBUG
long sys_filesize(); long sys_filesize();
#endif #endif
struct idf * CurrentId;
GetFile(name) GetFile(name)
char *name; char *name;
{ {
/* Try to find a file with basename "name" and extension ".def", /* Try to find a file with basename "name" and extension ".def",
in the directories mentioned in "DEFPATH". in the directories mentioned in "DEFPATH".
*/ */
char buf[256]; char buf[15];
char *strcpy(), *strcat(); char *strcpy(), *strcat();
strcpy(buf, name); strncpy(buf, name, 10);
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))) {
@ -42,17 +42,18 @@ GetFile(name)
} }
struct def * struct def *
GetDefinitionModule(id) GetDefinitionModule(id, incr)
struct idf *id; register struct idf *id;
{ {
/* Return a pointer to the "def" structure of the definition /* Return a pointer to the "def" structure of the definition
module indicated by "id". module indicated by "id".
We may have to read the definition module itself. We may have to read the definition module itself.
Also increment level by "incr".
*/ */
struct def *df; struct def *df;
static int level; static int level;
level++; level += incr;
df = lookup(id, GlobalScope); df = lookup(id, GlobalScope);
if (!df) { if (!df) {
/* Read definition module. Make an exception for SYSTEM. /* Read definition module. Make an exception for SYSTEM.
@ -62,6 +63,8 @@ GetDefinitionModule(id)
} }
else { else {
GetFile(id->id_text); GetFile(id->id_text);
CurrentId = id;
open_scope(CLOSEDSCOPE);
DefModule(); DefModule();
if (level == 1) { if (level == 1) {
/* The module is directly imported by the /* The module is directly imported by the
@ -69,12 +72,23 @@ GetDefinitionModule(id)
remember its name because we have to call remember its name because we have to call
its initialization routine its initialization routine
*/ */
AddModule(id); static struct node *nd_end; /* end of list */
register struct node *n;
extern struct node *Modules;
n = MkLeaf(Name, &dot);
n->nd_IDF = id;
n->nd_symb = IDENT;
if (nd_end) nd_end->next = n;
else Modules = n;
nd_end = n;
} }
close_scope(SC_CHKFORW);
} }
df = lookup(id, GlobalScope); df = lookup(id, GlobalScope);
} }
CurrentId = 0;
assert(df && df->df_kind == D_MODULE); assert(df && df->df_kind == D_MODULE);
level--; level -= incr;
return df; return df;
} }

View file

@ -1,9 +1,5 @@
/* D E S I G N A T O R E V A L U A T I O N */ /* D E S I G N A T O R E V A L U A T I O N */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Code generation for designators. /* Code generation for designators.
This file contains some routines that generate code common to address This file contains some routines that generate code common to address
as well as value computations, and leave a description in a "desig" as well as value computations, and leave a description in a "desig"
@ -166,7 +162,6 @@ CodeFieldDesig(df, ds)
in "ds". "df" indicates the definition of the field. in "ds". "df" indicates the definition of the field.
*/ */
if (ds->dsg_kind == DSG_INIT) { if (ds->dsg_kind == DSG_INIT) {
/* In a WITH statement. We must find the designator in the /* In a WITH statement. We must find the designator in the
WITH statement, and act as if the field is a selection WITH statement, and act as if the field is a selection

View file

@ -1,7 +1,5 @@
/* D E S I G N A T O R D E S C R I P T I O N S */ /* D E S I G N A T O R D E S C R I P T I O N S */
/* $Header$ */
/* Generating code for designators is not particularly easy, especially if /* Generating code for designators is not particularly easy, especially if
you don't know wether you want the address or the value. you don't know wether you want the address or the value.
The next structure is used to generate code for designators. The next structure is used to generate code for designators.

View file

@ -1,9 +1,5 @@
/* H I G H L E V E L S Y M B O L E N T R Y */ /* H I G H L E V E L S Y M B O L E N T R Y */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <alloc.h> #include <alloc.h>
@ -119,7 +115,8 @@ EnterVarList(Idlist, type, local)
df->var_addrgiven = 1; df->var_addrgiven = 1;
df->df_flags |= D_NOREG; df->df_flags |= D_NOREG;
if (idlist->nd_left->nd_type != card_type) { if (idlist->nd_left->nd_type != card_type) {
node_error(idlist->nd_left,"Illegal type for address"); node_error(idlist->nd_left,
"Illegal type for address");
} }
df->var_off = idlist->nd_left->nd_INT; df->var_off = idlist->nd_left->nd_INT;
} }
@ -155,8 +152,8 @@ node_error(idlist->nd_left,"Illegal type for address");
} }
EnterParamList(ppr, Idlist, type, VARp, off) EnterParamList(ppr, Idlist, type, VARp, off)
struct node *Idlist;
struct paramlist **ppr; struct paramlist **ppr;
struct node *Idlist;
struct type *type; struct type *type;
int VARp; int VARp;
arith *off; arith *off;
@ -178,18 +175,14 @@ EnterParamList(ppr, Idlist, type, VARp, off)
for ( ; idlist; idlist = idlist->next) { for ( ; idlist; idlist = idlist->next) {
pr = new_paramlist(); pr = new_paramlist();
pr->next = 0; pr->next = 0;
if (!*ppr) { if (!*ppr) *ppr = pr;
*ppr = pr;
}
else last->next = pr; else last->next = pr;
last = pr; last = pr;
if (!DefinitionModule && idlist != dummy) { if (!DefinitionModule && idlist != dummy) {
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE); df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
df->var_off = *off; df->var_off = *off;
} }
else { else df = new_def();
df = new_def();
}
pr->par_def = df; pr->par_def = df;
df->df_type = type; df->df_type = type;
df->df_flags = VARp; df->df_flags = VARp;
@ -259,11 +252,11 @@ ForwModule(df, idn)
enclosing scope, but this must be done AFTER enclosing scope, but this must be done AFTER
closing this one closing this one
*/ */
df->for_vis = vis;
df->for_node = MkLeaf(Name, &(idn->nd_token));
close_scope(0); close_scope(0);
vis->sc_encl = enclosing(CurrVis); vis->sc_encl = enclosing(CurrVis);
/* Here ! */ /* Here ! */
df->for_vis = vis;
df->for_node = MkLeaf(Name, &(idn->nd_token));
return vis; return vis;
} }
@ -294,7 +287,6 @@ EnterExportList(Idlist, qualified)
*/ */
register struct node *idlist = Idlist; register struct node *idlist = Idlist;
register struct def *df, *df1; register struct def *df, *df1;
register struct def *impmod;
for (;idlist; idlist = idlist->next) { for (;idlist; idlist = idlist->next) {
df = lookup(idlist->nd_IDF, CurrentScope); df = lookup(idlist->nd_IDF, CurrentScope);
@ -302,13 +294,16 @@ EnterExportList(Idlist, qualified)
if (!df) { if (!df) {
/* undefined item in export list /* undefined item in export list
*/ */
node_error(idlist, "identifier \"%s\" not defined", idlist->nd_IDF->id_text); node_error(idlist,
"identifier \"%s\" not defined",
idlist->nd_IDF->id_text);
continue; continue;
} }
if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) { if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) {
node_error(idlist, "identifier \"%s\" occurs more than once in export list", node_error(idlist,
idlist->nd_IDF->id_text); "multiple occurrences of \"%s\" in export list",
idlist->nd_IDF->id_text);
} }
df->df_flags |= qualified; df->df_flags |= qualified;
@ -317,13 +312,13 @@ idlist->nd_IDF->id_text);
Find all imports of the module in which this export Find all imports of the module in which this export
occurs, and export the current definition to it occurs, and export the current definition to it
*/ */
impmod = CurrentScope->sc_definedby->df_idf->id_def; df1 = CurrentScope->sc_definedby->df_idf->id_def;
while (impmod) { while (df1) {
if (impmod->df_kind == D_IMPORT && if (df1->df_kind == D_IMPORT &&
impmod->imp_def == CurrentScope->sc_definedby) { df1->imp_def == CurrentScope->sc_definedby) {
DoImport(df, impmod->df_scope); DoImport(df, df1->df_scope);
} }
impmod = impmod->next; df1 = df1->next;
} }
/* Also handle the definition as if the enclosing /* Also handle the definition as if the enclosing
@ -345,7 +340,9 @@ idlist->nd_IDF->id_text);
if (df1->df_kind == D_HIDDEN && if (df1->df_kind == D_HIDDEN &&
df->df_kind == D_TYPE) { df->df_kind == D_TYPE) {
if (df->df_type->tp_fund != T_POINTER) { if (df->df_type->tp_fund != T_POINTER) {
node_error(idlist, "opaque type \"%s\" is not a pointer type", df->df_idf->id_text); node_error(idlist,
"opaque type \"%s\" is not a pointer type",
df->df_idf->id_text);
} }
assert(df1->df_type->next == NULLTYPE); assert(df1->df_type->next == NULLTYPE);
df1->df_kind = D_TYPE; df1->df_kind = D_TYPE;
@ -388,23 +385,23 @@ EnterFromImportList(Idlist, FromDef)
vis = FromDef->mod_vis; vis = FromDef->mod_vis;
break; break;
default: default:
error("identifier \"%s\" does not represent a module", error("identifier \"%s\" does not represent a module",
FromDef->df_idf->id_text); FromDef->df_idf->id_text);
break; break;
} }
for (; idlist; idlist = idlist->next) { for (; idlist; idlist = idlist->next) {
if (forwflag) { if (forwflag) df = ForwDef(idlist, vis->sc_scope);
df = ForwDef(idlist, vis->sc_scope); else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope))) {
} node_error(idlist,
else if (!(df = lookup(idlist->nd_IDF, vis->sc_scope))) { "identifier \"%s\" not declared in qualifying module",
node_error(idlist, "identifier \"%s\" not declared in qualifying module", idlist->nd_IDF->id_text);
idlist->nd_IDF->id_text);
df = define(idlist->nd_IDF,vis->sc_scope,D_ERROR); df = define(idlist->nd_IDF,vis->sc_scope,D_ERROR);
} }
else if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) { else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
node_error(idlist,"identifier \"%s\" not exported from qualifying module", node_error(idlist,
idlist->nd_IDF->id_text); "identifier \"%s\" not exported from qualifying module",
idlist->nd_IDF->id_text);
df->df_flags |= D_QEXPORTED; df->df_flags |= D_QEXPORTED;
} }
DoImport(df, CurrentScope); DoImport(df, CurrentScope);
@ -422,14 +419,14 @@ EnterImportList(Idlist, local)
This case is indicated by the value 0 of the "local" flag. This case is indicated by the value 0 of the "local" flag.
*/ */
register struct node *idlist = Idlist; register struct node *idlist = Idlist;
register struct def *df; struct scope *sc = enclosing(CurrVis)->sc_scope;
struct scopelist *vis = enclosing(CurrVis);
extern struct def *GetDefinitionModule(); extern struct def *GetDefinitionModule();
for (; idlist; idlist = idlist->next) { for (; idlist; idlist = idlist->next) {
if (local) df = ForwDef(idlist, vis->sc_scope); DoImport(local ?
else df = GetDefinitionModule(idlist->nd_IDF); ForwDef(idlist, sc) :
DoImport(df, CurrentScope); GetDefinitionModule(idlist->nd_IDF) ,
CurrentScope);
} }
FreeNode(Idlist); FreeNode(Idlist);
} }

View file

@ -5,10 +5,6 @@
number of arguments! number of arguments!
*/ */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "errout.h" #include "errout.h"
#include "debug.h" #include "debug.h"

View file

@ -1,10 +1,6 @@
/* E X P R E S S I O N S */ /* E X P R E S S I O N S */
{ {
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <alloc.h> #include <alloc.h>
@ -38,22 +34,19 @@ qualident(int types;
struct node **p; struct node **p;
) )
{ {
register struct def *df;
struct node *nd; struct node *nd;
} : } :
IDENT { nd = MkLeaf(Name, &dot); } IDENT { nd = MkLeaf(Name, &dot); }
[ [
selector(&nd) selector(&nd)
]* ]*
{ if (types) { { if (types && ChkDesignator(nd)) {
df = ill_df; if (nd->nd_class != Def) {
if (ChkDesignator(nd)) {
if (nd->nd_class != Def) {
node_error(nd, "%s expected", str); node_error(nd, "%s expected", str);
} }
else { else {
df = nd->nd_def; register struct def *df = nd->nd_def;
if ( !((types|D_ERROR) & df->df_kind)) { if ( !((types|D_ERROR) & df->df_kind)) {
if (df->df_kind == D_FORWARD) { if (df->df_kind == D_FORWARD) {
node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text); node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text);
@ -62,9 +55,8 @@ node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text);
node_error(nd,"identifier \"%s\" is not a %s", df->df_idf->id_text, str); node_error(nd,"identifier \"%s\" is not a %s", df->df_idf->id_text, str);
} }
} }
} if (pdf) *pdf = df;
} }
*pdf = df;
} }
if (!p) FreeNode(nd); if (!p) FreeNode(nd);
else *p = nd; else *p = nd;
@ -170,10 +162,9 @@ MulOperator:
factor(register struct node **p;) factor(register struct node **p;)
{ {
struct def *df;
struct node *nd; struct node *nd;
} : } :
qualident(0, &df, (char *) 0, p) qualident(0, (struct def **) 0, (char *) 0, p)
[ [
designator_tail(p)? designator_tail(p)?
[ [
@ -236,10 +227,8 @@ element(struct node *nd;)
; ;
designator(struct node **pnd;) designator(struct node **pnd;)
{ :
struct def *df; qualident(0, (struct def **) 0, (char *) 0, pnd)
} :
qualident(0, &df, (char *) 0, pnd)
designator_tail(pnd)? designator_tail(pnd)?
; ;

View file

@ -1,7 +1,5 @@
/* F I L E D E S C R I P T O R S T R U C T U R E */ /* F I L E D E S C R I P T O R S T R U C T U R E */
/* $Header$ */
struct f_info { struct f_info {
unsigned short f_lineno; unsigned short f_lineno;
char *f_filename; char *f_filename;

View file

@ -1,6 +1,4 @@
/* I N S T A N T I A T I O N O F I D F P A C K A G E */ /* I N S T A N T I A T I O N O F I D F P A C K A G E */
/* $Header$ */
#include "idf.h" #include "idf.h"
#include <idf_pkg.body> #include <idf_pkg.body>

View file

@ -1,7 +1,5 @@
/* U S E R D E C L A R E D P A R T O F I D F */ /* U S E R D E C L A R E D P A R T O F I D F */
/* $Header$ */
struct id_u { struct id_u {
int id_res; int id_res;
struct def *id_df; struct def *id_df;

View file

@ -1,17 +1,25 @@
/* I N S T A N T I A T I O N O F I N P U T P A C K A G E */ /* I N S T A N T I A T I O N O F I N P U T P A C K A G E */
/* $Header$ */
#include "f_info.h" #include "f_info.h"
struct f_info file_info; struct f_info file_info;
#include "input.h" #include "input.h"
#include <em_arith.h>
#include <em_label.h>
#include "def.h"
#include "idf.h"
#include "scope.h"
#include <inp_pkg.body> #include <inp_pkg.body>
extern struct idf *CurrentId;
AtEoIF() AtEoIF()
{ {
/* Make the unstacking of input streams noticable to the /* Make the unstacking of input streams noticable to the
lexical analyzer lexical analyzer
*/ */
if (CurrentId && ! lookup(CurrentId, GlobalScope)) {
fatal("No definition module read for \"%s\"", CurrentId->id_text);
}
return 1; return 1;
} }

View file

@ -1,7 +1,5 @@
/* I N S T A N T I A T I O N O F I N P U T M O D U L E */ /* I N S T A N T I A T I O N O F I N P U T M O D U L E */
/* $Header$ */
#include "inputtype.h" #include "inputtype.h"
#define INP_NPUSHBACK 2 #define INP_NPUSHBACK 2

View file

@ -1,9 +1,5 @@
/* L O O K U P R O U T I N E S */ /* L O O K U P R O U T I N E S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <em_arith.h> #include <em_arith.h>

View file

@ -1,9 +1,5 @@
/* M A I N P R O G R A M */ /* M A I N P R O G R A M */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include "ndir.h" #include "ndir.h"
@ -26,7 +22,6 @@ static char *RcsId = "$Header$";
int state; /* either IMPLEMENTATION or PROGRAM */ int state; /* either IMPLEMENTATION or PROGRAM */
char options[128]; char options[128];
int DefinitionModule; int DefinitionModule;
int SYSTEMModule;
char *ProgName; char *ProgName;
char *DEFPATH[NDIRS+1]; char *DEFPATH[NDIRS+1];
struct def *Defined; struct def *Defined;
@ -73,7 +68,6 @@ Compile(src, dst)
reserve(tkidf); reserve(tkidf);
InitScope(); InitScope();
InitTypes(); InitTypes();
InitDef();
AddStandards(); AddStandards();
#ifdef DEBUG #ifdef DEBUG
if (options['l']) { if (options['l']) {
@ -186,27 +180,29 @@ AddStandards()
df->enm_next = 0; df->enm_next = 0;
} }
do_SYSTEM() /* How do you like that! Modula-2 in a C-program.
{ */
/* Simulate the reading of the SYSTEM definition module char SYSTEM[] = "\
*/
char *SYSTEM = "\
DEFINITION MODULE SYSTEM;\n\ DEFINITION MODULE SYSTEM;\n\
TYPE PROCESS = ADDRESS;\n\
PROCEDURE NEWPROCESS(P:PROC; A:ADDRESS; n:CARDINAL; VAR p1:ADDRESS);\n\ PROCEDURE NEWPROCESS(P:PROC; A:ADDRESS; n:CARDINAL; VAR p1:ADDRESS);\n\
PROCEDURE TRANSFER(VAR p1,p2:ADDRESS);\n\ PROCEDURE TRANSFER(VAR p1,p2:ADDRESS);\n\
END SYSTEM.\n"; END SYSTEM.\n";
do_SYSTEM()
{
/* Simulate the reading of the SYSTEM definition module
*/
open_scope(CLOSEDSCOPE); open_scope(CLOSEDSCOPE);
(void) Enter("WORD", D_TYPE, word_type, 0); (void) Enter("WORD", D_TYPE, word_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);
if (!InsertText(SYSTEM, strlen(SYSTEM))) { if (!InsertText(SYSTEM, sizeof(SYSTEM) - 1)) {
fatal("Could not insert text"); fatal("Could not insert text");
} }
SYSTEMModule = 1;
DefModule(); DefModule();
SYSTEMModule = 0; close_scope(SC_CHKFORW);
} }
#ifdef DEBUG #ifdef DEBUG

View file

@ -1,7 +1,5 @@
/* S O M E G L O B A L V A R I A B L E S */ /* S O M E G L O B A L V A R I A B L E S */
/* $Header$ */
extern char options[]; /* indicating which options were given */ extern char options[]; /* indicating which options were given */
extern int DefinitionModule; extern int DefinitionModule;
@ -9,9 +7,6 @@ extern int DefinitionModule;
module module
*/ */
extern int SYSTEMModule;/* flag indicating that we are handling the SYSTEM
module
*/
extern struct def *Defined; extern struct def *Defined;
/* definition structure of module defined in this /* definition structure of module defined in this
compilation compilation

View file

@ -1,25 +1,26 @@
sed -e ' sed -e '
s:^.*[ ]ALLOCDEF[ ].*"\(.*\)".*$:\ s:^.*[ ]ALLOCDEF[ ].*"\(.*\)"[ ]*\([0-9][0-9]*\).*$:\
/* allocation definitions of struct \1 */\ /* allocation definitions of struct \1 */\
extern char *st_alloc();\ extern char *st_alloc();\
extern struct \1 *h_\1;\ extern struct \1 *h_\1;\
#ifdef DEBUG\ #ifdef DEBUG\
extern int cnt_\1;\ extern int cnt_\1;\
#define new_\1() ((struct \1 *) std_alloc((char **)\&h_\1, sizeof(struct \1), \&cnt_\1))\ extern char *std_alloc();\
#define new_\1() ((struct \1 *) std_alloc((char **)\&h_\1, sizeof(struct \1), \2, \&cnt_\1))\
#else\ #else\
#define new_\1() ((struct \1 *) st_alloc((char **)\&h_\1, sizeof(struct \1)))\ #define new_\1() ((struct \1 *) st_alloc((char **)\&h_\1, sizeof(struct \1), \2))\
#endif\ #endif\
#define free_\1(p) st_free(p, h_\1, sizeof(struct \1))\ #define free_\1(p) st_free(p, h_\1, sizeof(struct \1))\
:' -e ' :' -e '
s:^.*[ ]STATICALLOCDEF[ ].*"\(.*\)".*$:\ s:^.*[ ]STATICALLOCDEF[ ].*"\(.*\)"[ ]*\([0-9][0-9]*\).*$:\
/* allocation definitions of struct \1 */\ /* allocation definitions of struct \1 */\
extern char *st_alloc();\ extern char *st_alloc();\
struct \1 *h_\1;\ struct \1 *h_\1;\
#ifdef DEBUG\ #ifdef DEBUG\
int cnt_\1;\ int cnt_\1;\
#define new_\1() ((struct \1 *) std_alloc((char **)\&h_\1, sizeof(struct \1), \&cnt_\1))\ #define new_\1() ((struct \1 *) std_alloc((char **)\&h_\1, sizeof(struct \1), \2, \&cnt_\1))\
#else\ #else\
#define new_\1() ((struct \1 *) st_alloc((char **)\&h_\1, sizeof(struct \1)))\ #define new_\1() ((struct \1 *) st_alloc((char **)\&h_\1, sizeof(struct \1), \2))\
#endif\ #endif\
#define free_\1(p) st_free(p, h_\1, sizeof(struct \1))\ #define free_\1(p) st_free(p, h_\1, sizeof(struct \1))\
:' :'

View file

@ -1,9 +1,5 @@
/* M I S C E L L A N E O U S R O U T I N E S */ /* M I S C E L L A N E O U S R O U T I N E S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include <alloc.h> #include <alloc.h>
#include <em_arith.h> #include <em_arith.h>
#include <em_label.h> #include <em_label.h>

View file

@ -1,7 +1,5 @@
/* M I S C E L L A N E O U S */ /* M I S C E L L A N E O U S */
/* $Header$ */
#define is_anon_idf(x) ((x)->id_text[0] == '#') #define is_anon_idf(x) ((x)->id_text[0] == '#')
extern struct idf extern struct idf

View file

@ -1,7 +1,5 @@
/* N O D E O F A N A B S T R A C T P A R S E T R E E */ /* N O D E O F A N A B S T R A C T P A R S E T R E E */
/* $Header$ */
struct node { struct node {
struct node *next; struct node *next;
#define nd_left next #define nd_left next
@ -35,7 +33,7 @@ struct node {
#define nd_REL nd_token.TOK_REL #define nd_REL nd_token.TOK_REL
}; };
/* ALLOCDEF "node" */ /* ALLOCDEF "node" 50 */
extern struct node *MkNode(), *MkLeaf(); extern struct node *MkNode(), *MkLeaf();

View file

@ -1,9 +1,5 @@
/* N O D E O F A N A B S T R A C T P A R S E T R E E */ /* N O D E O F A N A B S T R A C T P A R S E T R E E */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <em_label.h> #include <em_label.h>

View file

@ -1,9 +1,5 @@
/* U S E R O P T I O N - H A N D L I N G */ /* U S E R O P T I O N - H A N D L I N G */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "idfsize.h" #include "idfsize.h"
#include "ndir.h" #include "ndir.h"
@ -17,7 +13,7 @@ extern int idfsize;
static int ndirs; static int ndirs;
DoOption(text) DoOption(text)
char *text; register char *text;
{ {
switch(*text++) { switch(*text++) {
@ -33,12 +29,15 @@ DoOption(text)
*/ */
case 'M': /* maximum identifier length */ case 'M': { /* maximum identifier length */
idfsize = txt2int(&text); char *t = text; /* because &text is illegal */
if (*text || idfsize <= 0)
idfsize = txt2int(&t);
if (*t || idfsize <= 0)
fatal("malformed -M option"); fatal("malformed -M option");
if (idfsize > IDFSIZE) if (idfsize > IDFSIZE)
fatal("maximum identifier length is %d", IDFSIZE); fatal("maximum identifier length is %d", IDFSIZE);
}
break; break;
case 'I' : case 'I' :
@ -53,13 +52,16 @@ DoOption(text)
arith size; arith size;
int align; int align;
char c; char c;
char *t;
while (c = *text++) { while (c = *text++) {
size = txt2int(&text); t = text;
size = txt2int(&t);
align = 0; align = 0;
if (*text == '.') { if (*(text = t) == '.') {
text++; t = text + 1;
align = txt2int(&text); align = txt2int(&t);
text = t;
} }
switch (c) { switch (c) {
@ -104,7 +106,7 @@ DoOption(text)
int int
txt2int(tp) txt2int(tp)
char **tp; register char **tp;
{ {
/* the integer pointed to by *tp is read, while increasing /* the integer pointed to by *tp is read, while increasing
*tp; the resulting value is yielded. *tp; the resulting value is yielded.

View file

@ -1,10 +1,6 @@
/* O V E R A L L S T R U C T U R E */ /* O V E R A L L S T R U C T U R E */
{ {
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <alloc.h> #include <alloc.h>
@ -42,14 +38,11 @@ static char *RcsId = "$Header$";
ModuleDeclaration ModuleDeclaration
{ {
struct idf *id; /* save module identifier */
register struct def *df; register struct def *df;
struct node *exportlist = 0; struct node *exportlist = 0;
int qualified; int qualified;
} : } :
MODULE IDENT { id = dot.TOK_IDF; MODULE IDENT { df = DefineLocalModule(dot.TOK_IDF); }
df = DefineLocalModule(id);
}
priority(&(df->mod_priority))? priority(&(df->mod_priority))?
';' ';'
import(1)* import(1)*
@ -59,7 +52,7 @@ ModuleDeclaration
EnterExportList(exportlist, qualified); EnterExportList(exportlist, qualified);
} }
close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE); close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
match_id(id, dot.TOK_IDF); match_id(df->df_idf, dot.TOK_IDF);
} }
; ;
@ -104,7 +97,7 @@ import(int local;)
df = lookfor(nd,enclosing(CurrVis),0); df = lookfor(nd,enclosing(CurrVis),0);
FreeNode(nd); FreeNode(nd);
} }
else df = GetDefinitionModule(dot.TOK_IDF); else df = GetDefinitionModule(dot.TOK_IDF, 1);
} }
| |
{ fromid = 0; } { fromid = 0; }
@ -124,16 +117,13 @@ import(int local;)
DefinitionModule DefinitionModule
{ {
register struct def *df; register struct def *df;
struct idf *id; /* save module identifier */
struct node *exportlist; struct node *exportlist;
int dummy; int dummy;
} : } :
DEFINITION DEFINITION
MODULE IDENT { id = dot.TOK_IDF; MODULE IDENT { df = define(dot.TOK_IDF, GlobalScope, D_MODULE);
df = define(id, GlobalScope, D_MODULE);
if (!Defined) Defined = df; if (!Defined) Defined = df;
if (!SYSTEMModule) open_scope(CLOSEDSCOPE); CurrentScope->sc_name = df->df_idf->id_text;
CurrentScope->sc_name = id->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, 0, (arith) 0);
df->df_type->rec_scope = df->mod_vis->sc_scope; df->df_type->rec_scope = df->mod_vis->sc_scope;
@ -154,15 +144,14 @@ node_warning(exportlist, "export list in definition module ignored");
/* empty */ /* empty */
] ]
definition* END IDENT definition* END IDENT
{ df = CurrentScope->sc_def; { register struct def *df1 = CurrentScope->sc_def;
while (df) { while (df1) {
/* Make all definitions "QUALIFIED EXPORT" */ /* Make all definitions "QUALIFIED EXPORT" */
df->df_flags |= D_QEXPORTED; df1->df_flags |= D_QEXPORTED;
df = df->df_nextinscope; df1 = df1->df_nextinscope;
} }
close_scope(SC_CHKFORW);
DefinitionModule--; DefinitionModule--;
match_id(id, dot.TOK_IDF); match_id(df->df_idf, dot.TOK_IDF);
} }
'.' '.'
; ;
@ -206,19 +195,17 @@ Semicolon:
ProgramModule ProgramModule
{ {
struct idf *id;
struct def *GetDefinitionModule(); struct def *GetDefinitionModule();
register struct def *df; register struct def *df;
} : } :
MODULE MODULE
IDENT { id = dot.TOK_IDF; IDENT { if (state == IMPLEMENTATION) {
if (state == IMPLEMENTATION) { df = GetDefinitionModule(dot.TOK_IDF, 0);
df = GetDefinitionModule(id);
CurrVis = df->mod_vis; CurrVis = df->mod_vis;
RemoveImports(&(CurrentScope->sc_def)); RemoveImports(&(CurrentScope->sc_def));
} }
else { else {
Defined = df = define(id, CurrentScope, D_MODULE); Defined = df = define(dot.TOK_IDF, CurrentScope, D_MODULE);
open_scope(CLOSEDSCOPE); open_scope(CLOSEDSCOPE);
df->mod_vis = CurrVis; df->mod_vis = CurrVis;
CurrentScope->sc_name = "_M2M"; CurrentScope->sc_name = "_M2M";
@ -229,13 +216,15 @@ ProgramModule
';' import(0)* ';' import(0)*
block(&(df->mod_body)) IDENT block(&(df->mod_body)) IDENT
{ close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE); { close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
match_id(id, dot.TOK_IDF); match_id(df->df_idf, dot.TOK_IDF);
} }
'.' '.'
; ;
Module: Module:
{ open_scope(CLOSEDSCOPE); }
DefinitionModule DefinitionModule
{ close_scope(SC_CHKFORW); }
| |
[ [
IMPLEMENTATION { state = IMPLEMENTATION; } IMPLEMENTATION { state = IMPLEMENTATION; }

View file

@ -1,9 +1,5 @@
/* S C O P E M E C H A N I S M */ /* S C O P E M E C H A N I S M */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -23,9 +19,9 @@ struct scopelist *CurrVis;
extern int proclevel; extern int proclevel;
static struct scopelist *PervVis; static struct scopelist *PervVis;
/* STATICALLOCDEF "scope" */ /* STATICALLOCDEF "scope" 10 */
/* STATICALLOCDEF "scopelist" */ /* STATICALLOCDEF "scopelist" 10 */
open_scope(scopetype) open_scope(scopetype)
{ {
@ -36,15 +32,14 @@ open_scope(scopetype)
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
clear((char *) sc, sizeof (struct scope));
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE; sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
sc->sc_level = proclevel; sc->sc_level = proclevel;
if (scopetype == OPENSCOPE) {
ls->next = CurrVis;
}
else ls->next = PervVis;
ls->sc_scope = sc; ls->sc_scope = sc;
ls->sc_encl = CurrVis; ls->sc_encl = CurrVis;
if (scopetype == OPENSCOPE) {
ls->next = ls->sc_encl;
}
else ls->next = PervVis;
CurrVis = ls; CurrVis = ls;
} }
@ -71,7 +66,7 @@ struct forwards {
struct type *fo_ptyp; struct type *fo_ptyp;
}; };
/* STATICALLOCDEF "forwards" */ /* STATICALLOCDEF "forwards" 5 */
Forward(tk, ptp) Forward(tk, ptp)
struct node *tk; struct node *tk;
@ -83,11 +78,12 @@ Forward(tk, ptp)
same scope. same scope.
*/ */
register struct forwards *f = new_forwards(); register struct forwards *f = new_forwards();
register struct scope *sc = CurrentScope;
f->fo_tok = tk; f->fo_tok = tk;
f->fo_ptyp = ptp; f->fo_ptyp = ptp;
f->next = CurrentScope->sc_forw; f->next = sc->sc_forw;
CurrentScope->sc_forw = f; sc->sc_forw = f;
} }
STATIC STATIC
@ -95,13 +91,14 @@ chk_proc(df)
register struct def *df; register struct def *df;
{ {
/* Called at scope closing. Check all definitions, and if one /* Called at scope closing. Check all definitions, and if one
is a D_PROCHEAD, the procedure was not defined is a D_PROCHEAD, the procedure was not defined.
*/ */
while (df) { while (df) {
if (df->df_kind == D_PROCHEAD) { if (df->df_kind == D_PROCHEAD) {
/* A not defined procedure /* A not defined procedure
*/ */
error("procedure \"%s\" not defined", df->df_idf->id_text); error("procedure \"%s\" not defined",
df->df_idf->id_text);
FreeNode(df->for_node); FreeNode(df->for_node);
} }
df = df->df_nextinscope; df = df->df_nextinscope;
@ -110,46 +107,48 @@ error("procedure \"%s\" not defined", df->df_idf->id_text);
STATIC STATIC
chk_forw(pdf) chk_forw(pdf)
register struct def **pdf; struct def **pdf;
{ {
/* Called at scope close. Look for all forward definitions and /* Called at scope close. Look for all forward definitions and
if the scope was a closed scope, give an error message for if the scope was a closed scope, give an error message for
them, and otherwise move them to the enclosing scope. them, and otherwise move them to the enclosing scope.
*/ */
while (*pdf) { register struct def *df;
if ((*pdf)->df_kind & (D_FORWARD|D_FORWMODULE)) {
while (df = *pdf) {
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!
*/ */
struct def *df1 = (*pdf)->df_nextinscope;
if (scopeclosed(CurrentScope)) { if (scopeclosed(CurrentScope)) {
/* Indeed, the scope was a closed /* Indeed, the scope was a closed
scope, so give error message scope, so give error message
*/ */
node_error((*pdf)->for_node, "identifier \"%s\" has not been declared", node_error(df->for_node, "identifier \"%s\" has not been declared",
(*pdf)->df_idf->id_text); df->df_idf->id_text);
FreeNode((*pdf)->for_node); FreeNode(df->for_node);
pdf = &(*pdf)->df_nextinscope;
} }
else { /* This scope was an open scope. else {
/* This scope was an open scope.
Maybe the definitions are in the Maybe the definitions are in the
enclosing scope? enclosing scope?
*/ */
struct scopelist *ls; register struct scopelist *ls =
nextvisible(CurrVis);
ls = nextvisible(CurrVis); struct def *df1 = df->df_nextinscope;
if ((*pdf)->df_kind == D_FORWMODULE) {
(*pdf)->for_vis->next = ls; if (df->df_kind == D_FORWMODULE) {
df->for_vis->next = ls;
} }
(*pdf)->df_nextinscope = ls->sc_scope->sc_def; df->df_nextinscope = ls->sc_scope->sc_def;
ls->sc_scope->sc_def = *pdf; ls->sc_scope->sc_def = df;
(*pdf)->df_scope = ls->sc_scope; df->df_scope = ls->sc_scope;
*pdf = df1; *pdf = df1;
continue;
} }
} }
else pdf = &(*pdf)->df_nextinscope; pdf = &df->df_nextinscope;
} }
} }
@ -163,20 +162,17 @@ rem_forwards(fo)
if (fo->next) rem_forwards(fo->next); if (fo->next) rem_forwards(fo->next);
df = lookfor(fo->fo_tok, CurrVis, 0); df = lookfor(fo->fo_tok, CurrVis, 0);
if (df->df_kind == D_ERROR) { if (! is_type(df)) {
node_error(fo->fo_tok, "identifier \"%s\" not declared", node_error(fo->fo_tok,
df->df_idf->id_text); "identifier \"%s\" does not represent a type",
} df->df_idf->id_text);
else if (df->df_kind != D_TYPE) {
node_error(fo->fo_tok, "identifier \"%s\" not a type",
df->df_idf->id_text);
} }
fo->fo_ptyp->next = df->df_type; fo->fo_ptyp->next = df->df_type;
free_forwards(fo); free_forwards(fo);
} }
Reverse(pdf) Reverse(pdf)
register struct def **pdf; struct def **pdf;
{ {
/* Reverse the order in the list of definitions in a scope. /* Reverse the order in the list of definitions in a scope.
This is neccesary because this list is built in reverse. This is neccesary because this list is built in reverse.
@ -188,23 +184,18 @@ Reverse(pdf)
df = 0; df = 0;
df1 = *pdf; df1 = *pdf;
while (df1) {
if (df1->df_kind & INTERESTING) break;
df1 = df1->df_nextinscope;
}
if (!(*pdf = df1)) return;
while (df1) { while (df1) {
*pdf = df1; if (df1->df_kind & INTERESTING) {
df1 = df1->df_nextinscope; struct def *prev = df;
while (df1) {
if (df1->df_kind & INTERESTING) break; df = df1;
df1 = df1->df_nextinscope; df1 = df1->df_nextinscope;
df->df_nextinscope = prev;
} }
(*pdf)->df_nextinscope = df; else df1 = df1->df_nextinscope;
df = *pdf;
} }
*pdf = df;
} }
close_scope(flag) close_scope(flag)

View file

@ -1,7 +1,5 @@
/* S C O P E M E C H A N I S M */ /* S C O P E M E C H A N I S M */
/* $Header$ */
#define OPENSCOPE 0 /* Indicating an open scope */ #define OPENSCOPE 0 /* Indicating an open scope */
#define CLOSEDSCOPE 1 /* Indicating a closed scope (module) */ #define CLOSEDSCOPE 1 /* Indicating a closed scope (module) */

View file

@ -1,7 +1,5 @@
/* S T A N D A R D P R O C E D U R E S A N D F U N C T I O N S */ /* S T A N D A R D P R O C E D U R E S A N D F U N C T I O N S */
/* $Header$ */
#define S_ABS 1 #define S_ABS 1
#define S_CAP 2 #define S_CAP 2
#define S_CHR 3 #define S_CHR 3

View file

@ -1,10 +1,6 @@
/* S T A T E M E N T S */ /* S T A T E M E N T S */
{ {
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include <assert.h> #include <assert.h>
#include <em_arith.h> #include <em_arith.h>
#include <em_label.h> #include <em_label.h>
@ -22,6 +18,7 @@ static int loopcount = 0; /* Count nested loops */
statement(register struct node **pnd;) statement(register struct node **pnd;)
{ {
register struct node *nd; register struct node *nd;
extern int return_occurred;
} : } :
/* /*
* This part is not in the reference grammar. The reference grammar * This part is not in the reference grammar. The reference grammar
@ -64,6 +61,7 @@ statement(register struct node **pnd;)
} }
| |
ReturnStatement(pnd) ReturnStatement(pnd)
{ return_occurred = 1; }
| |
/* empty */ { *pnd = 0; } /* empty */ { *pnd = 0; }
; ;
@ -88,9 +86,12 @@ StatementSequence(register struct node **pnd;)
[ %persistent [ %persistent
';' statement(&nd) ';' statement(&nd)
{ if (nd) { { if (nd) {
*pnd = MkNode(Link, *pnd, nd, &dot); register struct node *nd1 =
(*pnd)->nd_symb = ';'; MkNode(Link, *pnd, nd, &dot);
pnd = &((*pnd)->nd_right);
*pnd = nd1;
nd1->nd_symb = ';';
pnd = &(nd1->nd_right);
} }
} }
]* ]*
@ -178,31 +179,29 @@ RepeatStatement(struct node **pnd;)
ForStatement(struct node **pnd;) ForStatement(struct node **pnd;)
{ {
register struct node *nd; register struct node *nd, *nd1;
struct node *dummy; struct node *dummy;
}: }:
FOR { *pnd = nd = MkLeaf(Stat, &dot); } FOR { *pnd = nd = MkLeaf(Stat, &dot); }
IDENT { nd->nd_IDF = dot.TOK_IDF; } IDENT { nd->nd_IDF = dot.TOK_IDF; }
BECOMES { nd->nd_left = MkLeaf(Stat, &dot); BECOMES { nd->nd_left = nd1 = MkLeaf(Stat, &dot); }
nd = nd->nd_left; expression(&(nd1->nd_left))
}
expression(&(nd->nd_left))
TO TO
expression(&(nd->nd_right)) expression(&(nd1->nd_right))
[ [
BY BY
ConstExpression(&dummy) ConstExpression(&dummy)
{ if (!(dummy->nd_type->tp_fund & T_INTORCARD)) { { if (!(dummy->nd_type->tp_fund & T_INTORCARD)) {
error("illegal type in BY clause"); error("illegal type in BY clause");
} }
nd->nd_INT = dummy->nd_INT; nd1->nd_INT = dummy->nd_INT;
FreeNode(dummy); FreeNode(dummy);
} }
| |
{ nd->nd_INT = 1; } { nd1->nd_INT = 1; }
] ]
DO DO
StatementSequence(&((*pnd)->nd_right)) StatementSequence(&(nd->nd_right))
END END
; ;
@ -227,12 +226,9 @@ ReturnStatement(struct node **pnd;)
{ {
register struct def *df = CurrentScope->sc_definedby; register struct def *df = CurrentScope->sc_definedby;
register struct node *nd; register struct node *nd;
extern int return_occurred;
} : } :
RETURN { *pnd = nd = MkLeaf(Stat, &dot); RETURN { *pnd = nd = MkLeaf(Stat, &dot); }
return_occurred = 1;
}
[ [
expression(&(nd->nd_right)) expression(&(nd->nd_right))
{ if (scopeclosed(CurrentScope)) { { if (scopeclosed(CurrentScope)) {

View file

@ -1,9 +1,5 @@
/* T E M P O R A R Y V A R I A B L E S */ /* T E M P O R A R Y V A R I A B L E S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Code for the allocation and de-allocation of temporary variables, /* Code for the allocation and de-allocation of temporary variables,
allowing re-use. allowing re-use.
The routines use "ProcScope" instead of "CurrentScope", because The routines use "ProcScope" instead of "CurrentScope", because
@ -29,7 +25,7 @@ struct tmpvar {
arith t_offset; /* offset from LocalBase */ arith t_offset; /* offset from LocalBase */
}; };
/* STATICALLOCDEF "tmpvar" */ /* STATICALLOCDEF "tmpvar" 10 */
static struct tmpvar *TmpInts, /* for integer temporaries */ static struct tmpvar *TmpInts, /* for integer temporaries */
*TmpPtrs; /* for pointer temporaries */ *TmpPtrs; /* for pointer temporaries */
@ -47,7 +43,7 @@ TmpOpen(sc) struct scope *sc;
arith arith
NewInt() NewInt()
{ {
arith offset; register arith offset;
register struct tmpvar *tmp; register struct tmpvar *tmp;
if (!TmpInts) { if (!TmpInts) {
@ -67,7 +63,7 @@ NewInt()
arith arith
NewPtr() NewPtr()
{ {
arith offset; register arith offset;
register struct tmpvar *tmp; register struct tmpvar *tmp;
if (!TmpPtrs) { if (!TmpPtrs) {

View file

@ -1,9 +1,5 @@
/* T O K E N D E F I N I T I O N S */ /* T O K E N D E F I N I T I O N S */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "tokenname.h" #include "tokenname.h"
#include "Lpars.h" #include "Lpars.h"
#include "idf.h" #include "idf.h"

View file

@ -1,7 +1,5 @@
/* T O K E N N A M E S T R U C T U R E */ /* T O K E N N A M E S T R U C T U R E */
/* $Header$ */
struct tokenname { /* Used for defining the name of a struct tokenname { /* Used for defining the name of a
token as identified by its symbol token as identified by its symbol
*/ */

View file

@ -1,7 +1,5 @@
/* T Y P E D E S C R I P T O R S T R U C T U R E */ /* T Y P E D E S C R I P T O R S T R U C T U R E */
/* $Header$ */
struct paramlist { /* structure for parameterlist of a PROCEDURE */ struct paramlist { /* structure for parameterlist of a PROCEDURE */
struct paramlist *next; struct paramlist *next;
struct def *par_def; /* "df" of parameter */ struct def *par_def; /* "df" of parameter */
@ -9,7 +7,7 @@ struct paramlist { /* structure for parameterlist of a PROCEDURE */
#define TypeOfParam(xpar) ((xpar)->par_def->df_type) #define TypeOfParam(xpar) ((xpar)->par_def->df_type)
}; };
/* ALLOCDEF "paramlist" */ /* ALLOCDEF "paramlist" 20 */
struct enume { struct enume {
struct def *en_enums; /* Definitions of enumeration literals */ struct def *en_enums; /* Definitions of enumeration literals */
@ -86,7 +84,7 @@ struct type {
} tp_value; } tp_value;
}; };
/* ALLOCDEF "type" */ /* ALLOCDEF "type" 50 */
extern struct type extern struct type
*bool_type, *bool_type,
@ -125,11 +123,11 @@ extern arith
align(); /* type.c */ align(); /* type.c */
struct type struct type
*create_type(),
*construct_type(), *construct_type(),
*standard_type(), *standard_type(),
*set_type(), *set_type(),
*subr_type(), *subr_type(),
*proc_type(),
*RemoveEqual(); /* All from type.c */ *RemoveEqual(); /* All from type.c */
#define NULLTYPE ((struct type *) 0) #define NULLTYPE ((struct type *) 0)

View file

@ -1,9 +1,5 @@
/* T Y P E D E F I N I T I O N M E C H A N I S M */ /* T Y P E D E F I N I T I O N M E C H A N I S M */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
#include "target_sizes.h" #include "target_sizes.h"
#include "debug.h" #include "debug.h"
#include "maxset.h" #include "maxset.h"
@ -66,21 +62,6 @@ struct type *h_type;
int cnt_type; int cnt_type;
#endif #endif
struct type *
create_type(fund)
int fund;
{
/* A brand new struct type is created, and its tp_fund set
to fund.
*/
register struct type *ntp = new_type();
clear((char *)ntp, sizeof(struct type));
ntp->tp_fund = fund;
return ntp;
}
struct type * struct type *
construct_type(fund, tp) construct_type(fund, tp)
int fund; int fund;
@ -89,9 +70,9 @@ construct_type(fund, tp)
/* fund must be a type constructor. /* fund must be a type constructor.
The pointer to the constructed type is returned. The pointer to the constructed type is returned.
*/ */
register struct type *dtp = create_type(fund); register struct type *dtp = new_type();
switch (fund) { switch (dtp->tp_fund = fund) {
case T_PROCEDURE: case T_PROCEDURE:
case T_POINTER: case T_POINTER:
case T_HIDDEN: case T_HIDDEN:
@ -135,8 +116,9 @@ standard_type(fund, align, size)
int align; int align;
arith size; arith size;
{ {
register struct type *tp = create_type(fund); register struct type *tp = new_type();
tp->tp_fund = fund;
tp->tp_align = align; tp->tp_align = align;
tp->tp_size = size; tp->tp_size = size;
@ -167,10 +149,6 @@ InitTypes()
fatal("long real size smaller than real size"); fatal("long real size smaller than real size");
} }
if (!pointer_size || pointer_size % word_size != 0) {
fatal("illegal pointer size");
}
/* character type /* character type
*/ */
char_type = standard_type(T_CHAR, 1, (arith) 1); char_type = standard_type(T_CHAR, 1, (arith) 1);
@ -303,6 +281,19 @@ subr_type(lb, ub)
return res; return res;
} }
struct type *
proc_type(result_type, parameters, n_bytes_params)
struct type *result_type;
struct paramlist *parameters;
arith n_bytes_params;
{
register struct type *tp = construct_type(T_PROCEDURE, result_type);
tp->prc_params = parameters;
tp->prc_nbpar = n_bytes_params;
return tp;
}
genrck(tp) genrck(tp)
register struct type *tp; register struct type *tp;
{ {
@ -310,20 +301,22 @@ genrck(tp)
neccessary. Return its label. neccessary. Return its label.
*/ */
arith lb, ub; arith lb, ub;
label ol, l; register label ol;
int newlabel = 0;
getbounds(tp, &lb, &ub); getbounds(tp, &lb, &ub);
if (tp->tp_fund == T_SUBRANGE) { if (tp->tp_fund == T_SUBRANGE) {
if (!(ol = tp->sub_rck)) { if (!(ol = tp->sub_rck)) {
tp->sub_rck = l = ++data_label; tp->sub_rck = ol = ++data_label;
newlabel = 1;
} }
} }
else if (!(ol = tp->enm_rck)) { else if (!(ol = tp->enm_rck)) {
tp->enm_rck = l = ++data_label; tp->enm_rck = ol = ++data_label;
newlabel = 1;
} }
if (!ol) { if (newlabel) {
ol = l;
C_df_dlb(ol); C_df_dlb(ol);
C_rom_cst(lb); C_rom_cst(lb);
C_rom_cst(ub); C_rom_cst(ub);
@ -385,7 +378,7 @@ ArrayElSize(tp)
Also make sure that its size is either a dividor of the word_size, Also make sure that its size is either a dividor of the word_size,
or a multiple of it. or a multiple of it.
*/ */
arith algn; register arith algn;
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);
@ -446,6 +439,7 @@ FreeType(tp)
while (pr) { while (pr) {
pr1 = pr; pr1 = pr;
pr = pr->next; pr = pr->next;
free_def(pr1->par_def);
free_paramlist(pr1); free_paramlist(pr1);
} }
@ -520,21 +514,14 @@ DumpType(tp)
{ {
if (!tp) return; if (!tp) return;
print(" a:%d; s:%ld;", tp->tp_align, (long) tp->tp_size); print("align:%d; size:%ld;", tp->tp_align, (long) tp->tp_size);
if (tp->next && tp->tp_fund != T_POINTER) {
/* Avoid printing recursive types!
*/
print(" n:(");
DumpType(tp->next);
print(")");
}
print(" f:"); print(" fund:");
switch(tp->tp_fund) { switch(tp->tp_fund) {
case T_RECORD: case T_RECORD:
print("RECORD"); break; print("RECORD"); break;
case T_ENUMERATION: case T_ENUMERATION:
print("ENUMERATION; n:%d", tp->enm_ncst); break; print("ENUMERATION; ncst:%d", tp->enm_ncst); break;
case T_INTEGER: case T_INTEGER:
print("INTEGER"); break; print("INTEGER"); break;
case T_CARDINAL: case T_CARDINAL:
@ -562,7 +549,7 @@ DumpType(tp)
print("PROCEDURE"); print("PROCEDURE");
if (par) { if (par) {
print("; p:"); print("(");
while(par) { while(par) {
if (IsVarParam(par)) print("VAR "); if (IsVarParam(par)) print("VAR ");
DumpType(TypeOfParam(par)); DumpType(TypeOfParam(par));
@ -573,11 +560,12 @@ DumpType(tp)
} }
case T_ARRAY: case T_ARRAY:
print("ARRAY"); print("ARRAY");
print("; el:"); print("; element:");
DumpType(tp->arr_elem); DumpType(tp->arr_elem);
print("; index:"); print("; index:");
DumpType(tp->next); DumpType(tp->next);
break; print(";");
return;
case T_STRING: case T_STRING:
print("STRING"); break; print("STRING"); break;
case T_INTORCARD: case T_INTORCARD:
@ -585,6 +573,13 @@ DumpType(tp)
default: default:
crash("DumpType"); crash("DumpType");
} }
if (tp->next && tp->tp_fund != T_POINTER) {
/* Avoid printing recursive types!
*/
print(" next:(");
DumpType(tp->next);
print(")");
}
print(";"); print(";");
} }
#endif #endif

View file

@ -1,9 +1,5 @@
/* T Y P E E Q U I V A L E N C E */ /* T Y P E E Q U I V A L E N C E */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Routines for testing type equivalence, type compatibility, and /* Routines for testing type equivalence, type compatibility, and
assignment compatibility assignment compatibility
*/ */

View file

@ -1,9 +1,5 @@
/* P A R S E T R E E W A L K E R */ /* P A R S E T R E E W A L K E R */
#ifndef NORCSID
static char *RcsId = "$Header$";
#endif
/* Routines to walk through parts of the parse tree, and generate /* Routines to walk through parts of the parse tree, and generate
code for these parts. code for these parts.
*/ */
@ -103,11 +99,6 @@ WalkModule(module)
C_loe_dlb(l1, (arith) 0); C_loe_dlb(l1, (arith) 0);
C_zne(RETURN_LABEL); C_zne(RETURN_LABEL);
C_ine_dlb(l1, (arith) 0); C_ine_dlb(l1, (arith) 0);
/* Prevent this module from calling its own
initialization routine
*/
assert(nd->nd_IDF == module->df_idf);
nd = nd->next;
} }
for (; nd; nd = nd->next) { for (; nd; nd = nd->next) {
@ -415,17 +406,16 @@ WalkStat(nd, exit_label)
break; break;
case IF: case IF:
{ label l1, l2, l3; { label l1 = ++text_label, l3 = ++text_label;
l1 = ++text_label;
l2 = ++text_label;
l3 = ++text_label;
ExpectBool(left, l3, l1); ExpectBool(left, l3, l1);
assert(right->nd_symb == THEN); assert(right->nd_symb == THEN);
C_df_ilb(l3); C_df_ilb(l3);
WalkNode(right->nd_left, exit_label); WalkNode(right->nd_left, exit_label);
if (right->nd_right) { /* ELSE part */ if (right->nd_right) { /* ELSE part */
label l2 = ++text_label;
C_bra(l2); C_bra(l2);
C_df_ilb(l1); C_df_ilb(l1);
WalkNode(right->nd_right, exit_label); WalkNode(right->nd_right, exit_label);
@ -440,73 +430,72 @@ WalkStat(nd, exit_label)
break; break;
case WHILE: case WHILE:
{ label l1, l2, l3; { label loop = ++text_label,
exit = ++text_label,
dummy = ++text_label;
l1 = ++text_label; C_df_ilb(loop);
l2 = ++text_label; ExpectBool(left, dummy, exit);
l3 = ++text_label; C_df_ilb(dummy);
C_df_ilb(l1);
ExpectBool(left, l3, l2);
C_df_ilb(l3);
WalkNode(right, exit_label); WalkNode(right, exit_label);
C_bra(l1); C_bra(loop);
C_df_ilb(l2); C_df_ilb(exit);
break; break;
} }
case REPEAT: case REPEAT:
{ label l1, l2; { label loop = ++text_label, exit = ++text_label;
l1 = ++text_label; C_df_ilb(loop);
l2 = ++text_label;
C_df_ilb(l1);
WalkNode(left, exit_label); WalkNode(left, exit_label);
ExpectBool(right, l2, l1); ExpectBool(right, exit, loop);
C_df_ilb(l2); C_df_ilb(exit);
break; break;
} }
case LOOP: case LOOP:
{ label l1, l2; { label loop = ++text_label, exit = ++text_label;
l1 = ++text_label; C_df_ilb(loop);
l2 = ++text_label; WalkNode(right, exit);
C_df_ilb(l1); C_bra(loop);
WalkNode(right, l2); C_df_ilb(exit);
C_bra(l1);
C_df_ilb(l2);
break; break;
} }
case FOR: case FOR:
{ {
arith tmp = 0; arith tmp = 0;
struct node *fnd; register struct node *fnd;
label l1 = ++text_label; label l1 = ++text_label;
label l2 = ++text_label; label l2 = ++text_label;
if (! DoForInit(nd, left)) break; if (! DoForInit(nd, left)) break;
fnd = left->nd_right; fnd = left->nd_right;
if (fnd->nd_class != Value) { if (fnd->nd_class != Value) {
/* Upperbound not constant.
The expression may only be evaluated once,
so generate a temporary for it
*/
CodePExpr(fnd); CodePExpr(fnd);
tmp = NewInt(); tmp = NewInt();
C_stl(tmp); C_stl(tmp);
} }
C_bra(l1); C_df_ilb(l1);
C_df_ilb(l2); C_dup(int_size);
if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
if (left->nd_INT > 0) {
C_bgt(l2);
}
else C_blt(l2);
RangeCheck(nd->nd_type, int_type); RangeCheck(nd->nd_type, int_type);
CodeDStore(nd); CodeDStore(nd);
WalkNode(right, exit_label); WalkNode(right, exit_label);
CodePExpr(nd); CodePExpr(nd);
C_loc(left->nd_INT); C_loc(left->nd_INT);
C_adi(int_size); C_adi(int_size);
C_df_ilb(l1); C_bra(l1);
C_dup(int_size); C_df_ilb(l2);
if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
if (left->nd_INT > 0) {
C_ble(l2);
}
else C_bge(l2);
C_asp(int_size); C_asp(int_size);
if (tmp) FreeInt(tmp); if (tmp) FreeInt(tmp);
} }
@ -517,7 +506,6 @@ WalkStat(nd, exit_label)
struct scopelist link; struct scopelist link;
struct withdesig wds; struct withdesig wds;
struct desig ds; struct desig ds;
arith tmp = 0;
if (! WalkDesignator(left, &ds)) break; if (! WalkDesignator(left, &ds)) break;
if (left->nd_type->tp_fund != T_RECORD) { if (left->nd_type->tp_fund != T_RECORD) {
@ -532,7 +520,7 @@ WalkStat(nd, exit_label)
ds.dsg_kind = DSG_FIXED; ds.dsg_kind = DSG_FIXED;
/* Create a designator structure for the temporary. /* Create a designator structure for the temporary.
*/ */
ds.dsg_offset = tmp = NewPtr(); ds.dsg_offset = NewPtr();
ds.dsg_name = 0; ds.dsg_name = 0;
CodeStore(&ds, pointer_size); CodeStore(&ds, pointer_size);
ds.dsg_kind = DSG_PFIXED; ds.dsg_kind = DSG_PFIXED;
@ -544,7 +532,7 @@ WalkStat(nd, exit_label)
WalkNode(right, exit_label); WalkNode(right, exit_label);
CurrVis = link.next; CurrVis = link.next;
WithDesigs = wds.w_next; WithDesigs = wds.w_next;
FreePtr(tmp); FreePtr(ds.dsg_offset);
break; break;
} }
@ -648,12 +636,13 @@ DoForInit(nd, left)
nd->nd_symb = IDENT; nd->nd_symb = IDENT;
if (! ChkVariable(nd) || if (! ChkVariable(nd) ||
! ChkExpression(left->nd_left) || ! WalkExpr(left->nd_left) ||
! ChkExpression(left->nd_right)) return 0; ! ChkExpression(left->nd_right)) return 0;
df = nd->nd_def; df = nd->nd_def;
if (df->df_kind == D_FIELD) { if (df->df_kind == D_FIELD) {
node_error(nd, "FOR-loop variable may not be a field of a record"); node_error(nd,
"FOR-loop variable may not be a field of a record");
return 0; return 0;
} }
@ -665,14 +654,15 @@ DoForInit(nd, left)
if (df->df_scope != CurrentScope) { if (df->df_scope != CurrentScope) {
register struct scopelist *sc = CurrVis; register struct scopelist *sc = CurrVis;
while (sc && sc->sc_scope != df->df_scope) { for (;;) {
if (!sc) {
node_error(nd,
"FOR-loop variable may not be imported");
return 0;
}
if (sc->sc_scope == df->df_scope) break;
sc = nextvisible(sc); sc = nextvisible(sc);
} }
if (!sc) {
node_error(nd, "FOR-loop variable may not be imported");
return 0;
}
} }
if (df->df_type->tp_size > word_size || if (df->df_type->tp_size > word_size ||
@ -691,8 +681,6 @@ DoForInit(nd, left)
node_warning(nd, "old-fashioned! compatibility required in FOR statement"); node_warning(nd, "old-fashioned! compatibility required in FOR statement");
} }
CodePExpr(left->nd_left);
return 1; return 1;
} }
@ -703,11 +691,12 @@ DoAssign(nd, left, right)
/* May we do it in this order (expression first) ??? /* May we do it in this order (expression first) ???
The reference manual sais nothing about it, but the book does: The reference manual sais nothing about it, but the book does:
it sais that the left hand side is evaluated first. it sais that the left hand side is evaluated first.
DAMN THE BOOK!
*/ */
struct desig dsl, dsr; struct desig dsl, dsr;
if (! ChkExpression(right)) return; if (! ChkExpression(right) || ! ChkVariable(left)) return;
if (! ChkVariable(left)) return;
if (right->nd_symb == STRING) TryToString(right, left->nd_type); if (right->nd_symb == STRING) TryToString(right, left->nd_type);
dsr = InitDesig; dsr = InitDesig;
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL); CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);

View file

@ -1,7 +1,5 @@
/* P A R S E T R E E W A L K E R */ /* P A R S E T R E E W A L K E R */
/* $Header$ */
/* Definition of WalkNode macro /* Definition of WalkNode macro
*/ */