newer version
This commit is contained in:
parent
53255dcf48
commit
6715e3b171
|
@ -76,7 +76,7 @@ GetString(upto)
|
||||||
register struct string *str = &string;
|
register struct string *str = &string;
|
||||||
register char *p;
|
register char *p;
|
||||||
|
|
||||||
str->s_str = p = Malloc((unsigned) (str->s_length = ISTRSIZE));
|
str->s_str = p = Malloc(str->s_length = ISTRSIZE);
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
while (ch != upto) {
|
while (ch != upto) {
|
||||||
if (class(ch) == STNL) {
|
if (class(ch) == STNL) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ hfiles: Parameters make.hfiles
|
||||||
touch hfiles
|
touch hfiles
|
||||||
|
|
||||||
main: $(OBJ) Makefile
|
main: $(OBJ) Makefile
|
||||||
$(CC) $(LFLAGS) $(OBJ) $(LIBDIR)/libcomp.a $(LIBDIR)/malloc.o /user1/erikb/em/lib/libprint.a /user1/erikb/em/lib/libstr.a /user1/erikb/em/lib/libsystem.a -o main
|
$(CC) $(LFLAGS) $(OBJ) /user1/erikb/em/lib/libem_mes.a /user1/erikb/em/lib/libeme.a $(LIBDIR)/libcomp.a $(LIBDIR)/malloc.o /user1/erikb/em/lib/libprint.a /user1/erikb/em/lib/libstr.a /user1/erikb/em/lib/libsystem.a -o main
|
||||||
size main
|
size main
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -91,12 +91,13 @@ type.o: LLlex.h const.h debug.h def.h idf.h node.h target_sizes.h type.h
|
||||||
def.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h
|
def.o: LLlex.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 def.h idf.h node.h scope.h type.h
|
enter.o: LLlex.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 scope.h
|
defmodule.o: LLlex.h debug.h def.h f_info.h idf.h input.h inputtype.h scope.h
|
||||||
typequiv.o: def.h type.h
|
typequiv.o: def.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 idf.h node.h standards.h target_sizes.h type.h
|
cstoper.o: LLlex.h Lpars.h idf.h node.h standards.h target_sizes.h type.h
|
||||||
chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
|
chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
|
||||||
|
options.o: idfsize.h type.h
|
||||||
tokenfile.o: Lpars.h
|
tokenfile.o: Lpars.h
|
||||||
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
|
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
|
||||||
declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h
|
declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h
|
||||||
|
|
|
@ -23,7 +23,7 @@ STEOI:\200
|
||||||
% INIDF
|
% INIDF
|
||||||
%
|
%
|
||||||
%C
|
%C
|
||||||
1:a-zA-Z_0-9
|
1:a-zA-Z0-9
|
||||||
%Tchar inidf[] = {
|
%Tchar inidf[] = {
|
||||||
%F %s,
|
%F %s,
|
||||||
%p
|
%p
|
||||||
|
|
|
@ -8,6 +8,7 @@ static char *RcsId = "$Header$";
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
|
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
@ -17,6 +18,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -25,7 +27,7 @@ chk_expr(expp)
|
||||||
{
|
{
|
||||||
/* Check the expression indicated by expp for semantic errors,
|
/* Check the expression indicated by expp for semantic errors,
|
||||||
identify identifiers used in it, replace constants by
|
identify identifiers used in it, replace constants by
|
||||||
their value.
|
their value, and try to evaluate the expression.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch(expp->nd_class) {
|
switch(expp->nd_class) {
|
||||||
|
@ -33,25 +35,32 @@ chk_expr(expp)
|
||||||
return chk_expr(expp->nd_left) &&
|
return chk_expr(expp->nd_left) &&
|
||||||
chk_expr(expp->nd_right) &&
|
chk_expr(expp->nd_right) &&
|
||||||
chk_oper(expp);
|
chk_oper(expp);
|
||||||
|
|
||||||
case Uoper:
|
case Uoper:
|
||||||
return chk_expr(expp->nd_right) &&
|
return chk_expr(expp->nd_right) &&
|
||||||
chk_uoper(expp);
|
chk_uoper(expp);
|
||||||
|
|
||||||
case Value:
|
case Value:
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case REAL:
|
case REAL:
|
||||||
case STRING:
|
case STRING:
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Xset:
|
case Xset:
|
||||||
return chk_set(expp);
|
return chk_set(expp);
|
||||||
|
|
||||||
case Name:
|
case Name:
|
||||||
return chk_name(expp);
|
return chk_name(expp);
|
||||||
|
|
||||||
case Call:
|
case Call:
|
||||||
return chk_call(expp);
|
return chk_call(expp);
|
||||||
|
|
||||||
case Link:
|
case Link:
|
||||||
return chk_name(expp);
|
return chk_name(expp);
|
||||||
default:
|
default:
|
||||||
|
@ -82,9 +91,9 @@ chk_set(expp)
|
||||||
findname(expp->nd_left);
|
findname(expp->nd_left);
|
||||||
assert(expp->nd_left->nd_class == Def);
|
assert(expp->nd_left->nd_class == Def);
|
||||||
df = expp->nd_left->nd_def;
|
df = expp->nd_left->nd_def;
|
||||||
if ((df->df_kind != D_TYPE && df->df_kind != D_ERROR) ||
|
if (!(df->df_kind & (D_TYPE|D_ERROR)) ||
|
||||||
(df->df_type->tp_fund != T_SET)) {
|
(df->df_type->tp_fund != T_SET)) {
|
||||||
node_error(expp, "Illegal set type");
|
node_error(expp, "illegal set type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tp = df->df_type;
|
tp = df->df_type;
|
||||||
|
@ -93,7 +102,8 @@ chk_set(expp)
|
||||||
|
|
||||||
/* Now check the elements given, and try to compute a constant set.
|
/* Now check the elements given, and try to compute a constant set.
|
||||||
*/
|
*/
|
||||||
set = (arith *) Malloc(tp->tp_size * sizeof(arith) / word_size);
|
set = (arith *)
|
||||||
|
Malloc((unsigned) (tp->tp_size * sizeof(arith) / word_size));
|
||||||
nd = expp->nd_right;
|
nd = expp->nd_right;
|
||||||
while (nd) {
|
while (nd) {
|
||||||
assert(nd->nd_class == Link && nd->nd_symb == ',');
|
assert(nd->nd_class == Link && nd->nd_symb == ',');
|
||||||
|
@ -102,7 +112,10 @@ chk_set(expp)
|
||||||
}
|
}
|
||||||
expp->nd_type = tp;
|
expp->nd_type = tp;
|
||||||
if (set) {
|
if (set) {
|
||||||
/* Yes, in 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
|
||||||
|
partial evaluation. Either we evaluate the set, or we
|
||||||
|
don't (at all). Improvement not neccesary. (???)
|
||||||
*/
|
*/
|
||||||
expp->nd_class = Set;
|
expp->nd_class = Set;
|
||||||
expp->nd_set = set;
|
expp->nd_set = set;
|
||||||
|
@ -123,6 +136,8 @@ chk_el(expp, tp, set)
|
||||||
recursively.
|
recursively.
|
||||||
Also try to compute the set!
|
Also try to compute the set!
|
||||||
*/
|
*/
|
||||||
|
register int i;
|
||||||
|
|
||||||
if (expp->nd_class == Link && expp->nd_symb == UPTO) {
|
if (expp->nd_class == Link && expp->nd_symb == UPTO) {
|
||||||
/* { ... , expr1 .. expr2, ... }
|
/* { ... , expr1 .. expr2, ... }
|
||||||
First check expr1 and expr2, and try to compute them.
|
First check expr1 and expr2, and try to compute them.
|
||||||
|
@ -136,10 +151,9 @@ chk_el(expp, tp, set)
|
||||||
/* We have a constant range. Put all elements in the
|
/* We have a constant range. Put all elements in the
|
||||||
set
|
set
|
||||||
*/
|
*/
|
||||||
register int i;
|
|
||||||
|
|
||||||
if (expp->nd_left->nd_INT > expp->nd_right->nd_INT) {
|
if (expp->nd_left->nd_INT > expp->nd_right->nd_INT) {
|
||||||
node_error(expp, "Lower bound exceeds upper bound in range");
|
node_error(expp, "lower bound exceeds upper bound in range");
|
||||||
return rem_set(set);
|
return rem_set(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,20 +175,21 @@ node_error(expp, "Lower bound exceeds upper bound in range");
|
||||||
return rem_set(set);
|
return rem_set(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 rem_set(set);
|
return rem_set(set);
|
||||||
}
|
}
|
||||||
if (expp->nd_class == Value) {
|
if (expp->nd_class == Value) {
|
||||||
|
i = expp->nd_INT;
|
||||||
if ((tp->tp_fund != T_ENUMERATION &&
|
if ((tp->tp_fund != T_ENUMERATION &&
|
||||||
(expp->nd_INT < tp->sub_lb || expp->nd_INT > tp->sub_ub))
|
(i < tp->sub_lb || i > tp->sub_ub))
|
||||||
||
|
||
|
||||||
(tp->tp_fund == T_ENUMERATION &&
|
(tp->tp_fund == T_ENUMERATION &&
|
||||||
(expp->nd_INT < 0 || expp->nd_INT > tp->enm_ncst))
|
(i < 0 || i > tp->enm_ncst))
|
||||||
) {
|
) {
|
||||||
node_error(expp, "Set element out of range");
|
node_error(expp, "set element out of range");
|
||||||
return rem_set(set);
|
return rem_set(set);
|
||||||
}
|
}
|
||||||
if (*set) (*set)[expp->nd_INT/wrd_bits] |= (1 << (expp->nd_INT%wrd_bits));
|
if (*set) (*set)[i/wrd_bits] |= (1 << (i%wrd_bits));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -207,8 +222,8 @@ getarg(argp, bases)
|
||||||
if (!chk_expr(argp->nd_left)) return 0;
|
if (!chk_expr(argp->nd_left)) return 0;
|
||||||
tp = argp->nd_left->nd_type;
|
tp = argp->nd_left->nd_type;
|
||||||
if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
|
if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
|
||||||
if (!(tp->tp_fund & bases)) {
|
if (bases && !(tp->tp_fund & bases)) {
|
||||||
node_error(argp, "Unexpected type");
|
node_error(argp, "unexpected type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return argp;
|
return argp;
|
||||||
|
@ -226,7 +241,7 @@ getname(argp, kinds)
|
||||||
findname(argp->nd_left);
|
findname(argp->nd_left);
|
||||||
assert(argp->nd_left->nd_class == Def);
|
assert(argp->nd_left->nd_class == Def);
|
||||||
if (!(argp->nd_left->nd_def->df_kind & kinds)) {
|
if (!(argp->nd_left->nd_def->df_kind & kinds)) {
|
||||||
node_error(argp, "Unexpected type");
|
node_error(argp, "unexpected type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return argp;
|
return argp;
|
||||||
|
@ -243,6 +258,8 @@ chk_call(expp)
|
||||||
register struct node *left;
|
register struct node *left;
|
||||||
register struct node *arg;
|
register struct node *arg;
|
||||||
|
|
||||||
|
/* First, get the name of the function or procedure
|
||||||
|
*/
|
||||||
expp->nd_type = error_type;
|
expp->nd_type = error_type;
|
||||||
left = expp->nd_left;
|
left = expp->nd_left;
|
||||||
findname(left);
|
findname(left);
|
||||||
|
@ -250,18 +267,18 @@ chk_call(expp)
|
||||||
if (left->nd_type == error_type) return 0;
|
if (left->nd_type == error_type) return 0;
|
||||||
if (left->nd_class == Def &&
|
if (left->nd_class == Def &&
|
||||||
(left->nd_def->df_kind & (D_HTYPE|D_TYPE|D_HIDDEN))) {
|
(left->nd_def->df_kind & (D_HTYPE|D_TYPE|D_HIDDEN))) {
|
||||||
/* A type cast. This is of course not portable.
|
/* It was a type cast. This is of course not portable.
|
||||||
No runtime action. Remove it.
|
No runtime action. Remove it.
|
||||||
*/
|
*/
|
||||||
arg = expp->nd_right;
|
arg = expp->nd_right;
|
||||||
if ((! arg) || arg->nd_right) {
|
if ((! arg) || arg->nd_right) {
|
||||||
node_error(expp, "Only one parameter expected in type cast");
|
node_error(expp, "only one parameter expected in type cast");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arg = arg->nd_left;
|
arg = arg->nd_left;
|
||||||
if (! chk_expr(arg)) return 0;
|
if (! chk_expr(arg)) return 0;
|
||||||
if (arg->nd_type->tp_size != left->nd_type->tp_size) {
|
if (arg->nd_type->tp_size != left->nd_type->tp_size) {
|
||||||
node_error(expp, "Size of type in type cast does not match size of operand");
|
node_error(expp, "size of type in type cast does not match size of operand");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arg->nd_type = left->nd_type;
|
arg->nd_type = left->nd_type;
|
||||||
|
@ -285,7 +302,7 @@ node_error(expp, "Size of type in type cast does not match size of operand");
|
||||||
/* A standard procedure
|
/* A standard procedure
|
||||||
*/
|
*/
|
||||||
assert(left->nd_class == Def);
|
assert(left->nd_class == Def);
|
||||||
DO_DEBUG(3, debug("Standard name \"%s\", %d",
|
DO_DEBUG(3, debug("standard name \"%s\", %d",
|
||||||
left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
switch(left->nd_def->df_value.df_stdname) {
|
switch(left->nd_def->df_value.df_stdname) {
|
||||||
case S_ABS:
|
case S_ABS:
|
||||||
|
@ -297,6 +314,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
cstcall(expp, S_ABS);
|
cstcall(expp, S_ABS);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CAP:
|
case S_CAP:
|
||||||
arg = getarg(arg, T_CHAR);
|
arg = getarg(arg, T_CHAR);
|
||||||
expp->nd_type = char_type;
|
expp->nd_type = char_type;
|
||||||
|
@ -306,6 +324,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
cstcall(expp, S_CAP);
|
cstcall(expp, S_CAP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CHR:
|
case S_CHR:
|
||||||
arg = getarg(arg, T_INTORCARD);
|
arg = getarg(arg, T_INTORCARD);
|
||||||
expp->nd_type = char_type;
|
expp->nd_type = char_type;
|
||||||
|
@ -314,11 +333,13 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
cstcall(expp, S_CHR);
|
cstcall(expp, S_CHR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_FLOAT:
|
case S_FLOAT:
|
||||||
arg = getarg(arg, T_INTORCARD);
|
arg = getarg(arg, T_INTORCARD);
|
||||||
expp->nd_type = real_type;
|
expp->nd_type = real_type;
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_HIGH:
|
case S_HIGH:
|
||||||
arg = getarg(arg, T_ARRAY);
|
arg = getarg(arg, T_ARRAY);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
|
@ -331,6 +352,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
}
|
}
|
||||||
else cstcall(expp, S_MAX);
|
else cstcall(expp, S_MAX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_MAX:
|
case S_MAX:
|
||||||
case S_MIN:
|
case S_MIN:
|
||||||
arg = getarg(arg, T_DISCRETE);
|
arg = getarg(arg, T_DISCRETE);
|
||||||
|
@ -338,6 +360,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
expp->nd_type = arg->nd_left->nd_type;
|
expp->nd_type = arg->nd_left->nd_type;
|
||||||
cstcall(expp,left->nd_def->df_value.df_stdname);
|
cstcall(expp,left->nd_def->df_value.df_stdname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ODD:
|
case S_ODD:
|
||||||
arg = getarg(arg, T_INTORCARD);
|
arg = getarg(arg, T_INTORCARD);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
|
@ -346,6 +369,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
cstcall(expp, S_ODD);
|
cstcall(expp, S_ODD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ORD:
|
case S_ORD:
|
||||||
arg = getarg(arg, T_DISCRETE);
|
arg = getarg(arg, T_DISCRETE);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
|
@ -354,6 +378,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
cstcall(expp, S_ORD);
|
cstcall(expp, S_ORD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_TSIZE: /* ??? */
|
case S_TSIZE: /* ??? */
|
||||||
case S_SIZE:
|
case S_SIZE:
|
||||||
arg = getname(arg, D_FIELD|D_VARIABLE|D_TYPE|D_HIDDEN|D_HTYPE);
|
arg = getname(arg, D_FIELD|D_VARIABLE|D_TYPE|D_HIDDEN|D_HTYPE);
|
||||||
|
@ -361,11 +386,13 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
cstcall(expp, S_SIZE);
|
cstcall(expp, S_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_TRUNC:
|
case S_TRUNC:
|
||||||
arg = getarg(arg, T_REAL);
|
arg = getarg(arg, T_REAL);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
expp->nd_type = card_type;
|
expp->nd_type = card_type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_VAL: {
|
case S_VAL: {
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
|
||||||
|
@ -388,11 +415,13 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case S_ADR:
|
case S_ADR:
|
||||||
arg = getname(arg, D_VARIABLE|D_FIELD|D_PROCEDURE);
|
arg = getname(arg, D_VARIABLE|D_FIELD|D_PROCEDURE);
|
||||||
expp->nd_type = address_type;
|
expp->nd_type = address_type;
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_DEC:
|
case S_DEC:
|
||||||
case S_INC:
|
case S_INC:
|
||||||
expp->nd_type = 0;
|
expp->nd_type = 0;
|
||||||
|
@ -403,9 +432,11 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_HALT:
|
case S_HALT:
|
||||||
expp->nd_type = 0;
|
expp->nd_type = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_EXCL:
|
case S_EXCL:
|
||||||
case S_INCL: {
|
case S_INCL: {
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
@ -421,11 +452,12 @@ node_error(arg, "EXCL and INCL expect a SET parameter");
|
||||||
arg = getarg(arg, T_DISCRETE);
|
arg = getarg(arg, T_DISCRETE);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
if (!TstCompat(tp->next, arg->nd_left->nd_type)) {
|
if (!TstCompat(tp->next, arg->nd_left->nd_type)) {
|
||||||
node_error(arg, "Unexpected type");
|
node_error(arg, "unexpected type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -436,14 +468,51 @@ node_error(arg, "EXCL and INCL expect a SET parameter");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Here, we have found a real procedure call
|
/* Here, we have found a real procedure call. The left hand
|
||||||
|
side may also represent a procedure variable.
|
||||||
*/
|
*/
|
||||||
return 1;
|
return chk_proccall(expp);
|
||||||
}
|
}
|
||||||
node_error(expp->nd_left, "procedure, type, or function expected");
|
node_error(expp->nd_left, "procedure, type, or function expected");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chk_proccall(expp)
|
||||||
|
struct node *expp;
|
||||||
|
{
|
||||||
|
/* Check a procedure call
|
||||||
|
*/
|
||||||
|
register struct node *left = expp->nd_left;
|
||||||
|
register struct node *arg;
|
||||||
|
register struct paramlist *param;
|
||||||
|
|
||||||
|
expp->nd_type = left->nd_type->next;
|
||||||
|
param = left->nd_type->prc_params;
|
||||||
|
arg = expp;
|
||||||
|
|
||||||
|
while (param) {
|
||||||
|
arg = getarg(arg, 0);
|
||||||
|
if (!arg) return 0;
|
||||||
|
if (param->par_var &&
|
||||||
|
! TstCompat(param->par_type, arg->nd_left->nd_type)) {
|
||||||
|
node_error(arg->nd_left, "type incompatibility in var parameter");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!param->par_var &&
|
||||||
|
!TstAssCompat(param->par_type, arg->nd_left->nd_type)) {
|
||||||
|
node_error(arg->nd_left, "type incompatibility in value parameter");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
param = param->next;
|
||||||
|
}
|
||||||
|
if (arg->nd_right) {
|
||||||
|
node_error(arg->nd_right, "too many parameters supplied");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
findname(expp)
|
findname(expp)
|
||||||
register struct node *expp;
|
register struct node *expp;
|
||||||
{
|
{
|
||||||
|
@ -471,7 +540,7 @@ findname(expp)
|
||||||
}
|
}
|
||||||
else if (tp->tp_fund != T_RECORD) {
|
else if (tp->tp_fund != T_RECORD) {
|
||||||
/* This is also true for modules */
|
/* This is also true for modules */
|
||||||
node_error(expp,"Illegal selection");
|
node_error(expp,"illegal selection");
|
||||||
df = ill_df;
|
df = ill_df;
|
||||||
}
|
}
|
||||||
else df = lookup(expp->nd_right->nd_IDF, tp->rec_scope);
|
else df = lookup(expp->nd_right->nd_IDF, tp->rec_scope);
|
||||||
|
@ -614,16 +683,19 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
cstbin(expp);
|
cstbin(expp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case T_SET:
|
case T_SET:
|
||||||
if (expp->nd_left->nd_class == Set &&
|
if (expp->nd_left->nd_class == Set &&
|
||||||
expp->nd_right->nd_class == Set) {
|
expp->nd_right->nd_class == Set) {
|
||||||
cstset(expp);
|
cstset(expp);
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
switch(tpl->tp_fund) {
|
switch(tpl->tp_fund) {
|
||||||
case T_SET:
|
case T_SET:
|
||||||
|
@ -632,10 +704,12 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
cstset(expp);
|
cstset(expp);
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIV:
|
case DIV:
|
||||||
case MOD:
|
case MOD:
|
||||||
if (tpl->tp_fund & T_INTORCARD) {
|
if (tpl->tp_fund & T_INTORCARD) {
|
||||||
|
@ -646,6 +720,7 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OR:
|
case OR:
|
||||||
case AND:
|
case AND:
|
||||||
if (tpl == bool_type) {
|
if (tpl == bool_type) {
|
||||||
|
@ -657,6 +732,7 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
}
|
}
|
||||||
errval = 3;
|
errval = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
case '#':
|
case '#':
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
|
@ -673,6 +749,7 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
cstset(expp);
|
cstset(expp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_ENUMERATION: /* includes boolean */
|
case T_ENUMERATION: /* includes boolean */
|
||||||
|
@ -683,24 +760,29 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
cstbin(expp);
|
cstbin(expp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
if (!(expp->nd_symb == '=' || expp->nd_symb == '#')) {
|
if (!(expp->nd_symb == '=' || expp->nd_symb == '#')) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
switch(errval) {
|
switch(errval) {
|
||||||
case 1:
|
case 1:
|
||||||
node_error(expp,"Operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
|
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
node_error(expp, "BOOLEAN type(s) expected");
|
node_error(expp, "BOOLEAN type(s) expected");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -727,6 +809,7 @@ chk_uoper(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
if (tpr->tp_fund & T_INTORCARD) {
|
if (tpr->tp_fund & T_INTORCARD) {
|
||||||
if (expp->nd_right->nd_class == Value) {
|
if (expp->nd_right->nd_class == Value) {
|
||||||
|
@ -747,6 +830,7 @@ chk_uoper(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOT:
|
case NOT:
|
||||||
if (tpr == bool_type) {
|
if (tpr == bool_type) {
|
||||||
if (expp->nd_right->nd_class == Value) {
|
if (expp->nd_right->nd_class == Value) {
|
||||||
|
@ -755,10 +839,12 @@ chk_uoper(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '^':
|
case '^':
|
||||||
if (tpr->tp_fund != T_POINTER) break;
|
if (tpr->tp_fund != T_POINTER) break;
|
||||||
expp->nd_type = tpr->next;
|
expp->nd_type = tpr->next;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,24 @@ static char *RcsId = "$Header$";
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
static int proclevel = 0; /* nesting level of procedures */
|
static int proclevel = 0; /* nesting level of procedures */
|
||||||
|
char * sprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcedureDeclaration
|
ProcedureDeclaration
|
||||||
{
|
{
|
||||||
struct def *df;
|
struct def *df;
|
||||||
|
char buf[256];
|
||||||
} :
|
} :
|
||||||
ProcedureHeading(&df, D_PROCEDURE)
|
ProcedureHeading(&df, D_PROCEDURE)
|
||||||
{ df->prc_level = proclevel++;
|
{ df->prc_level = proclevel++;
|
||||||
|
if (DefinitionModule) {
|
||||||
|
C_exp(sprint(buf, "%s_%s",
|
||||||
|
df->df_scope->sc_name,
|
||||||
|
df->df_idf->id_text));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
';' 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);
|
||||||
|
|
|
@ -14,8 +14,13 @@ struct module {
|
||||||
struct variable {
|
struct variable {
|
||||||
arith va_off; /* address or offset of variable */
|
arith va_off; /* address or offset of variable */
|
||||||
char va_addrgiven; /* an address was given in the program */
|
char va_addrgiven; /* an address was given in the program */
|
||||||
|
char va_noreg; /* may not be in a register */
|
||||||
|
short va_number; /* number of this variable in definition module
|
||||||
|
*/
|
||||||
#define var_off df_value.df_variable.va_off
|
#define var_off df_value.df_variable.va_off
|
||||||
#define var_addrgiven df_value.df_variable.va_addrgiven
|
#define var_addrgiven df_value.df_variable.va_addrgiven
|
||||||
|
#define var_noreg df_value.df_variable.va_noreg
|
||||||
|
#define var_number df_value.df_variable.va_number
|
||||||
};
|
};
|
||||||
|
|
||||||
struct constant {
|
struct constant {
|
||||||
|
@ -43,13 +48,16 @@ struct field {
|
||||||
|
|
||||||
struct dfproc {
|
struct dfproc {
|
||||||
struct scope *pr_scope; /* scope of procedure */
|
struct scope *pr_scope; /* scope of procedure */
|
||||||
int pr_level; /* depth level of this procedure */
|
short pr_level; /* depth level of this procedure */
|
||||||
arith pr_nbpar; /* Number of bytes parameters */
|
short pr_number; /* number of this procedure in definition module
|
||||||
|
*/
|
||||||
|
arith pr_nbpar; /* number of bytes parameters */
|
||||||
struct node *pr_body; /* body of this procedure */
|
struct node *pr_body; /* body of this procedure */
|
||||||
#define prc_scope df_value.df_proc.pr_scope
|
#define prc_scope df_value.df_proc.pr_scope
|
||||||
#define prc_level df_value.df_proc.pr_level
|
#define prc_level df_value.df_proc.pr_level
|
||||||
#define prc_nbpar df_value.df_proc.pr_nbpar
|
#define prc_nbpar df_value.df_proc.pr_nbpar
|
||||||
#define prc_body df_value.df_proc.pr_body
|
#define prc_body df_value.df_proc.pr_body
|
||||||
|
#define prc_number df_value.df_proc.pr_number
|
||||||
};
|
};
|
||||||
|
|
||||||
struct import {
|
struct import {
|
||||||
|
|
|
@ -22,6 +22,32 @@ static struct def illegal_def =
|
||||||
|
|
||||||
struct def *ill_df = &illegal_def;
|
struct def *ill_df = &illegal_def;
|
||||||
|
|
||||||
|
struct def *
|
||||||
|
MkDef(id, scope, kind)
|
||||||
|
struct idf *id;
|
||||||
|
struct scope *scope;
|
||||||
|
{
|
||||||
|
/* Create a new definition structure in scope "scope", with
|
||||||
|
id "id" and kind "kind".
|
||||||
|
*/
|
||||||
|
register struct def *df;
|
||||||
|
|
||||||
|
df = new_def();
|
||||||
|
df->df_flags = 0;
|
||||||
|
df->df_idf = id;
|
||||||
|
df->df_scope = scope;
|
||||||
|
df->df_kind = kind;
|
||||||
|
df->df_type = 0;
|
||||||
|
df->next = id->id_def;
|
||||||
|
id->id_def = df;
|
||||||
|
|
||||||
|
/* enter the definition in the list of definitions in this scope
|
||||||
|
*/
|
||||||
|
df->df_nextinscope = scope->sc_def;
|
||||||
|
scope->sc_def = df;
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
define(id, scope, kind)
|
define(id, scope, kind)
|
||||||
register struct idf *id;
|
register struct idf *id;
|
||||||
|
@ -85,19 +111,7 @@ error("identifier \"%s\" already declared", id->id_text);
|
||||||
}
|
}
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
df = new_def();
|
return MkDef(id, scope, kind);
|
||||||
df->df_flags = 0;
|
|
||||||
df->df_idf = id;
|
|
||||||
df->df_scope = scope;
|
|
||||||
df->df_kind = kind;
|
|
||||||
df->df_type = 0;
|
|
||||||
df->next = id->id_def;
|
|
||||||
id->id_def = df;
|
|
||||||
|
|
||||||
/* enter the definition in the list of definitions in this scope */
|
|
||||||
df->df_nextinscope = scope->sc_def;
|
|
||||||
scope->sc_def = df;
|
|
||||||
return df;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
|
|
|
@ -12,6 +12,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
Enter(name, kind, type, pnam)
|
Enter(name, kind, type, pnam)
|
||||||
|
@ -126,6 +127,13 @@ node_error(IdList->nd_left,"Illegal type for address");
|
||||||
df->var_off = off;
|
df->var_off = off;
|
||||||
scope->sc_off = off;
|
scope->sc_off = off;
|
||||||
}
|
}
|
||||||
|
else if (DefinitionModule) {
|
||||||
|
char buf[256];
|
||||||
|
char *sprint();
|
||||||
|
|
||||||
|
C_exa_dnam(sprint(buf,"%s_%s",df->df_scope->sc_name,
|
||||||
|
df->df_idf->id_text));
|
||||||
|
}
|
||||||
IdList = IdList->nd_right;
|
IdList = IdList->nd_right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,17 +145,20 @@ lookfor(id, scope, give_error)
|
||||||
{
|
{
|
||||||
/* Look for an identifier in the visibility range started by
|
/* Look for an identifier in the visibility range started by
|
||||||
"scope".
|
"scope".
|
||||||
If it is not defined, give an error message, and
|
If it is not defined, maybe give an error message, and
|
||||||
create a dummy definition.
|
create a dummy definition.
|
||||||
*/
|
*/
|
||||||
struct def *df;
|
struct def *df;
|
||||||
register struct scope *sc = scope;
|
register struct scope *sc = scope;
|
||||||
|
struct def *MkDef();
|
||||||
|
|
||||||
while (sc) {
|
while (sc) {
|
||||||
df = lookup(id->nd_IDF, sc);
|
df = lookup(id->nd_IDF, sc);
|
||||||
if (df) return df;
|
if (df) return df;
|
||||||
sc = nextvisible(sc);
|
sc = nextvisible(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (give_error) id_not_declared(id);
|
if (give_error) id_not_declared(id);
|
||||||
return define(id->nd_IDF, scope, D_ERROR);
|
|
||||||
|
return MkDef(id->nd_IDF, scope, D_ERROR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ static char *RcsId = "$Header$";
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
|
||||||
#include "errout.h"
|
#include "errout.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
|
|
|
@ -183,10 +183,15 @@ factor(struct node **p;)
|
||||||
| %default
|
| %default
|
||||||
number(p)
|
number(p)
|
||||||
|
|
|
|
||||||
STRING { *p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
STRING {
|
||||||
|
*p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
||||||
if (dot.TOK_SLE == 1) {
|
if (dot.TOK_SLE == 1) {
|
||||||
dot.TOK_INT = *(dot.TOK_STR);
|
int i;
|
||||||
(*p)->nd_type = char_type;
|
|
||||||
|
i = *(dot.TOK_STR) & 0377;
|
||||||
|
(*p)->nd_type = charc_type;
|
||||||
|
free(dot.TOK_STR);
|
||||||
|
dot.TOK_INT = i;
|
||||||
}
|
}
|
||||||
else (*p)->nd_type = string_type;
|
else (*p)->nd_type = string_type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,23 +40,24 @@ main(argc, argv)
|
||||||
Nargv[Nargc++] = *argv++;
|
Nargv[Nargc++] = *argv++;
|
||||||
}
|
}
|
||||||
Nargv[Nargc] = 0; /* terminate the arg vector */
|
Nargv[Nargc] = 0; /* terminate the arg vector */
|
||||||
if (Nargc != 2) {
|
if (Nargc < 2) {
|
||||||
fprint(STDERR, "%s: Use one file argument\n", ProgName);
|
fprint(STDERR, "%s: Use a file argument\n", ProgName);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print("Mod2 compiler -- Debug version\n");
|
print("MODULA-2 compiler -- Debug version\n");
|
||||||
#endif DEBUG
|
|
||||||
DO_DEBUG(1, debug("Debugging level: %d", options['D']));
|
DO_DEBUG(1, debug("Debugging level: %d", options['D']));
|
||||||
return !Compile(Nargv[1]);
|
#endif DEBUG
|
||||||
|
return !Compile(Nargv[1], Nargv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Compile(src)
|
Compile(src, dst)
|
||||||
char *src;
|
char *src, *dst;
|
||||||
{
|
{
|
||||||
extern struct tokenname tkidf[];
|
extern struct tokenname tkidf[];
|
||||||
|
|
||||||
DO_DEBUG(1, debug("Filename : %s", src));
|
DO_DEBUG(1, debug("Filename : %s", src));
|
||||||
|
DO_DEBUG(1, (!dst || debug("Targetfile: %s", dst)));
|
||||||
if (! InsertFile(src, (char **) 0, &src)) {
|
if (! InsertFile(src, (char **) 0, &src)) {
|
||||||
fprint(STDERR,"%s: cannot open %s\n", ProgName, src);
|
fprint(STDERR,"%s: cannot open %s\n", ProgName, src);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -77,8 +78,15 @@ Compile(src)
|
||||||
{
|
{
|
||||||
(void) open_scope(CLOSEDSCOPE);
|
(void) open_scope(CLOSEDSCOPE);
|
||||||
GlobalScope = CurrentScope;
|
GlobalScope = CurrentScope;
|
||||||
|
C_init(word_size, pointer_size);
|
||||||
|
if (! C_open(dst)) {
|
||||||
|
fatal("Could not open output file");
|
||||||
|
}
|
||||||
|
C_magic();
|
||||||
|
C_ms_emx(word_size, pointer_size);
|
||||||
CompUnit();
|
CompUnit();
|
||||||
}
|
}
|
||||||
|
C_close();
|
||||||
if (err_occurred) return 0;
|
if (err_occurred) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +95,7 @@ Compile(src)
|
||||||
LexScan()
|
LexScan()
|
||||||
{
|
{
|
||||||
register int symb;
|
register int symb;
|
||||||
|
char *symbol2str();
|
||||||
|
|
||||||
while ((symb = LLlex()) > 0) {
|
while ((symb = LLlex()) > 0) {
|
||||||
print(">>> %s ", symbol2str(symb));
|
print(">>> %s ", symbol2str(symb));
|
||||||
|
@ -171,6 +180,8 @@ init_DEFPATH()
|
||||||
if (*p) *p++ = '\0';
|
if (*p) *p++ = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else DEFPATH[i++] = "";
|
||||||
|
|
||||||
DEFPATH[i] = 0;
|
DEFPATH[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@ static int DEFofIMPL = 0; /* Flag indicating that we are currently
|
||||||
implementation module currently being
|
implementation module currently being
|
||||||
compiled
|
compiled
|
||||||
*/
|
*/
|
||||||
|
short nmcount = 0; /* count names in definition modules in order
|
||||||
|
to create suitable names in the object code
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
The grammar as given by Wirth is already almost LL(1); the
|
The grammar as given by Wirth is already almost LL(1); the
|
||||||
|
@ -95,7 +98,7 @@ export(int def;)
|
||||||
Export(ExportList, QUALflag);
|
Export(ExportList, QUALflag);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warning("export list in definition module ignored");
|
node_warning(ExportList, "export list in definition module ignored");
|
||||||
FreeNode(ExportList);
|
FreeNode(ExportList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,16 +128,20 @@ DefinitionModule
|
||||||
{
|
{
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
int savnmcount = nmcount;
|
||||||
} :
|
} :
|
||||||
DEFINITION
|
DEFINITION
|
||||||
MODULE IDENT { id = dot.TOK_IDF;
|
MODULE IDENT { id = dot.TOK_IDF;
|
||||||
df = define(id, GlobalScope, D_MODULE);
|
df = define(id, GlobalScope, D_MODULE);
|
||||||
if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
|
if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
|
||||||
df->mod_scope = CurrentScope;
|
df->mod_scope = CurrentScope;
|
||||||
|
CurrentScope->sc_name = id->id_text;
|
||||||
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_scope;
|
df->df_type->rec_scope = df->mod_scope;
|
||||||
DefinitionModule = 1;
|
DefinitionModule++;
|
||||||
DO_DEBUG(1, debug("Definition module \"%s\"", id->id_text));
|
nmcount = 0;
|
||||||
|
DO_DEBUG(1, debug("Definition module \"%s\" %d",
|
||||||
|
id->id_text, DefinitionModule));
|
||||||
}
|
}
|
||||||
';'
|
';'
|
||||||
import(0)*
|
import(0)*
|
||||||
|
@ -158,8 +165,9 @@ DefinitionModule
|
||||||
df = df->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
}
|
}
|
||||||
if (!SYSTEMModule) close_scope(SC_CHKFORW);
|
if (!SYSTEMModule) close_scope(SC_CHKFORW);
|
||||||
DefinitionModule = 0;
|
DefinitionModule--;
|
||||||
match_id(id, dot.TOK_IDF);
|
match_id(id, dot.TOK_IDF);
|
||||||
|
nmcount = savnmcount;
|
||||||
}
|
}
|
||||||
'.'
|
'.'
|
||||||
;
|
;
|
||||||
|
@ -210,7 +218,6 @@ ProgramModule(int state;)
|
||||||
df = GetDefinitionModule(id);
|
df = GetDefinitionModule(id);
|
||||||
CurrentScope = df->mod_scope;
|
CurrentScope = df->mod_scope;
|
||||||
DEFofIMPL = 0;
|
DEFofIMPL = 0;
|
||||||
DefinitionModule = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = define(id, CurrentScope, D_MODULE);
|
df = define(id, CurrentScope, D_MODULE);
|
||||||
|
|
|
@ -15,6 +15,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
struct scope *CurrentScope, *PervasiveScope, *GlobalScope;
|
struct scope *CurrentScope, *PervasiveScope, *GlobalScope;
|
||||||
|
static int scp_level;
|
||||||
|
|
||||||
/* STATICALLOCDEF "scope" */
|
/* STATICALLOCDEF "scope" */
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ open_scope(scopetype)
|
||||||
|
|
||||||
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
|
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
|
||||||
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
|
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
|
||||||
|
sc->sc_level = scp_level++;
|
||||||
sc->sc_forw = 0;
|
sc->sc_forw = 0;
|
||||||
sc->sc_def = 0;
|
sc->sc_def = 0;
|
||||||
sc->sc_off = 0;
|
sc->sc_off = 0;
|
||||||
|
@ -45,6 +47,7 @@ init_scope()
|
||||||
sc->sc_scopeclosed = 0;
|
sc->sc_scopeclosed = 0;
|
||||||
sc->sc_forw = 0;
|
sc->sc_forw = 0;
|
||||||
sc->sc_def = 0;
|
sc->sc_def = 0;
|
||||||
|
sc->sc_level = scp_level++;
|
||||||
sc->next = 0;
|
sc->next = 0;
|
||||||
PervasiveScope = sc;
|
PervasiveScope = sc;
|
||||||
CurrentScope = sc;
|
CurrentScope = sc;
|
||||||
|
@ -197,6 +200,7 @@ close_scope(flag)
|
||||||
Reverse(&(sc->sc_def));
|
Reverse(&(sc->sc_def));
|
||||||
}
|
}
|
||||||
CurrentScope = sc->next;
|
CurrentScope = sc->next;
|
||||||
|
scp_level = CurrentScope->sc_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
struct scope {
|
struct scope {
|
||||||
struct scope *next;
|
struct scope *next;
|
||||||
struct forwards *sc_forw;
|
struct forwards *sc_forw;
|
||||||
|
char *sc_name; /* name of this scope */
|
||||||
struct def *sc_def; /* list of definitions in this scope */
|
struct def *sc_def; /* list of definitions in this scope */
|
||||||
arith sc_off; /* offsets of variables in this scope */
|
arith sc_off; /* offsets of variables in this scope */
|
||||||
char sc_scopeclosed; /* flag indicating closed or open scope */
|
char sc_scopeclosed; /* flag indicating closed or open scope */
|
||||||
|
int sc_level; /* level of this scope */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct scope
|
extern struct scope
|
||||||
|
|
|
@ -88,6 +88,7 @@ struct type {
|
||||||
extern struct type
|
extern struct type
|
||||||
*bool_type,
|
*bool_type,
|
||||||
*char_type,
|
*char_type,
|
||||||
|
*charc_type,
|
||||||
*int_type,
|
*int_type,
|
||||||
*card_type,
|
*card_type,
|
||||||
*longint_type,
|
*longint_type,
|
||||||
|
|
|
@ -40,6 +40,7 @@ arith
|
||||||
struct type
|
struct type
|
||||||
*bool_type,
|
*bool_type,
|
||||||
*char_type,
|
*char_type,
|
||||||
|
*charc_type,
|
||||||
*int_type,
|
*int_type,
|
||||||
*card_type,
|
*card_type,
|
||||||
*longint_type,
|
*longint_type,
|
||||||
|
@ -134,6 +135,8 @@ init_types()
|
||||||
|
|
||||||
char_type = standard_type(T_CHAR, 1, (arith) 1);
|
char_type = standard_type(T_CHAR, 1, (arith) 1);
|
||||||
char_type->enm_ncst = 256;
|
char_type->enm_ncst = 256;
|
||||||
|
charc_type = standard_type(T_CHAR, 1, (arith) 1);
|
||||||
|
charc_type->enm_ncst = 256;
|
||||||
bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
|
bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
|
||||||
bool_type->enm_ncst = 2;
|
bool_type->enm_ncst = 2;
|
||||||
int_type = standard_type(T_INTEGER, int_align, int_size);
|
int_type = standard_type(T_INTEGER, int_align, int_size);
|
||||||
|
|
|
@ -111,3 +111,27 @@ TstCompat(tp1, tp2)
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TstAssCompat(tp1, tp2)
|
||||||
|
struct type *tp1, *tp2;
|
||||||
|
{
|
||||||
|
/* Test if two types are assignment compatible.
|
||||||
|
*/
|
||||||
|
if (TstCompat(tp1, tp2)) return 1;
|
||||||
|
|
||||||
|
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
||||||
|
if (tp2->tp_fund == T_SUBRANGE) tp2 = tp2->next;
|
||||||
|
if ((tp1->tp_fund & (T_INTEGER|T_CARDINAL)) &&
|
||||||
|
(tp2->tp_fund & (T_INTEGER|T_CARDINAL))) return 1;
|
||||||
|
if (tp1 == char_type && tp2 == charc_type) return 1;
|
||||||
|
if (tp1->tp_fund == T_ARRAY &&
|
||||||
|
(tp2 == charc_type || tp2 == string_type)) {
|
||||||
|
/* Unfortunately the length of the string is not
|
||||||
|
available here, so this must be tested somewhere else (???)
|
||||||
|
*/
|
||||||
|
tp1 = tp1->arr_elem;
|
||||||
|
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
||||||
|
return tp1 == char_type;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue