newer version

This commit is contained in:
ceriel 1986-06-20 14:36:49 +00:00
parent a9dfdc494b
commit 9932033365
16 changed files with 337 additions and 196 deletions

View file

@ -11,7 +11,7 @@ LSRC = tokenfile.g program.g declar.g expression.g statement.g
CC = cc CC = cc
GEN = /usr/em/util/LLgen/src/LLgen GEN = /usr/em/util/LLgen/src/LLgen
GENOPTIONS = -d GENOPTIONS = -d
PROFILE = -p PROFILE =
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC= CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
LINTFLAGS = -DSTATIC= -DNORCSID LINTFLAGS = -DSTATIC= -DNORCSID
LFLAGS = $(PROFILE) LFLAGS = $(PROFILE)
@ -22,10 +22,17 @@ COBJ = LLlex.o LLmessage.o char.o error.o main.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
OBJ = $(COBJ) $(LOBJ) Lpars.o OBJ = $(COBJ) $(LOBJ) Lpars.o
GENFILES= tokenfile.c \
program.c declar.c expression.c statement.c \
tokenfile.g symbol2str.c char.c Lpars.c Lpars.h
# Keep the next three entries up to date!
GENCFILES= tokenfile.c \
program.c declar.c expression.c statement.c \
symbol2str.c char.c Lpars.c casestat.c tmpvar.c scope.c
GENGFILES= tokenfile.g
GENHFILES= errout.h\
idfsize.h numsize.h strsize.h target_sizes.h debug.h\
inputtype.h maxset.h ndir.h density.h
#
GENFILES = $(GENGFILES) $(GENCFILES) $(GENHFILES)
all: all:
make hfiles make hfiles
make LLfiles make LLfiles
@ -44,7 +51,7 @@ main: $(OBJ) Makefile
size main size main
clean: clean:
rm -f $(OBJ) $(GENFILES) LLfiles rm -f $(OBJ) $(GENFILES) LLfiles hfiles
lint: LLfiles hfiles lint: LLfiles hfiles
lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)` lint $(INCLUDES) $(LINTFLAGS) `sources $(OBJ)`
@ -101,7 +108,7 @@ 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
chk_expr.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h chk_expr.o: LLlex.h Lpars.h chk_expr.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
options.o: idfsize.h main.h ndir.h type.h options.o: idfsize.h main.h ndir.h type.h
walk.o: LLlex.h Lpars.h chk_expr.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h walk.o: LLlex.h Lpars.h chk_expr.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h walk.h
casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.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 code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h standards.h type.h

View file

@ -16,6 +16,7 @@ static char *RcsId = "$Header$";
#include "LLlex.h" #include "LLlex.h"
#include "node.h" #include "node.h"
#include "desig.h" #include "desig.h"
#include "walk.h"
#include "density.h" #include "density.h"
@ -48,8 +49,6 @@ struct case_entry {
*/ */
#define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY) #define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY)
extern label text_label(), data_label();
CaseCode(nd, exitlabel) CaseCode(nd, exitlabel)
struct node *nd; struct node *nd;
label exitlabel; label exitlabel;
@ -68,7 +67,7 @@ CaseCode(nd, exitlabel)
clear((char *) sh, sizeof(*sh)); clear((char *) sh, sizeof(*sh));
WalkExpr(pnode->nd_left); 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
*/ */
@ -76,7 +75,7 @@ CaseCode(nd, exitlabel)
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) {
pnode->nd_lab = text_label(); pnode->nd_lab = ++text_label;
if (! AddCases(sh, if (! AddCases(sh,
pnode->nd_left->nd_left, pnode->nd_left->nd_left,
pnode->nd_lab)) { pnode->nd_lab)) {
@ -89,17 +88,17 @@ CaseCode(nd, exitlabel)
/* Else part /* Else part
*/ */
sh->sh_default = text_label(); sh->sh_default = ++text_label;
pnode = 0; pnode = 0;
} }
} }
/* Now generate code for the switch itself /* Now generate code for the switch itself
*/ */
tablabel = data_label(); /* the rom must have a label */ tablabel = ++data_label; /* the rom must have a label */
C_df_dlb(tablabel); C_df_dlb(tablabel);
if (sh->sh_default) C_rom_ilb(sh->sh_default); if (sh->sh_default) C_rom_ilb(sh->sh_default);
else C_rom_ilb(sh->sh_break); 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 */
@ -113,7 +112,7 @@ CaseCode(nd, exitlabel)
ce = ce->next; ce = ce->next;
} }
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_ilb(sh->sh_break); else C_rom_ucon("0", pointer_size);
} }
C_lae_dlb(tablabel, (arith)0); /* perform the switch */ C_lae_dlb(tablabel, (arith)0); /* perform the switch */
C_csa(word_size); C_csa(word_size);

View file

@ -31,7 +31,7 @@ STATIC int
chk_arr(expp) chk_arr(expp)
struct node *expp; struct node *expp;
{ {
return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED); return chk_designator(expp, VARIABLE, D_USED);
} }
STATIC int STATIC int
@ -54,7 +54,7 @@ STATIC int
chk_linkorname(expp) chk_linkorname(expp)
register struct node *expp; register struct node *expp;
{ {
if (chk_designator(expp, VALUE|DESIGNATOR, D_USED)) { if (chk_designator(expp, VALUE, D_USED)) {
if (expp->nd_class == Def && if (expp->nd_class == Def &&
expp->nd_def->df_kind == D_PROCEDURE) { expp->nd_def->df_kind == D_PROCEDURE) {
/* Check that this procedure is one that we /* Check that this procedure is one that we
@ -269,7 +269,7 @@ getarg(argp, bases, designator)
if ((!designator && !chk_expr(left)) || if ((!designator && !chk_expr(left)) ||
(designator && (designator &&
!chk_designator(left, DESIGNATOR|VARIABLE, D_USED|D_NOREG))) { !chk_designator(left, VARIABLE, D_USED|D_NOREG))) {
return 0; return 0;
} }
@ -299,7 +299,10 @@ getname(argp, kinds)
arg = arg->nd_right; arg = arg->nd_right;
if (! chk_designator(arg->nd_left, 0, D_REFERRED)) return 0; if (! chk_designator(arg->nd_left, 0, D_REFERRED)) return 0;
if (arg->nd_left->nd_class != Def); if (arg->nd_left->nd_class != Def && arg->nd_left->nd_class != LinkDef) {
node_error(arg, "identifier expected");
return 0;
}
if (!(arg->nd_left->nd_def->df_kind & kinds)) { if (!(arg->nd_left->nd_def->df_kind & kinds)) {
node_error(arg, "unexpected type"); node_error(arg, "unexpected type");
@ -324,7 +327,7 @@ chk_proccall(expp)
arg = expp; arg = expp;
expp->nd_type = left->nd_type->next; expp->nd_type = left->nd_type->next;
for (param = left->nd_type->prc_params; 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(&arg, 0, IsVarParam(param)))) return 0;
if (left->nd_symb == STRING) { if (left->nd_symb == STRING) {
TryToString(left, TypeOfParam(param)); TryToString(left, TypeOfParam(param));
@ -430,8 +433,6 @@ chk_designator(expp, flag, dflags)
be something that can be assigned to. be something that can be assigned to.
It may also contain the flag VALUE, indicating that a It may also contain the flag VALUE, indicating that a
value is expected. In this case, VARIABLE may not be set. value is expected. In this case, VARIABLE may not be set.
It also contains the flag DESIGNATOR, indicating that '['
and '^' are allowed for this designator.
Also contained may be the flag HASSELECTORS, indicating that Also contained may be the flag HASSELECTORS, indicating that
the result must have selectors. the result must have selectors.
"dflags" contains some flags that must be set at the definition "dflags" contains some flags that must be set at the definition
@ -440,6 +441,11 @@ chk_designator(expp, flag, dflags)
register struct def *df; register struct def *df;
register struct type *tp; register struct type *tp;
if (expp->nd_class == Def || expp->nd_class == LinkDef) {
expp->nd_def->df_flags |= dflags;
return 1;
}
expp->nd_type = error_type; expp->nd_type = error_type;
if (expp->nd_class == Name) { if (expp->nd_class == Name) {
@ -453,7 +459,7 @@ chk_designator(expp, flag, dflags)
assert(expp->nd_symb == '.'); assert(expp->nd_symb == '.');
if (! chk_designator(left, if (! chk_designator(left,
(flag&DESIGNATOR)|HASSELECTORS, HASSELECTORS,
dflags)) return 0; dflags)) return 0;
tp = left->nd_type; tp = left->nd_type;
@ -466,6 +472,7 @@ chk_designator(expp, flag, dflags)
else { else {
expp->nd_def = df; expp->nd_def = df;
expp->nd_type = df->df_type; expp->nd_type = df->df_type;
expp->nd_class = LinkDef;
if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) { if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
/* Fields of a record are always D_QEXPORTED, /* Fields of a record are always D_QEXPORTED,
so ... so ...
@ -513,18 +520,13 @@ df->df_idf->id_text);
return 1; return 1;
} }
if (! (flag & DESIGNATOR)) {
node_error(expp, "identifier expected");
return 0;
}
if (expp->nd_class == Arrsel) { if (expp->nd_class == Arrsel) {
struct type *tpl, *tpr; struct type *tpl, *tpr;
assert(expp->nd_symb == '['); assert(expp->nd_symb == '[');
if ( if (
!chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags) !chk_designator(expp->nd_left, VARIABLE, dflags)
|| ||
!chk_expr(expp->nd_right) !chk_expr(expp->nd_right)
|| ||
@ -556,7 +558,7 @@ df->df_idf->id_text);
if (expp->nd_class == Arrow) { if (expp->nd_class == Arrow) {
assert(expp->nd_symb == '^'); assert(expp->nd_symb == '^');
if (! chk_designator(expp->nd_right, DESIGNATOR|VARIABLE, dflags)) { if (! chk_designator(expp->nd_right, VARIABLE, dflags)) {
return 0; return 0;
} }
@ -795,7 +797,7 @@ chk_uoper(expp)
break; break;
default: default:
assert(0); crash("chk_uoper");
} }
node_error(expp, "illegal operand for unary operator \"%s\"", node_error(expp, "illegal operand for unary operator \"%s\"",
symbol2str(expp->nd_symb)); symbol2str(expp->nd_symb));
@ -818,14 +820,14 @@ getvariable(argp)
left = arg->nd_left; left = arg->nd_left;
if (! chk_designator(left, DESIGNATOR, D_REFERRED)) return 0; if (! chk_designator(left, 0, D_REFERRED)) return 0;
if (left->nd_class == Arrsel || left->nd_class == Arrow) { if (left->nd_class == Arrsel || left->nd_class == Arrow) {
*argp = arg; *argp = arg;
return left; return left;
} }
df = 0; df = 0;
if (left->nd_class == Link || left->nd_class == Def) { if (left->nd_class == LinkDef || left->nd_class == Def) {
df = left->nd_def; df = left->nd_def;
} }
@ -917,6 +919,47 @@ DO_DEBUG(3,debug("standard name \"%s\", %d",left->nd_def->df_idf->id_text,std));
if (left->nd_class == Value) cstcall(expp, S_ORD); if (left->nd_class == Value) cstcall(expp, S_ORD);
break; break;
case S_NEW:
case S_DISPOSE:
{
static int warning_given = 0;
if (!warning_given) {
warning_given = 1;
node_warning(expp, "NEW and DISPOSE are old-fashioned");
}
}
if (! (left = getvariable(&arg))) return 0;
if (! (left->nd_type->tp_fund == T_POINTER)) {
node_error(left, "pointer variable expected");
return 0;
}
if (left->nd_class == Def) {
left->nd_def->df_flags |= D_NOREG;
}
/* Now, make it look like a call to ALLOCATE or DEALLOCATE */
{
struct token dt;
struct node *nd;
dt.TOK_INT = left->nd_type->next->tp_size;
dt.tk_symb = INTEGER;
dt.tk_lineno = left->nd_lineno;
nd = MkLeaf(Value, &dt);
nd->nd_type = card_type;
dt.tk_symb = ',';
arg->nd_right = MkNode(Link, nd, NULLNODE, &dt);
/* Ignore other arguments to NEW and/or DISPOSE ??? */
FreeNode(expp->nd_left);
dt.tk_symb = IDENT;
dt.tk_lineno = expp->nd_left->nd_lineno;
dt.TOK_IDF = str2idf(std == S_NEW ?
"ALLOCATE" : "DEALLOCATE", 0);
expp->nd_left = MkLeaf(Name, &dt);
}
return chk_call(expp);
case S_TSIZE: /* ??? */ case S_TSIZE: /* ??? */
case S_SIZE: case S_SIZE:
expp->nd_type = intorcard_type; expp->nd_type = intorcard_type;
@ -1080,5 +1123,6 @@ int (*ChkTable[])() = {
chk_set, chk_set,
NodeCrash, NodeCrash,
NodeCrash, NodeCrash,
chk_linkorname chk_linkorname,
NodeCrash
}; };

View file

@ -21,9 +21,8 @@ static char *RcsId = "$Header$";
#include "node.h" #include "node.h"
#include "Lpars.h" #include "Lpars.h"
#include "standards.h" #include "standards.h"
#include "walk.h"
extern label data_label();
extern label text_label();
extern char *long2str(); extern char *long2str();
extern char *symbol2str(); extern char *symbol2str();
extern int proclevel; extern int proclevel;
@ -43,7 +42,7 @@ CodeConst(cst, size)
C_ldc(cst); C_ldc(cst);
} }
else { else {
C_df_dlb(dlab = data_label()); C_df_dlb(dlab = ++data_label);
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);
@ -59,7 +58,7 @@ CodeString(nd)
C_loc(nd->nd_INT); C_loc(nd->nd_INT);
} }
else { else {
C_df_dlb(lab = data_label()); C_df_dlb(lab = ++data_label);
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);
} }
@ -88,7 +87,7 @@ CodePadString(nd, sz)
CodeReal(nd) CodeReal(nd)
register struct node *nd; register struct node *nd;
{ {
label lab = data_label(); label lab = ++data_label;
C_df_dlb(lab); C_df_dlb(lab);
C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size); C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
@ -114,6 +113,7 @@ CodeExpr(nd, ds, true_label, false_label)
/* Fall through */ /* Fall through */
case Link: case Link:
case LinkDef:
case Arrsel: case Arrsel:
case Arrow: case Arrow:
CodeDesig(nd, ds); CodeDesig(nd, ds);
@ -290,6 +290,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 type *result_tp;
if (left->nd_type == std_type) { if (left->nd_type == std_type) {
CodeStd(nd); CodeStd(nd);
@ -308,7 +309,7 @@ CodeCall(nd)
assert(IsProcCall(left)); assert(IsProcCall(left));
if (nd->nd_right) { if (nd->nd_right) {
CodeParameters(left->nd_type->prc_params, nd->nd_right); CodeParameters(ParamList(left->nd_type), nd->nd_right);
} }
if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) { if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) {
@ -325,8 +326,12 @@ CodeCall(nd)
C_cai(); C_cai();
} }
if (left->nd_type->prc_nbpar) C_asp(left->nd_type->prc_nbpar); if (left->nd_type->prc_nbpar) C_asp(left->nd_type->prc_nbpar);
if (left->nd_type->next) { if (result_tp = ResultType(left->nd_type)) {
C_lfr(WA(left->nd_type->next->tp_size)); if (IsConstructed(result_tp)) {
C_lfr(pointer_size);
C_loi(result_tp->tp_size);
}
else C_lfr(WA(result_tp->tp_size));
} }
} }
@ -765,6 +770,7 @@ CodeOper(expr, true_label, false_label)
C_com(tp->tp_size); C_com(tp->tp_size);
C_and(tp->tp_size); C_and(tp->tp_size);
C_ior(tp->tp_size); C_ior(tp->tp_size);
C_zer(tp->tp_size);
} }
C_cms(tp->tp_size); C_cms(tp->tp_size);
break; break;
@ -795,10 +801,10 @@ CodeOper(expr, true_label, false_label)
case AND: case AND:
case '&': case '&':
if (true_label == 0) { if (true_label == 0) {
label l_true = text_label(); label l_true = ++text_label;
label l_false = text_label(); label l_false = ++text_label;
label l_maybe = text_label(); label l_maybe = ++text_label;
label l_end = text_label(); label l_end = ++text_label;
struct desig Des; struct desig Des;
Des = InitDesig; Des = InitDesig;
@ -814,7 +820,7 @@ CodeOper(expr, true_label, false_label)
C_df_ilb(l_end); C_df_ilb(l_end);
} }
else { else {
label l_maybe = text_label(); label l_maybe = ++text_label;
struct desig Des; struct desig Des;
Des = InitDesig; Des = InitDesig;
@ -826,10 +832,10 @@ CodeOper(expr, true_label, false_label)
break; break;
case OR: case OR:
if (true_label == 0) { if (true_label == 0) {
label l_true = text_label(); label l_true = ++text_label;
label l_false = text_label(); label l_false = ++text_label;
label l_maybe = text_label(); label l_maybe = ++text_label;
label l_end = text_label(); label l_end = ++text_label;
struct desig Des; struct desig Des;
Des = InitDesig; Des = InitDesig;
@ -845,7 +851,7 @@ CodeOper(expr, true_label, false_label)
C_df_ilb(l_end); C_df_ilb(l_end);
} }
else { else {
label l_maybe = text_label(); label l_maybe = ++text_label;
struct desig Des; struct desig Des;
Des = InitDesig; Des = InitDesig;
@ -1026,13 +1032,10 @@ CodeDStore(nd)
DoHIGH(nd) DoHIGH(nd)
struct node *nd; struct node *nd;
{ {
register struct def *df; register struct def *df = nd->nd_def;
arith highoff; register arith highoff;
assert(nd->nd_class == Def); assert(nd->nd_class == Def);
df = nd->nd_def;
assert(df->df_kind == D_VARIABLE); assert(df->df_kind == D_VARIABLE);
highoff = df->var_off + pointer_size + word_size; highoff = df->var_off + pointer_size + word_size;

View file

@ -21,23 +21,31 @@ static char *RcsId = "$Header$";
#include "misc.h" #include "misc.h"
#include "main.h" #include "main.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
procedure or function
*/
} }
ProcedureDeclaration ProcedureDeclaration
{ {
struct def *df; register struct def *df;
struct def *df1;
} : } :
{ proclevel++; } { proclevel++; }
ProcedureHeading(&df, D_PROCEDURE) ProcedureHeading(&df1, D_PROCEDURE)
{ {
CurrentScope->sc_definedby = df; CurrentScope->sc_definedby = df = df1;
df->prc_vis = CurrVis; df->prc_vis = CurrVis;
return_occurred = 0;
} }
';' block(&(df->prc_body)) IDENT ';' block(&(df->prc_body)) IDENT
{ {
match_id(dot.TOK_IDF, df->df_idf); match_id(dot.TOK_IDF, df->df_idf);
close_scope(SC_CHKFORW|SC_REVERSE); close_scope(SC_CHKFORW|SC_REVERSE);
if (! return_occurred && ResultType(df->df_type)) {
error("function procedure does not return a value", df->df_idf->id_text);
}
proclevel--; proclevel--;
} }
; ;

View file

@ -311,7 +311,7 @@ CodeDesig(nd, ds)
} }
break; break;
case Link: case LinkDef:
assert(nd->nd_symb == '.'); assert(nd->nd_symb == '.');
CodeDesig(nd->nd_left, ds); CodeDesig(nd->nd_left, ds);

View file

@ -26,26 +26,31 @@ lookup(id, scope)
Return a pointer to its "def" structure if it exists, Return a pointer to its "def" structure if it exists,
otherwise return 0. otherwise return 0.
*/ */
register struct def *df; register struct def *df, *df1;
struct def *df1;
for (df = id->id_def, df1 = 0; df; df1 = df, df = df->next) { /* Look in the chain of definitions of this "id" for one with scope
if (df->df_scope == scope) { "scope".
if (df1) { */
/* Put the definition in front for (df = id->id_def, df1 = 0;
*/ df && df->df_scope != scope;
df1->next = df->next; df1 = df, df = df->next) { /* nothing */ }
df->next = id->id_def;
id->id_def = df; if (df) {
} /* Found it
if (df->df_kind == D_IMPORT) { */
assert(df->imp_def != 0); if (df1) {
return df->imp_def; /* Put the definition in front
} */
return df; df1->next = df->next;
df->next = id->id_def;
id->id_def = df;
}
if (df->df_kind == D_IMPORT) {
assert(df->imp_def != 0);
return df->imp_def;
} }
} }
return 0; return df;
} }
struct def * struct def *
@ -57,7 +62,7 @@ lookfor(id, vis, give_error)
If it is not defined create a dummy definition and, If it is not defined create a dummy definition and,
if "give_error" is set, give an error message. if "give_error" is set, give an error message.
*/ */
struct def *df; register struct def *df;
register struct scopelist *sc = vis; register struct scopelist *sc = vis;
while (sc) { while (sc) {

View file

@ -159,6 +159,8 @@ AddStandards()
(void) Enter("DEC", D_PROCEDURE, std_type, S_DEC); (void) Enter("DEC", D_PROCEDURE, std_type, S_DEC);
(void) Enter("INC", D_PROCEDURE, std_type, S_INC); (void) Enter("INC", D_PROCEDURE, std_type, S_INC);
(void) Enter("VAL", D_PROCEDURE, std_type, S_VAL); (void) Enter("VAL", D_PROCEDURE, std_type, S_VAL);
(void) Enter("NEW", D_PROCEDURE, std_type, S_NEW);
(void) Enter("DISPOSE", D_PROCEDURE, std_type, S_DISPOSE);
(void) Enter("TRUNC", D_PROCEDURE, std_type, S_TRUNC); (void) Enter("TRUNC", D_PROCEDURE, std_type, S_TRUNC);
(void) Enter("SIZE", D_PROCEDURE, std_type, S_SIZE); (void) Enter("SIZE", D_PROCEDURE, std_type, S_SIZE);
(void) Enter("ORD", D_PROCEDURE, std_type, S_ORD); (void) Enter("ORD", D_PROCEDURE, std_type, S_ORD);

View file

@ -19,6 +19,7 @@ struct node {
#define Def 9 /* an identified name */ #define Def 9 /* an identified name */
#define Stat 10 /* a statement */ #define Stat 10 /* a statement */
#define Link 11 #define Link 11
#define LinkDef 12
/* do NOT change the order or the numbers!!! */ /* do NOT change the order or the numbers!!! */
struct type *nd_type; /* type of this node */ struct type *nd_type; /* type of this node */
struct token nd_token; struct token nd_token;
@ -40,10 +41,9 @@ extern struct node *MkNode(), *MkLeaf();
#define NULLNODE ((struct node *) 0) #define NULLNODE ((struct node *) 0)
#define DESIGNATOR 1 #define HASSELECTORS 002
#define HASSELECTORS 2 #define VARIABLE 004
#define VARIABLE 4 #define VALUE 010
#define VALUE 8
#define IsCast(lnd) ((lnd)->nd_class == Def && is_type((lnd)->nd_def)) #define IsCast(lnd) (((lnd)->nd_class == Def || (lnd)->nd_class == LinkDef) && is_type((lnd)->nd_def))
#define IsProcCall(lnd) ((lnd)->nd_type->tp_fund == T_PROCEDURE) #define IsProcCall(lnd) ((lnd)->nd_type->tp_fund == T_PROCEDURE)

View file

@ -19,6 +19,8 @@
#define S_SIZE 15 #define S_SIZE 15
#define S_TRUNC 16 #define S_TRUNC 16
#define S_VAL 17 #define S_VAL 17
#define S_NEW 18
#define S_DISPOSE 19
/* Standard procedures and functions defined in the SYSTEM module ... */ /* Standard procedures and functions defined in the SYSTEM module ... */

View file

@ -229,9 +229,12 @@ 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

@ -74,7 +74,7 @@ struct type {
#define T_NUMERIC (T_INTORCARD|T_REAL) #define T_NUMERIC (T_INTORCARD|T_REAL)
#define T_INDEX (T_ENUMERATION|T_CHAR|T_SUBRANGE) #define T_INDEX (T_ENUMERATION|T_CHAR|T_SUBRANGE)
#define T_DISCRETE (T_INDEX|T_INTORCARD) #define T_DISCRETE (T_INDEX|T_INTORCARD)
#define T_PRCRESULT (T_DISCRETE|T_REAL|T_POINTER|T_WORD) #define T_CONSTRUCTED (T_ARRAY|T_SET|T_RECORD)
int tp_align; /* alignment requirement of this type */ int tp_align; /* alignment requirement of this type */
arith tp_size; /* size of this type */ arith tp_size; /* size of this type */
union { union {
@ -136,6 +136,8 @@ struct type
#define IsConformantArray(tpx) ((tpx)->tp_fund==T_ARRAY && (tpx)->next==0) #define IsConformantArray(tpx) ((tpx)->tp_fund==T_ARRAY && (tpx)->next==0)
#define bounded(tpx) ((tpx)->tp_fund & T_INDEX) #define bounded(tpx) ((tpx)->tp_fund & T_INDEX)
#define complex(tpx) ((tpx)->tp_fund & (T_RECORD|T_ARRAY)) #define complex(tpx) ((tpx)->tp_fund & (T_RECORD|T_ARRAY))
#define returntype(tpx) (((tpx)->tp_fund & T_PRCRESULT) ||\
((tpx)->tp_fund == T_SET && (tpx)->tp_size <= dword_size))
#define WA(sz) (align(sz, (int) word_size)) #define WA(sz) (align(sz, (int) word_size))
#define ResultType(tpx) (assert((tpx)->tp_fund == T_PROCEDURE), (tpx)->next)
#define ParamList(tpx) (assert((tpx)->tp_fund == T_PROCEDURE),\
(tpx)->prc_params)
#define IsConstructed(tpx) ((tpx)->tp_fund & T_CONSTRUCTED)

View file

@ -20,6 +20,7 @@ static char *RcsId = "$Header$";
#include "node.h" #include "node.h"
#include "const.h" #include "const.h"
#include "scope.h" #include "scope.h"
#include "walk.h"
int int
word_align = AL_WORD, word_align = AL_WORD,
@ -64,8 +65,6 @@ struct type *h_type;
int cnt_type; int cnt_type;
#endif #endif
extern label data_label();
struct type * struct type *
create_type(fund) create_type(fund)
int fund; int fund;
@ -93,10 +92,6 @@ construct_type(fund, tp)
switch (fund) { switch (fund) {
case T_PROCEDURE: case T_PROCEDURE:
if (tp && !returntype(tp)) {
error("illegal procedure result type");
}
/* Fall through */
case T_POINTER: case T_POINTER:
case T_HIDDEN: case T_HIDDEN:
dtp->tp_align = pointer_align; dtp->tp_align = pointer_align;
@ -315,11 +310,11 @@ genrck(tp)
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 = l = ++data_label;
} }
} }
else if (!(ol = tp->enm_rck)) { else if (!(ol = tp->enm_rck)) {
tp->enm_rck = l = data_label(); tp->enm_rck = l = ++data_label;
} }
if (!ol) { if (!ol) {
ol = l; ol = l;
@ -423,7 +418,7 @@ ArraySizes(tp)
/* generate descriptor and remember label. /* generate descriptor and remember label.
*/ */
tp->arr_descr = data_label(); tp->arr_descr = ++data_label;
C_df_dlb(tp->arr_descr); C_df_dlb(tp->arr_descr);
C_rom_cst(lo); C_rom_cst(lo);
C_rom_cst(hi - lo); C_rom_cst(hi - lo);
@ -441,7 +436,7 @@ FreeType(tp)
assert(tp->tp_fund == T_PROCEDURE); assert(tp->tp_fund == T_PROCEDURE);
pr = tp->prc_params; pr = ParamList(tp);
while (pr) { while (pr) {
pr1 = pr; pr1 = pr;
pr = pr->next; pr = pr->next;
@ -516,7 +511,7 @@ DumpType(tp)
break; break;
case T_PROCEDURE: case T_PROCEDURE:
{ {
register struct paramlist *par = tp->prc_params; register struct paramlist *par = ParamList(tp);
print("PROCEDURE"); print("PROCEDURE");
if (par) { if (par) {
@ -541,7 +536,7 @@ DumpType(tp)
case T_INTORCARD: case T_INTORCARD:
print("INTORCARD"); break; print("INTORCARD"); break;
default: default:
assert(0); crash("DumpType");
} }
print(";"); print(";");
} }

View file

@ -7,8 +7,11 @@ static char *RcsId = "$Header$";
/* Routines for testing type equivalence, type compatibility, and /* Routines for testing type equivalence, type compatibility, and
assignment compatibility assignment compatibility
*/ */
#include "debug.h"
#include <em_arith.h> #include <em_arith.h>
#include <em_label.h> #include <em_label.h>
#include <assert.h>
#include "type.h" #include "type.h"
#include "def.h" #include "def.h"
@ -66,8 +69,8 @@ TstProcEquiv(tp1, tp2)
*/ */
if (! TstTypeEquiv(tp1->next, tp2->next)) return 0; if (! TstTypeEquiv(tp1->next, tp2->next)) return 0;
p1 = tp1->prc_params; p1 = ParamList(tp1);
p2 = tp2->prc_params; p2 = ParamList(tp2);
/* Now check the parameters /* Now check the parameters
*/ */
@ -180,6 +183,10 @@ TstParCompat(formaltype, actualtype, VARflag, nd)
TstTypeEquiv(formaltype, actualtype) TstTypeEquiv(formaltype, actualtype)
|| ||
( !VARflag && TstAssCompat(formaltype, actualtype)) ( !VARflag && TstAssCompat(formaltype, actualtype))
||
( formaltype == address_type
&& actualtype->tp_fund == T_POINTER
)
|| ||
( formaltype == word_type ( formaltype == word_type
&& &&

View file

@ -26,31 +26,18 @@ static char *RcsId = "$Header$";
#include "f_info.h" #include "f_info.h"
#include "idf.h" #include "idf.h"
#include "chk_expr.h" #include "chk_expr.h"
#include "walk.h"
extern arith NewPtr(); extern arith NewPtr();
extern arith NewInt(); extern arith NewInt();
extern int proclevel; extern int proclevel;
static label instructionlabel; label text_label;
static char return_expr_occurred; label data_label;
static struct type *func_type; static struct type *func_type;
struct withdesig *WithDesigs; struct withdesig *WithDesigs;
struct node *Modules; struct node *Modules;
struct scope *ProcScope; struct scope *ProcScope;
label
text_label()
{
return instructionlabel++;
}
label
data_label()
{
static label datalabel = 0;
return ++datalabel;
}
STATIC STATIC
DoProfil() DoProfil()
{ {
@ -58,7 +45,7 @@ DoProfil()
if (! options['L']) { if (! options['L']) {
if (!filename_label) { if (!filename_label) {
filename_label = data_label(); filename_label = ++data_label;
C_df_dlb(filename_label); C_df_dlb(filename_label);
C_rom_scon(FileName, (arith) (strlen(FileName) + 1)); C_rom_scon(FileName, (arith) (strlen(FileName) + 1));
} }
@ -73,7 +60,6 @@ WalkModule(module)
/* Walk through a module, and all its local definitions. /* Walk through a module, and all its local definitions.
Also generate code for its body. Also generate code for its body.
*/ */
register struct def *df = module->mod_vis->sc_scope->sc_def;
register struct scope *sc; register struct scope *sc;
struct scopelist *vis; struct scopelist *vis;
@ -81,20 +67,10 @@ WalkModule(module)
CurrVis = module->mod_vis; CurrVis = module->mod_vis;
sc = CurrentScope; sc = CurrentScope;
if (!proclevel) { if (!proclevel && module == Defined) {
/* This module is a glocal module. /* This module is a global module. Export the name of its
Generate code to allocate storage for its variables. initialization routine
They all have an explicit name.
*/ */
while (df) {
if (df->df_kind == D_VARIABLE) {
C_df_dnam(df->var_name);
C_bss_cst(
WA(df->df_type->tp_size),
(arith) 0, 0);
}
df = df->df_nextinscope;
}
if (state == PROGRAM) C_exp("main"); if (state == PROGRAM) C_exp("main");
else C_exp(sc->sc_name); else C_exp(sc->sc_name);
} }
@ -108,12 +84,11 @@ WalkModule(module)
this module. this module.
*/ */
sc->sc_off = 0; sc->sc_off = 0;
instructionlabel = 2; text_label = 1;
func_type = 0;
ProcScope = CurrentScope; ProcScope = CurrentScope;
C_pro_narg(state == PROGRAM ? "main" : sc->sc_name); C_pro_narg(state==PROGRAM && module==Defined ? "main" : sc->sc_name);
DoProfil(); DoProfil();
if (CurrVis == Defined->mod_vis) { if (module == Defined) {
/* Body of implementation or program module. /* Body of implementation or program module.
Call initialization routines of imported modules. Call initialization routines of imported modules.
Also prevent recursive calls of this one. Also prevent recursive calls of this one.
@ -121,7 +96,7 @@ WalkModule(module)
struct node *nd; struct node *nd;
if (state == IMPLEMENTATION) { if (state == IMPLEMENTATION) {
label l1 = data_label(); label l1 = ++data_label;
/* we don't actually prevent recursive calls, /* we don't actually prevent recursive calls,
but do nothing if called recursively but do nothing if called recursively
*/ */
@ -157,44 +132,73 @@ WalkProcedure(procedure)
/* Walk through the definition of a procedure and all its /* Walk through the definition of a procedure and all its
local definitions local definitions
*/ */
struct scopelist *vis = CurrVis; struct scopelist *savevis = CurrVis;
register struct scope *sc; register struct scope *sc;
register struct type *tp; register struct type *tp;
register struct paramlist *param; register struct paramlist *param;
label func_res_label = 0;
proclevel++; proclevel++;
CurrVis = procedure->prc_vis; CurrVis = procedure->prc_vis;
ProcScope = sc = CurrentScope; ProcScope = sc = CurrentScope;
/* Generate code for all local modules and procedures
*/
WalkDef(sc->sc_def); WalkDef(sc->sc_def);
/* Generate code for this procedure /* Generate code for this procedure
*/ */
C_pro_narg(sc->sc_name); C_pro_narg(sc->sc_name);
DoProfil(); DoProfil();
/* generate calls to initialization routines of modules defined within
/* Generate calls to initialization routines of modules defined within
this procedure this procedure
*/ */
MkCalls(sc->sc_def); MkCalls(sc->sc_def);
return_expr_occurred = 0;
instructionlabel = 2; /* Make sure that arguments of size < word_size are on a
func_type = tp = procedure->df_type->next; fixed place.
if (! returntype(tp)) { */
node_error(procedure->prc_body, "illegal result type"); for (param = ParamList(procedure->df_type);
} param;
WalkNode(procedure->prc_body, (label) 0); param = param->next) {
C_df_ilb((label) 1); if (! IsVarParam(param)) {
if (tp) { tp = TypeOfParam(param);
if (! return_expr_occurred) {
node_error(procedure->prc_body,"function procedure does not return a value"); if (!IsConformantArray(tp) && tp->tp_size < word_size) {
C_lol(param->par_def->var_off);
C_lal(param->par_def->var_off);
C_sti(tp->tp_size);
}
} }
C_ret(WA(tp->tp_size));
} }
else C_ret((arith) 0);
text_label = 1;
func_type = tp = ResultType(procedure->df_type);
if (IsConstructed(tp)) {
func_res_label = ++data_label;
C_df_dlb(func_res_label);
C_bss_cst(tp->tp_size, (arith) 0, 0);
}
WalkNode(procedure->prc_body, (label) 0);
C_ret((arith) 0);
if (tp) {
C_df_ilb((label) 1);
if (func_res_label) {
C_lae_dlb(func_res_label, (arith) 0);
C_sti(tp->tp_size);
C_lae_dlb(func_res_label, (arith) 0);
C_ret(pointer_size);
}
else C_ret(WA(tp->tp_size));
}
RegisterMessages(sc->sc_def); RegisterMessages(sc->sc_def);
C_end(-sc->sc_off); C_end(-sc->sc_off);
TmpClose(); TmpClose();
CurrVis = vis; CurrVis = savevis;
proclevel--; proclevel--;
} }
@ -211,6 +215,12 @@ WalkDef(df)
else if (df->df_kind == D_PROCEDURE) { else if (df->df_kind == D_PROCEDURE) {
WalkProcedure(df); WalkProcedure(df);
} }
else if (!proclevel && df->df_kind == D_VARIABLE) {
C_df_dnam(df->var_name);
C_bss_cst(
WA(df->df_type->tp_size),
(arith) 0, 0);
}
df = df->df_nextinscope; df = df->df_nextinscope;
} }
} }
@ -231,22 +241,36 @@ MkCalls(df)
} }
} }
WalkNode(nd, lab) WalkLink(nd, lab)
register struct node *nd; register struct node *nd;
label lab; label lab;
{ {
/* Node "nd" represents either a statement or a statement list. /* Walk node "nd", which is a link.
Walk through it.
"lab" represents the label that must be jumped to on "lab" represents the label that must be jumped to on
encountering an EXIT statement. encountering an EXIT statement.
*/ */
while (nd->nd_class == Link) { /* statement list */ while (nd && nd->nd_class == Link) { /* statement list */
WalkStat(nd->nd_left, lab); WalkNode(nd->nd_left, lab);
nd = nd->nd_right; nd = nd->nd_right;
} }
WalkStat(nd, lab); WalkNode(nd, lab);
}
WalkCall(nd)
register struct node *nd;
{
assert(nd->nd_class == Call);
if (! options['L']) C_lin((arith) nd->nd_lineno);
if (chk_call(nd)) {
if (nd->nd_type != 0) {
node_error(nd, "procedure call expected");
return;
}
CodeCall(nd);
}
} }
WalkStat(nd, lab) WalkStat(nd, lab)
@ -260,27 +284,9 @@ WalkStat(nd, lab)
register struct node *left = nd->nd_left; register struct node *left = nd->nd_left;
register struct node *right = nd->nd_right; register struct node *right = nd->nd_right;
if (!nd) {
/* Empty statement
*/
return;
}
if (! options['L']) C_lin((arith) nd->nd_lineno);
if (nd->nd_class == Call) {
if (chk_call(nd)) {
if (nd->nd_type != 0) {
node_error(nd, "procedure call expected");
return;
}
CodeCall(nd);
}
return;
}
assert(nd->nd_class == Stat); assert(nd->nd_class == Stat);
if (! options['L']) C_lin((arith) nd->nd_lineno);
switch(nd->nd_symb) { switch(nd->nd_symb) {
case BECOMES: case BECOMES:
DoAssign(nd, left, right); DoAssign(nd, left, right);
@ -289,9 +295,9 @@ WalkStat(nd, lab)
case IF: case IF:
{ label l1, l2, l3; { label l1, l2, l3;
l1 = instructionlabel++; l1 = ++text_label;
l2 = instructionlabel++; l2 = ++text_label;
l3 = instructionlabel++; 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);
@ -314,9 +320,9 @@ WalkStat(nd, lab)
case WHILE: case WHILE:
{ label l1, l2, l3; { label l1, l2, l3;
l1 = instructionlabel++; l1 = ++text_label;
l2 = instructionlabel++; l2 = ++text_label;
l3 = instructionlabel++; l3 = ++text_label;
C_df_ilb(l1); C_df_ilb(l1);
ExpectBool(left, l3, l2); ExpectBool(left, l3, l2);
C_df_ilb(l3); C_df_ilb(l3);
@ -329,8 +335,8 @@ WalkStat(nd, lab)
case REPEAT: case REPEAT:
{ label l1, l2; { label l1, l2;
l1 = instructionlabel++; l1 = ++text_label;
l2 = instructionlabel++; l2 = ++text_label;
C_df_ilb(l1); C_df_ilb(l1);
WalkNode(left, lab); WalkNode(left, lab);
ExpectBool(right, l2, l1); ExpectBool(right, l2, l1);
@ -341,8 +347,8 @@ WalkStat(nd, lab)
case LOOP: case LOOP:
{ label l1, l2; { label l1, l2;
l1 = instructionlabel++; l1 = ++text_label;
l2 = instructionlabel++; l2 = ++text_label;
C_df_ilb(l1); C_df_ilb(l1);
WalkNode(right, l2); WalkNode(right, l2);
C_bra(l1); C_bra(l1);
@ -354,8 +360,8 @@ WalkStat(nd, lab)
{ {
arith tmp = 0; arith tmp = 0;
struct node *fnd; struct node *fnd;
label l1 = instructionlabel++; label l1 = ++text_label;
label l2 = instructionlabel++; label l2 = ++text_label;
if (! DoForInit(nd, left)) break; if (! DoForInit(nd, left)) break;
fnd = left->nd_right; fnd = left->nd_right;
@ -432,14 +438,16 @@ WalkStat(nd, lab)
case RETURN: case RETURN:
if (right) { if (right) {
WalkExpr(right); WalkExpr(right);
/* Assignment compatibility? Yes, see Rep. 9.11 /* The type of the return-expression must be
assignment compatible with the result type of the
function procedure (See Rep. 9.11).
*/ */
if (!TstAssCompat(func_type, right->nd_type)) { if (!TstAssCompat(func_type, right->nd_type)) {
node_error(right, "type incompatibility in RETURN statement"); node_error(right, "type incompatibility in RETURN statement");
} }
return_expr_occurred = 1; C_bra((label) 1);
} }
C_bra((label) 1); else C_ret((arith) 0);
break; break;
default: default:
@ -447,6 +455,24 @@ node_error(right, "type incompatibility in RETURN statement");
} }
} }
extern int NodeCrash();
int (*WalkTable[])() = {
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
WalkCall,
NodeCrash,
NodeCrash,
NodeCrash,
NodeCrash,
WalkStat,
WalkLink,
NodeCrash
};
ExpectBool(nd, true_label, false_label) ExpectBool(nd, true_label, false_label)
register struct node *nd; register struct node *nd;
label true_label, false_label; label true_label, false_label;
@ -488,7 +514,7 @@ WalkDesignator(nd, ds)
DO_DEBUG(1, (DumpTree(nd), print("\n"))); DO_DEBUG(1, (DumpTree(nd), print("\n")));
if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return; if (! chk_designator(nd, VARIABLE, D_DEFINED)) return;
*ds = InitDesig; *ds = InitDesig;
CodeDesig(nd, ds); CodeDesig(nd, ds);
@ -497,6 +523,7 @@ WalkDesignator(nd, ds)
DoForInit(nd, left) DoForInit(nd, left)
register struct node *nd, *left; register struct node *nd, *left;
{ {
register struct def *df;
nd->nd_left = nd->nd_right = 0; nd->nd_left = nd->nd_right = 0;
nd->nd_class = Name; nd->nd_class = Name;
@ -506,6 +533,30 @@ DoForInit(nd, left)
! chk_expr(left->nd_left) || ! chk_expr(left->nd_left) ||
! chk_expr(left->nd_right)) return 0; ! chk_expr(left->nd_right)) return 0;
df = nd->nd_def;
if (df->df_kind == D_FIELD) {
node_error(nd, "FOR-loop variable may not be a field of a record");
return 0;
}
if (!df->var_name && df->var_off >= 0) {
node_error(nd, "FOR-loop variable may not be a parameter");
return 0;
}
if (df->df_scope != CurrentScope) {
register struct scopelist *sc = CurrVis;
while (sc && sc->sc_scope != df->df_scope) {
sc = nextvisible(sc);
}
if (!sc) {
node_error(nd, "FOR-loop variable may not be imported");
return 0;
}
}
if (nd->nd_type->tp_size > word_size || if (nd->nd_type->tp_size > word_size ||
!(nd->nd_type->tp_fund & T_DISCRETE)) { !(nd->nd_type->tp_fund & T_DISCRETE)) {
node_error(nd, "illegal type of FOR loop variable"); node_error(nd, "illegal type of FOR loop variable");
@ -536,7 +587,7 @@ DoAssign(nd, left, right)
struct desig dsl, dsr; struct desig dsl, dsr;
if (!chk_expr(right)) return; if (!chk_expr(right)) return;
if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return; if (! chk_designator(left, VARIABLE, D_DEFINED)) return;
TryToString(right, left->nd_type); TryToString(right, left->nd_type);
dsr = InitDesig; dsr = InitDesig;
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL); CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);

13
lang/m2/comp/walk.h Normal file
View file

@ -0,0 +1,13 @@
/* P A R S E T R E E W A L K E R */
/* $Header$ */
/* Definition of WalkNode macro
*/
extern int (*WalkTable[])();
#define WalkNode(xnd, xlab) ((xnd) && (*WalkTable[(xnd)->nd_class])((xnd), (xlab)))
extern label text_label;
extern label data_label;