first, almost complete, version
This commit is contained in:
parent
db795bc07a
commit
9e0ab0029b
19 changed files with 458 additions and 309 deletions
|
@ -26,9 +26,10 @@ static char *RcsId = "$Header$";
|
||||||
long str2long();
|
long str2long();
|
||||||
|
|
||||||
struct token dot, aside;
|
struct token dot, aside;
|
||||||
struct type *numtype;
|
struct type *toktype;
|
||||||
struct string string;
|
struct string string;
|
||||||
int idfsize = IDFSIZE;
|
int idfsize = IDFSIZE;
|
||||||
|
extern label data_label();
|
||||||
|
|
||||||
static
|
static
|
||||||
SkipComment()
|
SkipComment()
|
||||||
|
@ -111,10 +112,10 @@ LLlex()
|
||||||
The putting aside of tokens is taken into account.
|
The putting aside of tokens is taken into account.
|
||||||
*/
|
*/
|
||||||
register struct token *tk = ˙
|
register struct token *tk = ˙
|
||||||
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
|
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 2];
|
||||||
register int ch, nch;
|
register int ch, nch;
|
||||||
|
|
||||||
numtype = error_type;
|
toktype = error_type;
|
||||||
if (ASIDE) { /* a token is put aside */
|
if (ASIDE) { /* a token is put aside */
|
||||||
*tk = aside;
|
*tk = aside;
|
||||||
ASIDE = 0;
|
ASIDE = 0;
|
||||||
|
@ -221,9 +222,16 @@ again:
|
||||||
|
|
||||||
case STSTR:
|
case STSTR:
|
||||||
GetString(ch);
|
GetString(ch);
|
||||||
tk->tk_data.tk_str = (struct string *)
|
if (string.s_length == 1) {
|
||||||
|
tk->TOK_INT = *(string.s_str) & 0377;
|
||||||
|
toktype = char_type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tk->tk_data.tk_str = (struct string *)
|
||||||
Malloc(sizeof (struct string));
|
Malloc(sizeof (struct string));
|
||||||
*(tk->tk_data.tk_str) = string;
|
*(tk->tk_data.tk_str) = string;
|
||||||
|
toktype = standard_type(T_STRING, 1, string.s_length);
|
||||||
|
}
|
||||||
return tk->tk_symb = STRING;
|
return tk->tk_symb = STRING;
|
||||||
|
|
||||||
case STNUM:
|
case STNUM:
|
||||||
|
@ -252,9 +260,9 @@ again:
|
||||||
Shex: *np++ = '\0';
|
Shex: *np++ = '\0';
|
||||||
tk->TOK_INT = str2long(&buf[1], 16);
|
tk->TOK_INT = str2long(&buf[1], 16);
|
||||||
if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
||||||
numtype = intorcard_type;
|
toktype = intorcard_type;
|
||||||
}
|
}
|
||||||
else numtype = card_type;
|
else toktype = card_type;
|
||||||
return tk->tk_symb = INTEGER;
|
return tk->tk_symb = INTEGER;
|
||||||
|
|
||||||
case '8':
|
case '8':
|
||||||
|
@ -290,15 +298,15 @@ Shex: *np++ = '\0';
|
||||||
*np++ = '\0';
|
*np++ = '\0';
|
||||||
tk->TOK_INT = str2long(&buf[1], 8);
|
tk->TOK_INT = str2long(&buf[1], 8);
|
||||||
if (ch == 'C') {
|
if (ch == 'C') {
|
||||||
numtype = char_type;
|
toktype = char_type;
|
||||||
if (tk->TOK_INT < 0 || tk->TOK_INT > 255) {
|
if (tk->TOK_INT < 0 || tk->TOK_INT > 255) {
|
||||||
lexwarning("Character constant out of range");
|
lexwarning("Character constant out of range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
else if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
||||||
numtype = intorcard_type;
|
toktype = intorcard_type;
|
||||||
}
|
}
|
||||||
else numtype = card_type;
|
else toktype = card_type;
|
||||||
return tk->tk_symb = INTEGER;
|
return tk->tk_symb = INTEGER;
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
|
@ -380,12 +388,10 @@ Sreal:
|
||||||
PushBack(ch);
|
PushBack(ch);
|
||||||
|
|
||||||
if (np == &buf[NUMSIZE + 1]) {
|
if (np == &buf[NUMSIZE + 1]) {
|
||||||
lexerror("floating constant too long");
|
|
||||||
tk->TOK_REL = Salloc("0.0", 5);
|
tk->TOK_REL = Salloc("0.0", 5);
|
||||||
|
lexerror("floating constant too long");
|
||||||
}
|
}
|
||||||
else {
|
else tk->TOK_REL = Salloc(buf, np - buf) + 1;
|
||||||
tk->TOK_REL = Salloc(buf, np - buf) + 1;
|
|
||||||
}
|
|
||||||
return tk->tk_symb = REAL;
|
return tk->tk_symb = REAL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -394,9 +400,9 @@ Sdec:
|
||||||
*np++ = '\0';
|
*np++ = '\0';
|
||||||
tk->TOK_INT = str2long(&buf[1], 10);
|
tk->TOK_INT = str2long(&buf[1], 10);
|
||||||
if (tk->TOK_INT < 0 || tk->TOK_INT > max_int) {
|
if (tk->TOK_INT < 0 || tk->TOK_INT > max_int) {
|
||||||
numtype = card_type;
|
toktype = card_type;
|
||||||
}
|
}
|
||||||
else numtype = intorcard_type;
|
else toktype = intorcard_type;
|
||||||
return tk->tk_symb = INTEGER;
|
return tk->tk_symb = INTEGER;
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
|
|
@ -25,10 +25,10 @@ struct token {
|
||||||
#define TOK_STR tk_data.tk_str->s_str
|
#define TOK_STR tk_data.tk_str->s_str
|
||||||
#define TOK_SLE tk_data.tk_str->s_length
|
#define TOK_SLE tk_data.tk_str->s_length
|
||||||
#define TOK_INT tk_data.tk_int
|
#define TOK_INT tk_data.tk_int
|
||||||
#define TOK_REL tk_data.tk_real
|
#define TOK_REL tk_data.tk_real
|
||||||
|
|
||||||
extern struct token dot, aside;
|
extern struct token dot, aside;
|
||||||
extern struct type *numtype;
|
extern struct type *toktype;
|
||||||
|
|
||||||
#define DOT dot.tk_symb
|
#define DOT dot.tk_symb
|
||||||
#define ASIDE aside.tk_symb
|
#define ASIDE aside.tk_symb
|
||||||
|
|
|
@ -61,7 +61,7 @@ chk_expr(expp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(chk_expr(Value))");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ chk_expr(expp)
|
||||||
return chk_designator(expp, DESIGNATOR|VALUE, D_USED|D_NOREG);
|
return chk_designator(expp, DESIGNATOR|VALUE, D_USED|D_NOREG);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(chk_expr)");
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
@ -90,9 +90,9 @@ chk_set(expp)
|
||||||
/* Check the legality of a SET aggregate, and try to evaluate it
|
/* Check the legality of a SET aggregate, and try to evaluate it
|
||||||
compile time. Unfortunately this is all rather complicated.
|
compile time. Unfortunately this is all rather complicated.
|
||||||
*/
|
*/
|
||||||
struct type *tp;
|
register struct type *tp;
|
||||||
struct def *df;
|
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
|
register struct def *df;
|
||||||
arith *set;
|
arith *set;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ chk_set(expp)
|
||||||
|
|
||||||
if (!(df->df_kind & (D_TYPE|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, "specifier does not represent a set type");
|
node_error(expp, "specifier does not represent a set type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tp = df->df_type;
|
tp = df->df_type;
|
||||||
|
@ -163,16 +163,16 @@ chk_set(expp)
|
||||||
int
|
int
|
||||||
chk_el(expp, tp, set)
|
chk_el(expp, tp, set)
|
||||||
register struct node *expp;
|
register struct node *expp;
|
||||||
struct type *tp;
|
register struct type *tp;
|
||||||
arith **set;
|
arith **set;
|
||||||
{
|
{
|
||||||
/* Check elements of a set. This routine may call itself
|
/* Check elements of a set. This routine may call itself
|
||||||
recursively.
|
recursively.
|
||||||
Also try to compute the set!
|
Also try to compute the set!
|
||||||
*/
|
*/
|
||||||
register int i;
|
|
||||||
register struct node *left = expp->nd_left;
|
register struct node *left = expp->nd_left;
|
||||||
register struct node *right = expp->nd_right;
|
register struct node *right = expp->nd_right;
|
||||||
|
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, ... }
|
||||||
|
@ -370,7 +370,9 @@ chk_proccall(expp)
|
||||||
|
|
||||||
while (param) {
|
while (param) {
|
||||||
if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
|
if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
|
||||||
|
if (left->nd_symb == STRING) {
|
||||||
|
TryToString(left, TypeOfParam(param));
|
||||||
|
}
|
||||||
if (! TstParCompat(TypeOfParam(param),
|
if (! TstParCompat(TypeOfParam(param),
|
||||||
left->nd_type,
|
left->nd_type,
|
||||||
IsVarParam(param),
|
IsVarParam(param),
|
||||||
|
@ -734,6 +736,7 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case T_HIDDEN:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
if (chk_address(tpl, tpr) ||
|
if (chk_address(tpl, tpr) ||
|
||||||
expp->nd_symb == '=' ||
|
expp->nd_symb == '=' ||
|
||||||
|
@ -812,16 +815,13 @@ chk_uoper(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (tpr->tp_fund == T_REAL) {
|
else if (tpr->tp_fund == T_REAL) {
|
||||||
|
expp->nd_type = tpr;
|
||||||
if (right->nd_class == Value) {
|
if (right->nd_class == Value) {
|
||||||
expp->nd_token = right->nd_token;
|
if (*(right->nd_REL) == '-') (right->nd_REL)++;
|
||||||
|
else (right->nd_REL)--;
|
||||||
expp->nd_class = Value;
|
expp->nd_class = Value;
|
||||||
if (*(expp->nd_REL) == '-') {
|
expp->nd_symb = REAL;
|
||||||
expp->nd_REL++;
|
expp->nd_REL = right->nd_REL;
|
||||||
}
|
|
||||||
else {
|
|
||||||
expp->nd_REL--;
|
|
||||||
*(expp->nd_REL) = '-';
|
|
||||||
}
|
|
||||||
FreeNode(right);
|
FreeNode(right);
|
||||||
expp->nd_right = 0;
|
expp->nd_right = 0;
|
||||||
}
|
}
|
||||||
|
@ -901,7 +901,10 @@ DO_DEBUG(3,debug("standard name \"%s\", %d",left->nd_def->df_idf->id_text,std));
|
||||||
case S_ABS:
|
case S_ABS:
|
||||||
if (!(left = getarg(&arg, T_NUMERIC, 0))) return 0;
|
if (!(left = getarg(&arg, T_NUMERIC, 0))) return 0;
|
||||||
expp->nd_type = left->nd_type;
|
expp->nd_type = left->nd_type;
|
||||||
if (left->nd_class == Value) cstcall(expp, S_ABS);
|
if (left->nd_class == Value &&
|
||||||
|
expp->nd_type->tp_fund != T_REAL) {
|
||||||
|
cstcall(expp, S_ABS);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CAP:
|
case S_CAP:
|
||||||
|
@ -1085,3 +1088,20 @@ node_error(expp, "only one parameter expected in type cast");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TryToString(nd, tp)
|
||||||
|
struct node *nd;
|
||||||
|
struct type *tp;
|
||||||
|
{
|
||||||
|
/* Try a coercion from character constant to string */
|
||||||
|
if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) {
|
||||||
|
int ch = nd->nd_INT;
|
||||||
|
|
||||||
|
nd->nd_type = standard_type(T_STRING, 1, (arith) 2);
|
||||||
|
nd->nd_token.tk_data.tk_str =
|
||||||
|
(struct string *) Malloc(sizeof(struct string));
|
||||||
|
nd->nd_STR = Salloc("X", 2);
|
||||||
|
*(nd->nd_STR) = ch;
|
||||||
|
nd->nd_SLE = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -50,25 +50,49 @@ CodeConst(cst, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeString(nd)
|
CodeString(nd)
|
||||||
struct node *nd;
|
register struct node *nd;
|
||||||
{
|
{
|
||||||
label lab;
|
label lab;
|
||||||
|
|
||||||
if (nd->nd_type == charc_type) {
|
if (nd->nd_type == char_type) {
|
||||||
C_loc(nd->nd_INT);
|
C_loc(nd->nd_INT);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
C_df_dlb(lab = data_label());
|
else {
|
||||||
C_rom_scon(nd->nd_STR, nd->nd_SLE);
|
C_df_dlb(lab = data_label());
|
||||||
C_lae_dlb(lab, (arith) 0);
|
C_rom_scon(nd->nd_STR, align(nd->nd_SLE + 1, word_size));
|
||||||
|
C_lae_dlb(lab, (arith) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CodePadString(nd, sz)
|
||||||
|
register struct node *nd;
|
||||||
|
arith sz;
|
||||||
|
{
|
||||||
|
/* Generate code to push the string indicated by "nd".
|
||||||
|
Make it null-padded to "sz" bytes
|
||||||
|
*/
|
||||||
|
register arith sizearg = align(nd->nd_type->tp_size, word_align);
|
||||||
|
|
||||||
|
assert(nd->nd_type->tp_fund == T_STRING);
|
||||||
|
|
||||||
|
if (sizearg != sz) {
|
||||||
|
/* null padding required */
|
||||||
|
assert(sizearg < sz);
|
||||||
|
C_zer(sz - sizearg);
|
||||||
|
}
|
||||||
|
C_asp(-sizearg); /* room for string */
|
||||||
|
CodeString(nd); /* push address of string */
|
||||||
|
C_lor((arith) 1); /* load stack pointer */
|
||||||
|
C_adp(pointer_size); /* and compute target address from it */
|
||||||
|
C_blm(sizearg); /* and copy */
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeReal(nd)
|
CodeReal(nd)
|
||||||
struct node *nd;
|
register struct node *nd;
|
||||||
{
|
{
|
||||||
label lab;
|
label lab = data_label();
|
||||||
|
|
||||||
C_df_dlb(lab = data_label());
|
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);
|
||||||
C_lae_dlb(lab, (arith) 0);
|
C_lae_dlb(lab, (arith) 0);
|
||||||
C_loi(nd->nd_type->tp_size);
|
C_loi(nd->nd_type->tp_size);
|
||||||
|
@ -83,10 +107,13 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
switch(nd->nd_class) {
|
switch(nd->nd_class) {
|
||||||
case Def:
|
case Def:
|
||||||
if (nd->nd_def->df_kind == D_PROCEDURE) {
|
if (nd->nd_def->df_kind == D_PROCEDURE) {
|
||||||
C_lpi(nd->nd_def->prc_vis->sc_scope->sc_name);
|
C_lpi(NameOfProc(nd->nd_def));
|
||||||
ds->dsg_kind = DSG_LOADED;
|
ds->dsg_kind = DSG_LOADED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case Link:
|
||||||
CodeDesig(nd, ds);
|
CodeDesig(nd, ds);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -97,10 +124,8 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
}
|
}
|
||||||
CodeOper(nd, true_label, false_label);
|
CodeOper(nd, true_label, false_label);
|
||||||
if (true_label == 0) ds->dsg_kind = DSG_LOADED;
|
if (true_label == 0) ds->dsg_kind = DSG_LOADED;
|
||||||
else {
|
else ds->dsg_kind = DSG_INIT;
|
||||||
*ds = InitDesig;
|
true_label = 0;
|
||||||
true_label = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Uoper:
|
case Uoper:
|
||||||
|
@ -130,10 +155,6 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
ds->dsg_kind = DSG_LOADED;
|
ds->dsg_kind = DSG_LOADED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Link:
|
|
||||||
CodeDesig(nd, ds);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Call:
|
case Call:
|
||||||
CodeCall(nd);
|
CodeCall(nd);
|
||||||
ds->dsg_kind = DSG_LOADED;
|
ds->dsg_kind = DSG_LOADED;
|
||||||
|
@ -177,7 +198,7 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
CodeCoercion(t1, t2)
|
CodeCoercion(t1, t2)
|
||||||
register struct type *t1, *t2;
|
register struct type *t1, *t2;
|
||||||
{
|
{
|
||||||
int fund1, fund2;
|
register int fund1, fund2;
|
||||||
|
|
||||||
if (t1 == t2) return;
|
if (t1 == t2) return;
|
||||||
if (t1->tp_fund == T_SUBRANGE) t1 = t1->next;
|
if (t1->tp_fund == T_SUBRANGE) t1 = t1->next;
|
||||||
|
@ -285,7 +306,6 @@ CodeCall(nd)
|
||||||
CodeStd(nd);
|
CodeStd(nd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tp = left->nd_type;
|
|
||||||
|
|
||||||
if (IsCast(left)) {
|
if (IsCast(left)) {
|
||||||
/* it was just a cast. Simply ignore it
|
/* it was just a cast. Simply ignore it
|
||||||
|
@ -299,18 +319,42 @@ CodeCall(nd)
|
||||||
assert(IsProcCall(left));
|
assert(IsProcCall(left));
|
||||||
|
|
||||||
for (param = left->nd_type->prc_params; param; param = param->next) {
|
for (param = left->nd_type->prc_params; param; param = param->next) {
|
||||||
|
tp = TypeOfParam(param);
|
||||||
arg = arg->nd_right;
|
arg = arg->nd_right;
|
||||||
assert(arg != 0);
|
assert(arg != 0);
|
||||||
if (IsVarParam(param)) {
|
if (IsConformantArray(tp)) {
|
||||||
|
C_loc(tp->arr_elsize);
|
||||||
|
if (IsConformantArray(arg->nd_left->nd_type)) {
|
||||||
|
DoHIGH(arg->nd_left);
|
||||||
|
}
|
||||||
|
else if (arg->nd_left->nd_symb == STRING) {
|
||||||
|
C_loc(arg->nd_left->nd_SLE);
|
||||||
|
}
|
||||||
|
else if (tp->arr_elem == word_type) {
|
||||||
|
C_loc(arg->nd_left->nd_type->tp_size / word_size - 1);
|
||||||
|
}
|
||||||
|
else C_loc(arg->nd_left->nd_type->tp_size /
|
||||||
|
tp->arr_elsize - 1);
|
||||||
|
C_loc(0);
|
||||||
|
if (arg->nd_left->nd_symb == STRING) {
|
||||||
|
CodeString(arg->nd_left);
|
||||||
|
}
|
||||||
|
else CodeDAddress(arg->nd_left);
|
||||||
|
pushed += pointer_size + 3 * word_size;
|
||||||
|
}
|
||||||
|
else if (IsVarParam(param)) {
|
||||||
CodeDAddress(arg->nd_left);
|
CodeDAddress(arg->nd_left);
|
||||||
pushed += pointer_size;
|
pushed += pointer_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CodePExpr(arg->nd_left);
|
if (arg->nd_left->nd_type->tp_fund == T_STRING) {
|
||||||
CheckAssign(arg->nd_left->nd_type, TypeOfParam(param));
|
CodePadString(arg->nd_left,
|
||||||
pushed += align(arg->nd_left->nd_type->tp_size, word_align);
|
align(tp->tp_size, word_align));
|
||||||
|
}
|
||||||
|
else CodePExpr(arg->nd_left);
|
||||||
|
CheckAssign(arg->nd_left->nd_type, tp);
|
||||||
|
pushed += align(tp->tp_size, word_align);
|
||||||
}
|
}
|
||||||
/* ??? Conformant arrays */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) {
|
if (left->nd_class == Def && left->nd_def->df_kind == D_PROCEDURE) {
|
||||||
|
@ -318,7 +362,7 @@ CodeCall(nd)
|
||||||
C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level);
|
C_lxl((arith) proclevel - left->nd_def->df_scope->sc_level);
|
||||||
pushed += pointer_size;
|
pushed += pointer_size;
|
||||||
}
|
}
|
||||||
C_cal(left->nd_def->prc_vis->sc_scope->sc_name);
|
C_cal(NameOfProc(left->nd_def));
|
||||||
}
|
}
|
||||||
else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) {
|
else if (left->nd_class == Def && left->nd_def->df_kind == D_PROCHEAD) {
|
||||||
C_cal(left->nd_def->for_name);
|
C_cal(left->nd_def->for_name);
|
||||||
|
@ -327,9 +371,9 @@ CodeCall(nd)
|
||||||
CodePExpr(left);
|
CodePExpr(left);
|
||||||
C_cai();
|
C_cai();
|
||||||
}
|
}
|
||||||
C_asp(pushed);
|
if (pushed) C_asp(pushed);
|
||||||
if (tp->next) {
|
if (left->nd_type->next) {
|
||||||
C_lfr(align(tp->next->tp_size, word_align));
|
C_lfr(align(left->nd_type->next->tp_size, word_align));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +429,7 @@ CodeStd(nd)
|
||||||
|
|
||||||
case S_HIGH:
|
case S_HIGH:
|
||||||
assert(IsConformantArray(tp));
|
assert(IsConformantArray(tp));
|
||||||
/* ??? */
|
DoHIGH(left);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ODD:
|
case S_ODD:
|
||||||
|
@ -480,15 +524,24 @@ CodeAssign(nd, dss, dst)
|
||||||
/* 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;
|
||||||
|
extern arith align();
|
||||||
|
|
||||||
if (dss->dsg_kind == DSG_LOADED) {
|
if (dss->dsg_kind == DSG_LOADED) {
|
||||||
|
if (tp->tp_fund == T_STRING) {
|
||||||
|
CodeAddress(dst);
|
||||||
|
C_loc(tp->tp_size);
|
||||||
|
C_loc(nd->nd_left->nd_type->tp_size);
|
||||||
|
C_cal("_StringAssign");
|
||||||
|
C_asp((int_size << 1) + (pointer_size << 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
CodeStore(dst, nd->nd_left->nd_type->tp_size);
|
CodeStore(dst, nd->nd_left->nd_type->tp_size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
CodeAddress(dss);
|
||||||
CodeAddress(dss);
|
CodeAddress(dst);
|
||||||
CodeAddress(dst);
|
C_blm(nd->nd_left->nd_type->tp_size);
|
||||||
C_blm(nd->nd_left->nd_type->tp_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckAssign(tpl, tpr)
|
CheckAssign(tpl, tpr)
|
||||||
|
@ -683,6 +736,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_cmi(tp->tp_size);
|
C_cmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
|
case T_HIDDEN:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
C_cmp();
|
C_cmp();
|
||||||
break;
|
break;
|
||||||
|
@ -904,12 +958,16 @@ CodeSet(nd)
|
||||||
|
|
||||||
CodeEl(nd, tp)
|
CodeEl(nd, tp)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
struct type *tp;
|
register struct type *tp;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (nd->nd_class == Link && nd->nd_symb == UPTO) {
|
if (nd->nd_class == Link && nd->nd_symb == UPTO) {
|
||||||
C_zer(tp->tp_size); /* empty set */
|
C_zer(tp->tp_size); /* empty set */
|
||||||
C_lor((arith) 1); /* SP: address of set */
|
C_lor((arith) 1); /* SP: address of set */
|
||||||
|
if (tp->next->tp_fund == T_SUBRANGE) {
|
||||||
|
C_loc(tp->next->sub_ub);
|
||||||
|
}
|
||||||
|
else C_loc(tp->next->enm_ncst - 1);
|
||||||
Operands(nd->nd_left, nd->nd_right);
|
Operands(nd->nd_left, nd->nd_right);
|
||||||
C_cal("_LtoUset"); /* library routine to fill set */
|
C_cal("_LtoUset"); /* library routine to fill set */
|
||||||
C_asp(2 * word_size + pointer_size);
|
C_asp(2 * word_size + pointer_size);
|
||||||
|
@ -960,3 +1018,23 @@ CodeDStore(nd)
|
||||||
CodeDesig(nd, &designator);
|
CodeDesig(nd, &designator);
|
||||||
CodeStore(&designator, nd->nd_type->tp_size);
|
CodeStore(&designator, nd->nd_type->tp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoHIGH(nd)
|
||||||
|
struct node *nd;
|
||||||
|
{
|
||||||
|
register struct def *df;
|
||||||
|
arith highoff;
|
||||||
|
|
||||||
|
assert(nd->nd_class == Def);
|
||||||
|
|
||||||
|
df = nd->nd_def;
|
||||||
|
|
||||||
|
assert(df->df_kind == D_VARIABLE);
|
||||||
|
|
||||||
|
highoff = df->var_off + pointer_size + word_size;
|
||||||
|
if (df->df_scope->sc_level < proclevel) {
|
||||||
|
C_lxa(proclevel - df->df_scope->sc_level);
|
||||||
|
C_lof(highoff);
|
||||||
|
}
|
||||||
|
else C_lol(highoff);
|
||||||
|
}
|
||||||
|
|
|
@ -374,12 +374,6 @@ cstcall(expp, call)
|
||||||
expp->nd_symb = INTEGER;
|
expp->nd_symb = INTEGER;
|
||||||
switch(call) {
|
switch(call) {
|
||||||
case S_ABS:
|
case S_ABS:
|
||||||
if (expr->nd_type->tp_fund == T_REAL) {
|
|
||||||
expp->nd_symb = REAL;
|
|
||||||
expp->nd_REL = expr->nd_REL;
|
|
||||||
if (*(expr->nd_REL) == '-') (expp->nd_REL)++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (expr->nd_INT < 0) expp->nd_INT = - expr->nd_INT;
|
if (expr->nd_INT < 0) expp->nd_INT = - expr->nd_INT;
|
||||||
else expp->nd_INT = expr->nd_INT;
|
else expp->nd_INT = expr->nd_INT;
|
||||||
CutSize(expp);
|
CutSize(expp);
|
||||||
|
|
|
@ -54,7 +54,7 @@ ProcedureHeading(struct def **pdf; int type;)
|
||||||
{
|
{
|
||||||
df = DeclProc(type);
|
df = DeclProc(type);
|
||||||
tp = construct_type(T_PROCEDURE, tp);
|
tp = construct_type(T_PROCEDURE, tp);
|
||||||
if (proclevel) {
|
if (proclevel > 1) {
|
||||||
/* Room for static link
|
/* Room for static link
|
||||||
*/
|
*/
|
||||||
tp->prc_nbpar = pointer_size;
|
tp->prc_nbpar = pointer_size;
|
||||||
|
@ -134,10 +134,10 @@ FPSection(struct paramlist **ppr; arith *parmaddr;)
|
||||||
{
|
{
|
||||||
struct node *FPList;
|
struct node *FPList;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
int VARp = 0;
|
int VARp = D_VALPAR;
|
||||||
} :
|
} :
|
||||||
[
|
[
|
||||||
VAR { VARp = 1; }
|
VAR { VARp = D_VARPAR; }
|
||||||
]?
|
]?
|
||||||
IdentList(&FPList) ':' FormalType(&tp)
|
IdentList(&FPList) ':' FormalType(&tp)
|
||||||
{
|
{
|
||||||
|
@ -146,43 +146,48 @@ FPSection(struct paramlist **ppr; arith *parmaddr;)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
FormalType(struct type **tp;)
|
FormalType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct def *df;
|
struct def *df;
|
||||||
int ARRAYflag = 0;
|
int ARRAYflag = 0;
|
||||||
|
register struct type *tp;
|
||||||
|
extern arith ArrayElSize();
|
||||||
} :
|
} :
|
||||||
[ ARRAY OF { ARRAYflag = 1; }
|
[ ARRAY OF { ARRAYflag = 1; }
|
||||||
]?
|
]?
|
||||||
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
{ if (ARRAYflag) {
|
{ if (ARRAYflag) {
|
||||||
*tp = construct_type(T_ARRAY, NULLTYPE);
|
*ptp = tp = construct_type(T_ARRAY, NULLTYPE);
|
||||||
(*tp)->arr_elem = df->df_type;
|
tp->arr_elem = df->df_type;
|
||||||
(*tp)->tp_align = lcm(word_align, pointer_align);
|
tp->arr_elsize = ArrayElSize(df->df_type);
|
||||||
(*tp)->tp_size = align(pointer_size + word_size,
|
tp->tp_align = lcm(word_align, pointer_align);
|
||||||
(*tp)->tp_align);
|
|
||||||
}
|
}
|
||||||
else *tp = df->df_type;
|
else *ptp = df->df_type;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
TypeDeclaration
|
TypeDeclaration
|
||||||
{
|
{
|
||||||
struct def *df;
|
register struct def *df;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
}:
|
}:
|
||||||
IDENT { df = lookup(dot.TOK_IDF, CurrentScope);
|
IDENT { df = lookup(dot.TOK_IDF, CurrentScope);
|
||||||
if (!df) df = define( dot.TOK_IDF,
|
if (!df) df = define(dot.TOK_IDF,CurrentScope,D_TYPE);
|
||||||
CurrentScope,
|
|
||||||
D_TYPE);
|
|
||||||
}
|
}
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ if (df->df_type) free_type(df->df_type); /* ??? */
|
{
|
||||||
df->df_type = tp;
|
if (df->df_kind == D_HIDDEN) {
|
||||||
if (df->df_kind == D_HIDDEN &&
|
if (tp->tp_fund != T_POINTER) {
|
||||||
tp->tp_fund != T_POINTER) {
|
|
||||||
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
|
}
|
||||||
|
df->df_kind = D_TYPE;
|
||||||
|
*(df->df_type) = *tp;
|
||||||
|
free_type(tp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
df->df_type = tp;
|
||||||
|
df->df_kind = D_TYPE;
|
||||||
}
|
}
|
||||||
df->df_kind = D_TYPE;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -235,6 +240,7 @@ enumeration(struct type **ptp;)
|
||||||
CurrentScope, (arith *) 0);
|
CurrentScope, (arith *) 0);
|
||||||
FreeNode(EnumList);
|
FreeNode(EnumList);
|
||||||
if (tp->enm_ncst > 256) {
|
if (tp->enm_ncst > 256) {
|
||||||
|
/* ??? is this reasonable ??? */
|
||||||
error("Too many enumeration literals");
|
error("Too many enumeration literals");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,12 +250,12 @@ IdentList(struct node **p;)
|
||||||
{
|
{
|
||||||
register struct node *q;
|
register struct node *q;
|
||||||
} :
|
} :
|
||||||
IDENT { q = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
IDENT { q = MkLeaf(Value, &dot);
|
||||||
*p = q;
|
*p = q;
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
',' IDENT
|
',' IDENT
|
||||||
{ q->next = MkNode(Value,NULLNODE,NULLNODE,&dot);
|
{ q->next = MkLeaf(Value, &dot);
|
||||||
q = q->next;
|
q = q->next;
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
|
@ -572,11 +578,11 @@ VariableDeclaration
|
||||||
IdentAddrList(struct node **pnd;)
|
IdentAddrList(struct node **pnd;)
|
||||||
{
|
{
|
||||||
} :
|
} :
|
||||||
IDENT { *pnd = MkNode(Name, NULLNODE, NULLNODE, &dot); }
|
IDENT { *pnd = MkLeaf(Name, &dot); }
|
||||||
ConstExpression(&(*pnd)->nd_left)?
|
ConstExpression(&(*pnd)->nd_left)?
|
||||||
[ { pnd = &((*pnd)->nd_right); }
|
[ { pnd = &((*pnd)->nd_right); }
|
||||||
',' IDENT
|
',' IDENT
|
||||||
{ *pnd = MkNode(Name, NULLNODE, NULLNODE, &dot); }
|
{ *pnd = MkLeaf(Name, &dot); }
|
||||||
ConstExpression(&(*pnd)->nd_left)?
|
ConstExpression(&(*pnd)->nd_left)?
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct dfproc {
|
||||||
struct node *pr_body; /* body of this procedure */
|
struct node *pr_body; /* body of this procedure */
|
||||||
#define prc_vis df_value.df_proc.pr_vis
|
#define prc_vis df_value.df_proc.pr_vis
|
||||||
#define prc_body df_value.df_proc.pr_body
|
#define prc_body df_value.df_proc.pr_body
|
||||||
|
#define NameOfProc(xdf) ((xdf)->prc_vis->sc_scope->sc_name)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct import {
|
struct import {
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct def *ill_df;
|
||||||
struct def *
|
struct def *
|
||||||
MkDef(id, scope, kind)
|
MkDef(id, scope, kind)
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
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
|
||||||
id "id" and kind "kind".
|
id "id" and kind "kind".
|
||||||
|
@ -55,7 +55,7 @@ MkDef(id, scope, kind)
|
||||||
InitDef()
|
InitDef()
|
||||||
{
|
{
|
||||||
/* Initialize this module. Easy, the only thing to be initialized
|
/* Initialize this module. Easy, the only thing to be initialized
|
||||||
is "illegal_def".
|
is "ill_df".
|
||||||
*/
|
*/
|
||||||
struct idf *gen_anon_idf();
|
struct idf *gen_anon_idf();
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ define(id, scope, kind)
|
||||||
) {
|
) {
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_HIDDEN:
|
case D_HIDDEN:
|
||||||
|
/* An opaque type. We may now have found the
|
||||||
|
definition of this type.
|
||||||
|
*/
|
||||||
if (kind == D_TYPE && !DefinitionModule) {
|
if (kind == D_TYPE && !DefinitionModule) {
|
||||||
df->df_kind = D_TYPE;
|
df->df_kind = D_TYPE;
|
||||||
return df;
|
return df;
|
||||||
|
@ -90,6 +93,10 @@ define(id, scope, kind)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_FORWMODULE:
|
case D_FORWMODULE:
|
||||||
|
/* A forward reference to a module. We may have found
|
||||||
|
another one, or we may have found the definition
|
||||||
|
for this module.
|
||||||
|
*/
|
||||||
if (kind == D_FORWMODULE) {
|
if (kind == D_FORWMODULE) {
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
@ -104,19 +111,27 @@ define(id, scope, kind)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_FORWARD:
|
case D_FORWARD:
|
||||||
|
/* A forward reference, for which we may now have
|
||||||
|
found a definition.
|
||||||
|
*/
|
||||||
if (kind != D_FORWARD) {
|
if (kind != D_FORWARD) {
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
df->df_kind = kind;
|
/* Fall through */
|
||||||
return df;
|
|
||||||
|
|
||||||
case D_ERROR:
|
case D_ERROR:
|
||||||
|
/* A definition generated by the compiler, because
|
||||||
|
it found an error. Maybe, the user gives a
|
||||||
|
definition after all.
|
||||||
|
*/
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind != D_ERROR) {
|
if (kind != D_ERROR) {
|
||||||
|
/* Avoid spurious error messages
|
||||||
|
*/
|
||||||
error("identifier \"%s\" already declared", id->id_text);
|
error("identifier \"%s\" already declared", id->id_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +164,8 @@ lookup(id, scope)
|
||||||
assert(retval != 0);
|
assert(retval != 0);
|
||||||
}
|
}
|
||||||
if (df1) {
|
if (df1) {
|
||||||
|
/* Put the definition now found in front
|
||||||
|
*/
|
||||||
df1->next = df->next;
|
df1->next = df->next;
|
||||||
df->next = id->id_def;
|
df->next = id->id_def;
|
||||||
id->id_def = df;
|
id->id_def = df;
|
||||||
|
@ -162,30 +179,34 @@ lookup(id, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
DoImport(df, scope)
|
DoImport(df, scope)
|
||||||
struct def *df;
|
register struct def *df;
|
||||||
struct scope *scope;
|
struct scope *scope;
|
||||||
{
|
{
|
||||||
register struct def *df1;
|
/* Definition "df" is imported to scope "scope".
|
||||||
|
Handle the case that it is an enumeration type or a module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(df->df_idf, scope, D_IMPORT)->imp_def = df;
|
||||||
|
|
||||||
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
||||||
/* Also import all enumeration literals
|
/* Also import all enumeration literals
|
||||||
*/
|
*/
|
||||||
df1 = df->df_type->enm_enums;
|
df = df->df_type->enm_enums;
|
||||||
while (df1) {
|
while (df) {
|
||||||
define(df1->df_idf, scope, D_IMPORT)->imp_def = df1;
|
define(df->df_idf, scope, D_IMPORT)->imp_def = df;
|
||||||
df1 = df1->enm_next;
|
df = df->enm_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (df->df_kind == D_MODULE) {
|
else if (df->df_kind == D_MODULE) {
|
||||||
/* Also import all definitions that are exported from this
|
/* Also import all definitions that are exported from this
|
||||||
module
|
module
|
||||||
*/
|
*/
|
||||||
df1 = df->mod_vis->sc_scope->sc_def;
|
df = df->mod_vis->sc_scope->sc_def;
|
||||||
while (df1) {
|
while (df) {
|
||||||
if (df1->df_flags & D_EXPORTED) {
|
if (df->df_flags & D_EXPORTED) {
|
||||||
define(df1->df_idf, scope, D_IMPORT)->imp_def = df1;
|
define(df->df_idf,scope,D_IMPORT)->imp_def = df;
|
||||||
}
|
}
|
||||||
df1 = df1->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +234,7 @@ node_error(ids, "identifier \"%s\" not defined", ids->nd_IDF->id_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) {
|
if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) {
|
||||||
node_error(ids, "Identifier \"%s\" occurs more than once in export list",
|
node_error(ids, "identifier \"%s\" occurs more than once in export list",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +246,8 @@ df->df_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
|
||||||
*/
|
*/
|
||||||
|
df->df_flags |= D_EXPORTED;
|
||||||
|
|
||||||
impmod = moddef->df_idf->id_def;
|
impmod = moddef->df_idf->id_def;
|
||||||
while (impmod) {
|
while (impmod) {
|
||||||
if (impmod->df_kind == D_IMPORT &&
|
if (impmod->df_kind == D_IMPORT &&
|
||||||
|
@ -234,7 +257,6 @@ df->df_idf->id_text);
|
||||||
impmod = impmod->next;
|
impmod = impmod->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
df->df_flags |= D_EXPORTED;
|
|
||||||
df1 = lookup(ids->nd_IDF, enclosing(CurrVis)->sc_scope);
|
df1 = lookup(ids->nd_IDF, enclosing(CurrVis)->sc_scope);
|
||||||
if (df1 && df1->df_kind == D_PROCHEAD) {
|
if (df1 && df1->df_kind == D_PROCHEAD) {
|
||||||
if (df->df_kind == D_PROCEDURE) {
|
if (df->df_kind == D_PROCEDURE) {
|
||||||
|
@ -255,10 +277,6 @@ error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
df1 = define(ids->nd_IDF,
|
|
||||||
enclosing(CurrVis)->sc_scope,
|
|
||||||
D_IMPORT);
|
|
||||||
df1->imp_def = df;
|
|
||||||
DoImport(df, enclosing(CurrVis)->sc_scope);
|
DoImport(df, enclosing(CurrVis)->sc_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +301,7 @@ ForwModule(df, idn)
|
||||||
closing this one
|
closing this one
|
||||||
*/
|
*/
|
||||||
df->for_vis = vis;
|
df->for_vis = vis;
|
||||||
df->for_node = MkNode(Name, NULLNODE, NULLNODE, &(idn->nd_token));
|
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 ! */
|
||||||
|
@ -302,7 +320,7 @@ ForwDef(ids, scope)
|
||||||
|
|
||||||
if (!(df = lookup(ids->nd_IDF, scope))) {
|
if (!(df = lookup(ids->nd_IDF, scope))) {
|
||||||
df = define(ids->nd_IDF, scope, D_FORWARD);
|
df = define(ids->nd_IDF, scope, D_FORWARD);
|
||||||
df->for_node = MkNode(Name,NULLNODE,NULLNODE,&(ids->nd_token));
|
df->for_node = MkLeaf(Name, &(ids->nd_token));
|
||||||
}
|
}
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +402,6 @@ ids->nd_IDF->id_text);
|
||||||
else df = GetDefinitionModule(ids->nd_IDF);
|
else df = GetDefinitionModule(ids->nd_IDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
define(ids->nd_IDF,CurrentScope,D_IMPORT)->imp_def = df;
|
|
||||||
DoImport(df, CurrentScope);
|
DoImport(df, CurrentScope);
|
||||||
|
|
||||||
ids = ids->next;
|
ids = ids->next;
|
||||||
|
@ -393,7 +410,7 @@ ids->nd_IDF->id_text);
|
||||||
FreeNode(idn);
|
FreeNode(idn);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemImports(pdf)
|
RemoveImports(pdf)
|
||||||
struct def **pdf;
|
struct def **pdf;
|
||||||
{
|
{
|
||||||
/* Remove all imports from a definition module. This is
|
/* Remove all imports from a definition module. This is
|
||||||
|
@ -404,7 +421,7 @@ RemImports(pdf)
|
||||||
|
|
||||||
while (df) {
|
while (df) {
|
||||||
if (df->df_kind == D_IMPORT) {
|
if (df->df_kind == D_IMPORT) {
|
||||||
RemFromId(df);
|
RemoveFromIdList(df);
|
||||||
*pdf = df->df_nextinscope;
|
*pdf = df->df_nextinscope;
|
||||||
free_def(df);
|
free_def(df);
|
||||||
}
|
}
|
||||||
|
@ -415,7 +432,7 @@ RemImports(pdf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RemFromId(df)
|
RemoveFromIdList(df)
|
||||||
struct def *df;
|
struct def *df;
|
||||||
{
|
{
|
||||||
/* Remove definition "df" from the definition list
|
/* Remove definition "df" from the definition list
|
||||||
|
@ -438,11 +455,11 @@ struct def *
|
||||||
DeclProc(type)
|
DeclProc(type)
|
||||||
{
|
{
|
||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
static int nmcount = 0;
|
static int nmcount = 0;
|
||||||
extern char *Malloc();
|
|
||||||
extern char *strcpy();
|
extern char *strcpy();
|
||||||
extern char *sprint();
|
extern char *sprint();
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
@ -453,7 +470,7 @@ DeclProc(type)
|
||||||
/* In a definition module
|
/* In a definition module
|
||||||
*/
|
*/
|
||||||
df = define(dot.TOK_IDF, CurrentScope, type);
|
df = define(dot.TOK_IDF, CurrentScope, type);
|
||||||
df->for_node = MkNode(Name, NULLNODE, NULLNODE, &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,df->df_idf->id_text);
|
||||||
df->for_name = Malloc((unsigned) (strlen(buf)+1));
|
df->for_name = Malloc((unsigned) (strlen(buf)+1));
|
||||||
strcpy(df->for_name, buf);
|
strcpy(df->for_name, buf);
|
||||||
|
@ -512,12 +529,12 @@ AddModule(id)
|
||||||
register struct node *n;
|
register struct node *n;
|
||||||
extern struct node *Modules;
|
extern struct node *Modules;
|
||||||
|
|
||||||
n = MkNode(Name, NULLNODE, NULLNODE, &dot);
|
n = MkLeaf(Name, &dot);
|
||||||
n->nd_IDF = id;
|
n->nd_IDF = id;
|
||||||
n->nd_symb = IDENT;
|
n->nd_symb = IDENT;
|
||||||
if (nd_end) nd_end->next = n;
|
if (nd_end) nd_end->next = n;
|
||||||
|
else Modules = n;
|
||||||
nd_end = n;
|
nd_end = n;
|
||||||
if (!Modules) Modules = n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DefInFront(df)
|
DefInFront(df)
|
||||||
|
@ -528,14 +545,24 @@ DefInFront(df)
|
||||||
This is neccessary because in some cases the order in this
|
This is neccessary because in some cases the order in this
|
||||||
list is important.
|
list is important.
|
||||||
*/
|
*/
|
||||||
register struct def *df1;
|
register struct def *df1 = df->df_scope->sc_def;
|
||||||
|
|
||||||
if (df->df_scope->sc_def != df) {
|
if (df1 != df) {
|
||||||
df1 = df->df_scope->sc_def;
|
/* Definition "df" is not in front of the list
|
||||||
|
*/
|
||||||
while (df1 && df1->df_nextinscope != df) {
|
while (df1 && df1->df_nextinscope != df) {
|
||||||
|
/* Find definition "df"
|
||||||
|
*/
|
||||||
df1 = df1->df_nextinscope;
|
df1 = df1->df_nextinscope;
|
||||||
}
|
}
|
||||||
if (df1) df1->df_nextinscope = df->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_nextinscope = df->df_scope->sc_def;
|
||||||
df->df_scope->sc_def = df;
|
df->df_scope->sc_def = df;
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,7 +268,8 @@ CodeVarDesig(df, ds)
|
||||||
/* value or var parameter
|
/* value or var parameter
|
||||||
*/
|
*/
|
||||||
C_lxa((arith) (proclevel - sc->sc_level));
|
C_lxa((arith) (proclevel - sc->sc_level));
|
||||||
if (df->df_flags & D_VARPAR) {
|
if ((df->df_flags & D_VARPAR) ||
|
||||||
|
IsConformantArray(df->df_type)) {
|
||||||
/* var parameter
|
/* var parameter
|
||||||
*/
|
*/
|
||||||
C_adp(df->var_off);
|
C_adp(df->var_off);
|
||||||
|
@ -287,7 +288,7 @@ CodeVarDesig(df, ds)
|
||||||
|
|
||||||
/* Now, finally, we have a local variable or a local parameter
|
/* Now, finally, we have a local variable or a local parameter
|
||||||
*/
|
*/
|
||||||
if (df->df_flags & D_VARPAR) {
|
if ((df->df_flags & D_VARPAR) || IsConformantArray(df->df_type)) {
|
||||||
/* a var parameter; address directly accessible.
|
/* a var parameter; address directly accessible.
|
||||||
*/
|
*/
|
||||||
ds->dsg_kind = DSG_PFIXED;
|
ds->dsg_kind = DSG_PFIXED;
|
||||||
|
@ -303,10 +304,11 @@ CodeDesig(nd, ds)
|
||||||
/* Generate code for a designator. Use divide and conquer
|
/* Generate code for a designator. Use divide and conquer
|
||||||
principle
|
principle
|
||||||
*/
|
*/
|
||||||
|
register struct def *df;
|
||||||
|
|
||||||
switch(nd->nd_class) { /* Divide */
|
switch(nd->nd_class) { /* Divide */
|
||||||
case Def: {
|
case Def:
|
||||||
register struct def *df = nd->nd_def;
|
df = nd->nd_def;
|
||||||
|
|
||||||
df->df_flags |= D_USED;
|
df->df_flags |= D_USED;
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
|
@ -321,7 +323,6 @@ CodeDesig(nd, ds)
|
||||||
default:
|
default:
|
||||||
crash("(CodeDesig) Def");
|
crash("(CodeDesig) Def");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Link:
|
case Link:
|
||||||
|
@ -336,18 +337,24 @@ CodeDesig(nd, ds)
|
||||||
|
|
||||||
CodeDesig(nd->nd_left, ds);
|
CodeDesig(nd->nd_left, ds);
|
||||||
CodeAddress(ds);
|
CodeAddress(ds);
|
||||||
*ds = InitDesig;
|
CodePExpr(nd->nd_right);
|
||||||
CodeExpr(nd->nd_right, ds, NO_LABEL, NO_LABEL);
|
|
||||||
CodeValue(ds, nd->nd_right->nd_type->tp_size);
|
|
||||||
if (nd->nd_right->nd_type->tp_size > word_size) {
|
if (nd->nd_right->nd_type->tp_size > word_size) {
|
||||||
CodeCoercion(nd->nd_right->nd_type, int_type);
|
CodeCoercion(nd->nd_right->nd_type, int_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now load address of descriptor
|
||||||
|
*/
|
||||||
if (IsConformantArray(nd->nd_left->nd_type)) {
|
if (IsConformantArray(nd->nd_left->nd_type)) {
|
||||||
/* ??? */
|
assert(nd->nd_left->nd_class == Def);
|
||||||
|
|
||||||
|
df = nd->nd_left->nd_def;
|
||||||
|
if (proclevel > df->df_scope->sc_level) {
|
||||||
|
C_lxa(proclevel - df->df_scope->sc_level);
|
||||||
|
C_adp(df->var_off + pointer_size);
|
||||||
|
}
|
||||||
|
else C_lal(df->var_off + pointer_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* load address of descriptor
|
|
||||||
*/
|
|
||||||
C_lae_dlb(nd->nd_left->nd_type->arr_descr, (arith) 0);
|
C_lae_dlb(nd->nd_left->nd_type->arr_descr, (arith) 0);
|
||||||
}
|
}
|
||||||
ds->dsg_kind = DSG_INDEXED;
|
ds->dsg_kind = DSG_INDEXED;
|
||||||
|
|
|
@ -26,48 +26,51 @@ number(struct node **p;)
|
||||||
} :
|
} :
|
||||||
[
|
[
|
||||||
%default
|
%default
|
||||||
INTEGER { tp = numtype; }
|
INTEGER { tp = toktype; }
|
||||||
|
|
|
|
||||||
REAL { tp = real_type; }
|
REAL { tp = real_type; }
|
||||||
] { *p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
] { *p = MkLeaf(Value, &dot);
|
||||||
(*p)->nd_type = tp;
|
(*p)->nd_type = tp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
qualident(int types; struct def **pdf; char *str; struct node **p;)
|
qualident(int types;
|
||||||
|
struct def **pdf;
|
||||||
|
char *str;
|
||||||
|
struct node **p;
|
||||||
|
)
|
||||||
{
|
{
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
} :
|
} :
|
||||||
IDENT { nd = MkNode(Name, NULLNODE, NULLNODE, &dot);
|
IDENT { nd = MkLeaf(Name, &dot); }
|
||||||
}
|
|
||||||
[
|
[
|
||||||
selector(&nd)
|
selector(&nd)
|
||||||
]*
|
]*
|
||||||
{ if (types) {
|
{ if (types) {
|
||||||
df = ill_df;
|
df = ill_df;
|
||||||
|
|
||||||
if (chk_designator(nd, 0, D_REFERRED)) {
|
if (chk_designator(nd, 0, D_REFERRED)) {
|
||||||
if (nd->nd_class != Def) {
|
if (nd->nd_class != Def) {
|
||||||
node_error(nd, "%s expected", str);
|
node_error(nd, "%s expected", str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
df = nd->nd_def;
|
||||||
|
if ( !((types|D_ERROR) & df->df_kind)) {
|
||||||
|
if (df->df_kind == D_FORWARD) {
|
||||||
|
node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = nd->nd_def;
|
|
||||||
if ( !((types|D_ERROR) & df->df_kind)) {
|
|
||||||
if (df->df_kind == D_FORWARD) {
|
|
||||||
node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
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);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*pdf = df;
|
}
|
||||||
}
|
|
||||||
if (!p) FreeNode(nd);
|
|
||||||
else *p = nd;
|
|
||||||
}
|
}
|
||||||
|
*pdf = df;
|
||||||
|
}
|
||||||
|
if (!p) FreeNode(nd);
|
||||||
|
else *p = nd;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
selector(struct node **pnd;):
|
selector(struct node **pnd;):
|
||||||
|
@ -84,7 +87,7 @@ ExpList(struct node **pnd;)
|
||||||
nd = &((*pnd)->nd_right);
|
nd = &((*pnd)->nd_right);
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
',' { *nd = MkNode(Link, NULLNODE, NULLNODE, &dot);
|
',' { *nd = MkLeaf(Link, &dot);
|
||||||
}
|
}
|
||||||
expression(&(*nd)->nd_left)
|
expression(&(*nd)->nd_left)
|
||||||
{ nd = &((*nd)->nd_right); }
|
{ nd = &((*nd)->nd_right); }
|
||||||
|
@ -131,7 +134,7 @@ SimpleExpression(struct node **pnd;)
|
||||||
} :
|
} :
|
||||||
[
|
[
|
||||||
[ '+' | '-' ]
|
[ '+' | '-' ]
|
||||||
{ *pnd = MkNode(Uoper, NULLNODE, NULLNODE, &dot);
|
{ *pnd = MkLeaf(Uoper, &dot);
|
||||||
pnd = &((*pnd)->nd_right);
|
pnd = &((*pnd)->nd_right);
|
||||||
}
|
}
|
||||||
]?
|
]?
|
||||||
|
@ -191,23 +194,13 @@ factor(struct node **p;)
|
||||||
number(p)
|
number(p)
|
||||||
|
|
|
|
||||||
STRING {
|
STRING {
|
||||||
*p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
*p = MkLeaf(Value, &dot);
|
||||||
if (dot.TOK_SLE == 1) {
|
(*p)->nd_type = toktype;
|
||||||
int i;
|
|
||||||
|
|
||||||
tp = charc_type;
|
|
||||||
i = *(dot.TOK_STR) & 0377;
|
|
||||||
free(dot.TOK_STR);
|
|
||||||
free((char *) dot.tk_data.tk_str);
|
|
||||||
(*p)->nd_INT = i;
|
|
||||||
}
|
|
||||||
else tp = standard_type(T_STRING, 1, dot.TOK_SLE);
|
|
||||||
(*p)->nd_type = tp;
|
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
'(' expression(p) ')'
|
'(' expression(p) ')'
|
||||||
|
|
|
|
||||||
NOT { *p = MkNode(Uoper, NULLNODE, NULLNODE, &dot); }
|
NOT { *p = MkLeaf(Uoper, &dot); }
|
||||||
factor(&((*p)->nd_right))
|
factor(&((*p)->nd_right))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -217,7 +210,7 @@ bare_set(struct node **pnd;)
|
||||||
} :
|
} :
|
||||||
'{' {
|
'{' {
|
||||||
dot.tk_symb = SET;
|
dot.tk_symb = SET;
|
||||||
*pnd = nd = MkNode(Xset, NULLNODE, NULLNODE, &dot);
|
*pnd = nd = MkLeaf(Xset, &dot);
|
||||||
nd->nd_type = bitset_type;
|
nd->nd_type = bitset_type;
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
|
|
|
@ -111,27 +111,27 @@ Compile(src, dst)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LexScan()
|
LexScan()
|
||||||
{
|
{
|
||||||
register int symb;
|
register struct token *tkp = ˙
|
||||||
char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
|
||||||
while ((symb = LLlex()) > 0) {
|
while (LLlex() > 0) {
|
||||||
print(">>> %s ", symbol2str(symb));
|
print(">>> %s ", symbol2str(tkp->tk_symb));
|
||||||
switch(symb) {
|
switch(tkp->tk_symb) {
|
||||||
|
|
||||||
case IDENT:
|
case IDENT:
|
||||||
print("%s\n", dot.TOK_IDF->id_text);
|
print("%s\n", tkp->TOK_IDF->id_text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
print("%ld\n", dot.TOK_INT);
|
print("%ld\n", tkp->TOK_INT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REAL:
|
case REAL:
|
||||||
print("%s\n", dot.TOK_REL);
|
print("%s\n", tkp->TOK_REL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
print("\"%s\"\n", dot.TOK_STR);
|
print("\"%s\"\n", tkp->TOK_STR);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct node {
|
||||||
|
|
||||||
/* ALLOCDEF "node" */
|
/* ALLOCDEF "node" */
|
||||||
|
|
||||||
extern struct node *MkNode();
|
extern struct node *MkNode(), *MkLeaf();
|
||||||
|
|
||||||
#define NULLNODE ((struct node *) 0)
|
#define NULLNODE ((struct node *) 0)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,19 @@ MkNode(class, left, right, token)
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct node *
|
||||||
|
MkLeaf(class, token)
|
||||||
|
struct token *token;
|
||||||
|
{
|
||||||
|
register struct node *nd = new_node();
|
||||||
|
|
||||||
|
nd->nd_left = nd->nd_right = 0;
|
||||||
|
nd->nd_token = *token;
|
||||||
|
nd->nd_type = error_type;
|
||||||
|
nd->nd_class = class;
|
||||||
|
return nd;
|
||||||
|
}
|
||||||
|
|
||||||
FreeNode(nd)
|
FreeNode(nd)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,6 @@ static char *RcsId = "$Header$";
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
static int DEFofIMPL = 0; /* Flag indicating that we are currently
|
|
||||||
parsing the definition module of the
|
|
||||||
implementation module currently being
|
|
||||||
compiled
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
The grammar as given by Wirth is already almost LL(1); the
|
The grammar as given by Wirth is already almost LL(1); the
|
||||||
|
@ -132,7 +127,7 @@ import(int local;)
|
||||||
struct node *id = 0;
|
struct node *id = 0;
|
||||||
} :
|
} :
|
||||||
[ FROM
|
[ FROM
|
||||||
IDENT { id = MkNode(Value, NULLNODE, NULLNODE, &dot); }
|
IDENT { id = MkLeaf(Value, &dot); }
|
||||||
]?
|
]?
|
||||||
IMPORT IdentList(&ImportList) ';'
|
IMPORT IdentList(&ImportList) ';'
|
||||||
/*
|
/*
|
||||||
|
@ -176,12 +171,6 @@ DefinitionModule
|
||||||
*/
|
*/
|
||||||
definition* END IDENT
|
definition* END IDENT
|
||||||
{
|
{
|
||||||
if (DEFofIMPL) {
|
|
||||||
/* Just read the definition module of the
|
|
||||||
implementation module being compiled
|
|
||||||
*/
|
|
||||||
RemImports(&(CurrentScope->sc_def));
|
|
||||||
}
|
|
||||||
df = CurrentScope->sc_def;
|
df = CurrentScope->sc_def;
|
||||||
while (df) {
|
while (df) {
|
||||||
/* Make all definitions "QUALIFIED EXPORT" */
|
/* Make all definitions "QUALIFIED EXPORT" */
|
||||||
|
@ -211,7 +200,7 @@ definition
|
||||||
It is restricted to pointer types.
|
It is restricted to pointer types.
|
||||||
*/
|
*/
|
||||||
{ df->df_kind = D_HIDDEN;
|
{ df->df_kind = D_HIDDEN;
|
||||||
df->df_type = construct_type(T_POINTER, NULLTYPE);
|
df->df_type = construct_type(T_HIDDEN, NULLTYPE);
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Semicolon
|
Semicolon
|
||||||
|
@ -239,11 +228,10 @@ ProgramModule
|
||||||
IDENT {
|
IDENT {
|
||||||
id = dot.TOK_IDF;
|
id = dot.TOK_IDF;
|
||||||
if (state == IMPLEMENTATION) {
|
if (state == IMPLEMENTATION) {
|
||||||
DEFofIMPL = 1;
|
|
||||||
df = GetDefinitionModule(id);
|
df = GetDefinitionModule(id);
|
||||||
CurrVis = df->mod_vis;
|
CurrVis = df->mod_vis;
|
||||||
CurrentScope = CurrVis->sc_scope;
|
CurrentScope = CurrVis->sc_scope;
|
||||||
DEFofIMPL = 0;
|
RemoveImports(&(CurrentScope->sc_def));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = define(id, CurrentScope, D_MODULE);
|
df = define(id, CurrentScope, D_MODULE);
|
||||||
|
|
|
@ -18,11 +18,10 @@ static char *RcsId = "$Header$";
|
||||||
static int loopcount = 0; /* Count nested loops */
|
static int loopcount = 0; /* Count nested loops */
|
||||||
}
|
}
|
||||||
|
|
||||||
statement(struct node **pnd;)
|
statement(register struct node **pnd;)
|
||||||
{
|
{
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
} :
|
} :
|
||||||
{ *pnd = 0; }
|
|
||||||
[
|
[
|
||||||
/*
|
/*
|
||||||
* This part is not in the reference grammar. The reference grammar
|
* This part is not in the reference grammar. The reference grammar
|
||||||
|
@ -61,11 +60,13 @@ statement(struct node **pnd;)
|
||||||
|
|
|
|
||||||
EXIT
|
EXIT
|
||||||
{ if (!loopcount) error("EXIT not in a LOOP");
|
{ if (!loopcount) error("EXIT not in a LOOP");
|
||||||
*pnd = MkNode(Stat, NULLNODE, NULLNODE, &dot);
|
*pnd = MkLeaf(Stat, &dot);
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
ReturnStatement(pnd)
|
ReturnStatement(pnd)
|
||||||
]?
|
|
|
||||||
|
/* empty */ { *pnd = 0; }
|
||||||
|
]
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -80,7 +81,9 @@ ProcedureCall:
|
||||||
;
|
;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
StatementSequence(struct node **pnd;):
|
StatementSequence(register struct node **pnd;)
|
||||||
|
{
|
||||||
|
} :
|
||||||
statement(pnd)
|
statement(pnd)
|
||||||
[
|
[
|
||||||
';' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
|
';' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
|
||||||
|
@ -94,21 +97,21 @@ IfStatement(struct node **pnd;)
|
||||||
{
|
{
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
} :
|
} :
|
||||||
IF { nd = MkNode(Stat, NULLNODE, NULLNODE, &dot);
|
IF { nd = MkLeaf(Stat, &dot);
|
||||||
*pnd = nd;
|
*pnd = nd;
|
||||||
}
|
}
|
||||||
expression(&(nd->nd_left))
|
expression(&(nd->nd_left))
|
||||||
THEN { nd = MkNode(Link, NULLNODE, NULLNODE, &dot);
|
THEN { nd->nd_right = MkLeaf(Link, &dot);
|
||||||
(*pnd)->nd_right = nd;
|
nd = nd->nd_right;
|
||||||
}
|
}
|
||||||
StatementSequence(&(nd->nd_left))
|
StatementSequence(&(nd->nd_left))
|
||||||
[
|
[
|
||||||
ELSIF { nd->nd_right = MkNode(Stat,NULLNODE,NULLNODE,&dot);
|
ELSIF { nd->nd_right = MkLeaf(Stat, &dot);
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
nd->nd_symb = IF;
|
nd->nd_symb = IF;
|
||||||
}
|
}
|
||||||
expression(&(nd->nd_left))
|
expression(&(nd->nd_left))
|
||||||
THEN { nd->nd_right = MkNode(Link,NULLNODE,NULLNODE,&dot);
|
THEN { nd->nd_right = MkLeaf(Link, &dot);
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
}
|
}
|
||||||
StatementSequence(&(nd->nd_left))
|
StatementSequence(&(nd->nd_left))
|
||||||
|
@ -125,7 +128,7 @@ CaseStatement(struct node **pnd;)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
struct type *tp = 0;
|
struct type *tp = 0;
|
||||||
} :
|
} :
|
||||||
CASE { *pnd = nd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
CASE { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
expression(&(nd->nd_left))
|
expression(&(nd->nd_left))
|
||||||
OF
|
OF
|
||||||
case(&(nd->nd_right), &tp)
|
case(&(nd->nd_right), &tp)
|
||||||
|
@ -140,12 +143,10 @@ CaseStatement(struct node **pnd;)
|
||||||
;
|
;
|
||||||
|
|
||||||
case(struct node **pnd; struct type **ptp;) :
|
case(struct node **pnd; struct type **ptp;) :
|
||||||
{ *pnd = 0; }
|
|
||||||
[ CaseLabelList(ptp, pnd)
|
[ CaseLabelList(ptp, pnd)
|
||||||
':' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot); }
|
':' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot); }
|
||||||
StatementSequence(&((*pnd)->nd_right))
|
StatementSequence(&((*pnd)->nd_right))
|
||||||
]?
|
]?
|
||||||
/* This rule is changed in new modula-2 */
|
|
||||||
{ *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
|
{ *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
|
||||||
(*pnd)->nd_symb = '|';
|
(*pnd)->nd_symb = '|';
|
||||||
}
|
}
|
||||||
|
@ -155,7 +156,7 @@ WhileStatement(struct node **pnd;)
|
||||||
{
|
{
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
}:
|
}:
|
||||||
WHILE { *pnd = nd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
WHILE { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
expression(&(nd->nd_left))
|
expression(&(nd->nd_left))
|
||||||
DO
|
DO
|
||||||
StatementSequence(&(nd->nd_right))
|
StatementSequence(&(nd->nd_right))
|
||||||
|
@ -166,7 +167,7 @@ RepeatStatement(struct node **pnd;)
|
||||||
{
|
{
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
}:
|
}:
|
||||||
REPEAT { *pnd = nd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
REPEAT { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
StatementSequence(&(nd->nd_left))
|
StatementSequence(&(nd->nd_left))
|
||||||
UNTIL
|
UNTIL
|
||||||
expression(&(nd->nd_right))
|
expression(&(nd->nd_right))
|
||||||
|
@ -177,10 +178,10 @@ ForStatement(struct node **pnd;)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
struct node *dummy;
|
struct node *dummy;
|
||||||
}:
|
}:
|
||||||
FOR { *pnd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
FOR { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
|
IDENT { nd->nd_IDF = dot.TOK_IDF; }
|
||||||
BECOMES { nd = MkNode(Stat, NULLNODE, NULLNODE, &dot);
|
BECOMES { nd->nd_left = MkLeaf(Stat, &dot);
|
||||||
(*pnd)->nd_left = nd;
|
nd = nd->nd_left;
|
||||||
}
|
}
|
||||||
expression(&(nd->nd_left))
|
expression(&(nd->nd_left))
|
||||||
TO
|
TO
|
||||||
|
@ -204,7 +205,7 @@ ForStatement(struct node **pnd;)
|
||||||
;
|
;
|
||||||
|
|
||||||
LoopStatement(struct node **pnd;):
|
LoopStatement(struct node **pnd;):
|
||||||
LOOP { *pnd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
LOOP { *pnd = MkLeaf(Stat, &dot); }
|
||||||
StatementSequence(&((*pnd)->nd_right))
|
StatementSequence(&((*pnd)->nd_right))
|
||||||
END
|
END
|
||||||
;
|
;
|
||||||
|
@ -213,7 +214,7 @@ WithStatement(struct node **pnd;)
|
||||||
{
|
{
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
}:
|
}:
|
||||||
WITH { *pnd = nd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
WITH { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
designator(&(nd->nd_left))
|
designator(&(nd->nd_left))
|
||||||
DO
|
DO
|
||||||
StatementSequence(&(nd->nd_right))
|
StatementSequence(&(nd->nd_right))
|
||||||
|
@ -226,7 +227,7 @@ ReturnStatement(struct node **pnd;)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
} :
|
} :
|
||||||
|
|
||||||
RETURN { *pnd = nd = MkNode(Stat, NULLNODE, NULLNODE, &dot); }
|
RETURN { *pnd = nd = MkLeaf(Stat, &dot); }
|
||||||
[
|
[
|
||||||
expression(&(nd->nd_right))
|
expression(&(nd->nd_right))
|
||||||
{ if (scopeclosed(CurrentScope)) {
|
{ if (scopeclosed(CurrentScope)) {
|
||||||
|
|
|
@ -21,18 +21,20 @@ struct enume {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subrange {
|
struct subrange {
|
||||||
arith su_lb, su_ub; /* Lower bound and upper bound */
|
arith su_lb, su_ub; /* lower bound and upper bound */
|
||||||
label su_rck; /* Label of range check descriptor */
|
label su_rck; /* label of range check descriptor */
|
||||||
#define sub_lb tp_value.tp_subrange.su_lb
|
#define sub_lb tp_value.tp_subrange.su_lb
|
||||||
#define sub_ub tp_value.tp_subrange.su_ub
|
#define sub_ub tp_value.tp_subrange.su_ub
|
||||||
#define sub_rck tp_value.tp_subrange.su_rck
|
#define sub_rck tp_value.tp_subrange.su_rck
|
||||||
};
|
};
|
||||||
|
|
||||||
struct array {
|
struct array {
|
||||||
struct type *ar_elem; /* Type of elements */
|
struct type *ar_elem; /* type of elements */
|
||||||
label ar_descr; /* Label of array descriptor */
|
label ar_descr; /* label of array descriptor */
|
||||||
|
arith ar_elsize; /* size of elements */
|
||||||
#define arr_elem tp_value.tp_arr.ar_elem
|
#define arr_elem tp_value.tp_arr.ar_elem
|
||||||
#define arr_descr tp_value.tp_arr.ar_descr
|
#define arr_descr tp_value.tp_arr.ar_descr
|
||||||
|
#define arr_elsize tp_value.tp_arr.ar_elsize
|
||||||
};
|
};
|
||||||
|
|
||||||
struct record {
|
struct record {
|
||||||
|
@ -59,7 +61,7 @@ struct type {
|
||||||
#define T_CARDINAL 0x0008
|
#define T_CARDINAL 0x0008
|
||||||
/* #define T_LONGINT 0x0010 */
|
/* #define T_LONGINT 0x0010 */
|
||||||
#define T_REAL 0x0020
|
#define T_REAL 0x0020
|
||||||
/* #define T_LONGREAL 0x0040 */
|
#define T_HIDDEN 0x0040
|
||||||
#define T_POINTER 0x0080
|
#define T_POINTER 0x0080
|
||||||
#define T_CHAR 0x0100
|
#define T_CHAR 0x0100
|
||||||
#define T_WORD 0x0200
|
#define T_WORD 0x0200
|
||||||
|
@ -89,7 +91,6 @@ 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,
|
||||||
|
@ -132,7 +133,7 @@ struct type
|
||||||
|
|
||||||
#define NULLTYPE ((struct type *) 0)
|
#define NULLTYPE ((struct type *) 0)
|
||||||
|
|
||||||
#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) ||\
|
#define returntype(tpx) (((tpx)->tp_fund & T_PRCRESULT) ||\
|
||||||
|
|
|
@ -45,7 +45,6 @@ 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,
|
||||||
|
@ -72,7 +71,7 @@ extern label data_label();
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
create_type(fund)
|
create_type(fund)
|
||||||
register int fund;
|
int fund;
|
||||||
{
|
{
|
||||||
/* A brand new struct type is created, and its tp_fund set
|
/* A brand new struct type is created, and its tp_fund set
|
||||||
to fund.
|
to fund.
|
||||||
|
@ -81,29 +80,29 @@ create_type(fund)
|
||||||
|
|
||||||
clear((char *)ntp, sizeof(struct type));
|
clear((char *)ntp, sizeof(struct type));
|
||||||
ntp->tp_fund = fund;
|
ntp->tp_fund = fund;
|
||||||
ntp->tp_size = (arith)-1;
|
|
||||||
|
|
||||||
return ntp;
|
return ntp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
construct_type(fund, tp)
|
construct_type(fund, tp)
|
||||||
struct type *tp;
|
int fund;
|
||||||
|
register struct type *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.
|
||||||
*/
|
*/
|
||||||
struct type *dtp = create_type(fund);
|
register struct type *dtp = create_type(fund);
|
||||||
|
|
||||||
switch (fund) {
|
switch (fund) {
|
||||||
case T_PROCEDURE:
|
case T_PROCEDURE:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_HIDDEN:
|
||||||
dtp->tp_align = pointer_align;
|
dtp->tp_align = pointer_align;
|
||||||
dtp->tp_size = pointer_size;
|
dtp->tp_size = pointer_size;
|
||||||
dtp->next = tp;
|
dtp->next = tp;
|
||||||
if (fund == T_PROCEDURE && tp) {
|
if (fund == T_PROCEDURE && tp) {
|
||||||
if (tp != bitset_type &&
|
if (! returntype(tp)) {
|
||||||
!(tp->tp_fund&(T_NUMERIC|T_INDEX|T_WORD|T_POINTER))) {
|
|
||||||
error("illegal procedure result type");
|
error("illegal procedure result type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +141,9 @@ align(pos, al)
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
standard_type(fund, align, size)
|
standard_type(fund, align, size)
|
||||||
int align; arith size;
|
int fund;
|
||||||
|
int align;
|
||||||
|
arith size;
|
||||||
{
|
{
|
||||||
register struct type *tp = create_type(fund);
|
register struct type *tp = create_type(fund);
|
||||||
|
|
||||||
|
@ -161,15 +162,19 @@ init_types()
|
||||||
/* first, do some checking
|
/* first, do some checking
|
||||||
*/
|
*/
|
||||||
if (int_size != word_size) {
|
if (int_size != word_size) {
|
||||||
fatal("Integer size not equal to word size");
|
fatal("integer size not equal to word size");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (long_size < int_size) {
|
if (long_size < int_size || long_size % word_size != 0) {
|
||||||
fatal("Long integer size smaller than integer size");
|
fatal("illegal long integer size");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (double_size < float_size) {
|
if (double_size < float_size) {
|
||||||
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
|
||||||
|
@ -177,12 +182,6 @@ 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;
|
||||||
|
|
||||||
/* character constant type, different from character type because
|
|
||||||
of compatibility with character array's
|
|
||||||
*/
|
|
||||||
charc_type = standard_type(T_CHAR, 1, (arith) 1);
|
|
||||||
charc_type->enm_ncst = 256;
|
|
||||||
|
|
||||||
/* boolean type
|
/* boolean type
|
||||||
*/
|
*/
|
||||||
bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
|
bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
|
||||||
|
@ -226,28 +225,36 @@ ParamList(ppr, ids, tp, VARp, off)
|
||||||
register struct node *ids;
|
register struct node *ids;
|
||||||
struct paramlist **ppr;
|
struct paramlist **ppr;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
int VARp;
|
||||||
arith *off;
|
arith *off;
|
||||||
{
|
{
|
||||||
/* Create (part of) a parameterlist of a procedure.
|
/* Create (part of) a parameterlist of a procedure.
|
||||||
"ids" indicates the list of identifiers, "tp" their type, and
|
"ids" indicates the list of identifiers, "tp" their type, and
|
||||||
"VARp" is set when the parameters are VAR-parameters.
|
"VARp" indicates D_VARPAR or D_VALPAR.
|
||||||
*/
|
*/
|
||||||
register struct paramlist *pr;
|
register struct paramlist *pr;
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct paramlist *pstart;
|
|
||||||
|
|
||||||
while (ids) {
|
for ( ; ids; ids = ids->next) {
|
||||||
pr = new_paramlist();
|
pr = new_paramlist();
|
||||||
pr->next = *ppr;
|
pr->next = *ppr;
|
||||||
*ppr = pr;
|
*ppr = pr;
|
||||||
df = define(ids->nd_IDF, CurrentScope, D_VARIABLE);
|
df = define(ids->nd_IDF, CurrentScope, D_VARIABLE);
|
||||||
pr->par_def = df;
|
pr->par_def = df;
|
||||||
df->df_type = tp;
|
df->df_type = tp;
|
||||||
if (VARp) df->df_flags = D_VARPAR;
|
|
||||||
else df->df_flags = D_VALPAR;
|
|
||||||
df->var_off = align(*off, word_align);
|
df->var_off = align(*off, word_align);
|
||||||
*off = df->var_off + tp->tp_size;
|
df->df_flags = VARp;
|
||||||
ids = ids->next;
|
if (IsConformantArray(tp)) {
|
||||||
|
/* we need room for the base address and a descriptor
|
||||||
|
*/
|
||||||
|
*off = df->var_off + pointer_size + 3 * word_size;
|
||||||
|
}
|
||||||
|
else if (VARp == D_VARPAR) {
|
||||||
|
*off = df->var_off + pointer_size;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*off = df->var_off + tp->tp_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +274,7 @@ chk_basesubrange(tp, base)
|
||||||
base = base->next;
|
base = base->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base->tp_fund == T_ENUMERATION || base->tp_fund == T_CHAR) {
|
if (base->tp_fund & (T_ENUMERATION|T_CHAR)) {
|
||||||
if (tp->next != base) {
|
if (tp->next != base) {
|
||||||
error("Specified base does not conform");
|
error("Specified base does not conform");
|
||||||
}
|
}
|
||||||
|
@ -384,7 +391,7 @@ getbounds(tp, plo, phi)
|
||||||
}
|
}
|
||||||
struct type *
|
struct type *
|
||||||
set_type(tp)
|
set_type(tp)
|
||||||
struct type *tp;
|
register struct type *tp;
|
||||||
{
|
{
|
||||||
/* Construct a set type with base type "tp", but first
|
/* Construct a set type with base type "tp", but first
|
||||||
perform some checks
|
perform some checks
|
||||||
|
@ -414,22 +421,33 @@ set_type(tp)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arith
|
||||||
|
ArrayElSize(tp)
|
||||||
|
register struct type *tp;
|
||||||
|
{
|
||||||
|
/* Align element size to alignment requirement of element type.
|
||||||
|
Also make sure that its size is either a dividor of the word_size,
|
||||||
|
or a multiple of it.
|
||||||
|
*/
|
||||||
|
arith algn;
|
||||||
|
|
||||||
|
if (tp->tp_fund == T_ARRAY) ArraySizes(tp);
|
||||||
|
algn = align(tp->tp_size, tp->tp_align);
|
||||||
|
if (!(algn % word_size == 0 || word_size % algn == 0)) {
|
||||||
|
algn = align(algn, word_size);
|
||||||
|
}
|
||||||
|
return algn;
|
||||||
|
}
|
||||||
|
|
||||||
ArraySizes(tp)
|
ArraySizes(tp)
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
{
|
{
|
||||||
/* Assign sizes to an array type, and check index type
|
/* Assign sizes to an array type, and check index type
|
||||||
*/
|
*/
|
||||||
arith elem_size;
|
|
||||||
register struct type *index_type = tp->next;
|
register struct type *index_type = tp->next;
|
||||||
register struct type *elem_type = tp->arr_elem;
|
register struct type *elem_type = tp->arr_elem;
|
||||||
|
|
||||||
if (elem_type->tp_fund == T_ARRAY) {
|
tp->arr_elsize = ArrayElSize(elem_type);
|
||||||
ArraySizes(elem_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* align element size to alignment requirement of element type
|
|
||||||
*/
|
|
||||||
elem_size = align(elem_type->tp_size, elem_type->tp_align);
|
|
||||||
tp->tp_align = elem_type->tp_align;
|
tp->tp_align = elem_type->tp_align;
|
||||||
|
|
||||||
/* check index type
|
/* check index type
|
||||||
|
@ -447,7 +465,7 @@ ArraySizes(tp)
|
||||||
|
|
||||||
switch(index_type->tp_fund) {
|
switch(index_type->tp_fund) {
|
||||||
case T_SUBRANGE:
|
case T_SUBRANGE:
|
||||||
tp->tp_size = elem_size *
|
tp->tp_size = tp->arr_elsize *
|
||||||
(index_type->sub_ub - index_type->sub_lb + 1);
|
(index_type->sub_ub - index_type->sub_lb + 1);
|
||||||
C_rom_cst(index_type->sub_lb);
|
C_rom_cst(index_type->sub_lb);
|
||||||
C_rom_cst(index_type->sub_ub - index_type->sub_lb);
|
C_rom_cst(index_type->sub_ub - index_type->sub_lb);
|
||||||
|
@ -455,7 +473,7 @@ ArraySizes(tp)
|
||||||
|
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
tp->tp_size = elem_size * index_type->enm_ncst;
|
tp->tp_size = tp->arr_elsize * index_type->enm_ncst;
|
||||||
C_rom_cst((arith) 0);
|
C_rom_cst((arith) 0);
|
||||||
C_rom_cst((arith) (index_type->enm_ncst - 1));
|
C_rom_cst((arith) (index_type->enm_ncst - 1));
|
||||||
break;
|
break;
|
||||||
|
@ -464,7 +482,7 @@ ArraySizes(tp)
|
||||||
crash("Funny index type");
|
crash("Funny index type");
|
||||||
}
|
}
|
||||||
|
|
||||||
C_rom_cst(elem_size);
|
C_rom_cst(tp->arr_elsize);
|
||||||
|
|
||||||
/* ??? overflow checking ???
|
/* ??? overflow checking ???
|
||||||
*/
|
*/
|
||||||
|
@ -473,7 +491,9 @@ ArraySizes(tp)
|
||||||
FreeType(tp)
|
FreeType(tp)
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
{
|
{
|
||||||
/* Release type structures indicated by "tp"
|
/* Release type structures indicated by "tp".
|
||||||
|
This procedure is only called for types, constructed with
|
||||||
|
T_PROCEDURE.
|
||||||
*/
|
*/
|
||||||
register struct paramlist *pr, *pr1;
|
register struct paramlist *pr, *pr1;
|
||||||
|
|
||||||
|
|
|
@ -105,10 +105,6 @@ TstCompat(tp1, tp2)
|
||||||
&&
|
&&
|
||||||
(tp1 == int_type || tp1 == card_type)
|
(tp1 == int_type || tp1 == card_type)
|
||||||
)
|
)
|
||||||
||
|
|
||||||
(tp1 == char_type && tp2 == charc_type)
|
|
||||||
||
|
|
||||||
(tp2 == char_type && tp1 == charc_type)
|
|
||||||
||
|
||
|
||||||
( tp1 == address_type
|
( tp1 == address_type
|
||||||
&&
|
&&
|
||||||
|
@ -145,8 +141,6 @@ TstAssCompat(tp1, tp2)
|
||||||
if ((tp1->tp_fund & T_INTORCARD) &&
|
if ((tp1->tp_fund & T_INTORCARD) &&
|
||||||
(tp2->tp_fund & T_INTORCARD)) return 1;
|
(tp2->tp_fund & T_INTORCARD)) return 1;
|
||||||
|
|
||||||
if (tp1 == char_type && tp2 == charc_type) return 1;
|
|
||||||
|
|
||||||
if (tp1->tp_fund == T_ARRAY) {
|
if (tp1->tp_fund == T_ARRAY) {
|
||||||
/* check for string
|
/* check for string
|
||||||
*/
|
*/
|
||||||
|
@ -162,12 +156,8 @@ TstAssCompat(tp1, tp2)
|
||||||
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
||||||
return
|
return
|
||||||
tp1 == char_type
|
tp1 == char_type
|
||||||
&&
|
&& (tp2->tp_fund == T_STRING && size >= tp2->tp_size)
|
||||||
(
|
;
|
||||||
tp2 == charc_type
|
|
||||||
||
|
|
||||||
(tp2->tp_fund == T_STRING && size >= tp2->tp_size)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,7 +25,6 @@ static char *RcsId = "$Header$";
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
|
||||||
extern arith align();
|
|
||||||
extern arith NewPtr();
|
extern arith NewPtr();
|
||||||
extern arith NewInt();
|
extern arith NewInt();
|
||||||
extern int proclevel;
|
extern int proclevel;
|
||||||
|
@ -58,7 +57,7 @@ DoProfil()
|
||||||
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));
|
C_rom_scon(FileName, (arith) (strlen(FileName) + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
C_fil_dlb(filename_label, (arith) 0);
|
C_fil_dlb(filename_label, (arith) 0);
|
||||||
|
@ -131,20 +130,22 @@ WalkModule(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.
|
||||||
*/
|
*/
|
||||||
label l1 = data_label(), l2 = text_label();
|
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
|
|
||||||
/* we don't actually prevent recursive calls, but do nothing
|
if (state == IMPLEMENTATION) {
|
||||||
if called recursively
|
label l1 = data_label(), l2 = text_label();
|
||||||
*/
|
/* we don't actually prevent recursive calls,
|
||||||
C_df_dlb(l1);
|
but do nothing if called recursively
|
||||||
C_bss_cst(word_size, (arith) 0, 1);
|
*/
|
||||||
C_loe_dlb(l1, (arith) 0);
|
C_df_dlb(l1);
|
||||||
C_zeq(l2);
|
C_bss_cst(word_size, (arith) 0, 1);
|
||||||
C_ret((arith) 0);
|
C_loe_dlb(l1, (arith) 0);
|
||||||
C_df_ilb(l2);
|
C_zeq(l2);
|
||||||
C_loc((arith) 1);
|
C_ret((arith) 0);
|
||||||
C_ste_dlb(l1, (arith) 0);
|
C_df_ilb(l2);
|
||||||
|
C_loc((arith) 1);
|
||||||
|
C_ste_dlb(l1, (arith) 0);
|
||||||
|
}
|
||||||
|
|
||||||
nd = Modules;
|
nd = Modules;
|
||||||
while (nd) {
|
while (nd) {
|
||||||
|
@ -278,7 +279,7 @@ WalkStat(nd, lab)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options['L']) C_lin((arith) nd->nd_lineno);
|
if (! options['L']) C_lin((arith) nd->nd_lineno);
|
||||||
|
|
||||||
if (nd->nd_class == Call) {
|
if (nd->nd_class == Call) {
|
||||||
if (chk_call(nd)) {
|
if (chk_call(nd)) {
|
||||||
|
@ -541,8 +542,11 @@ DoAssign(nd, left, right)
|
||||||
/* May we do it in this order (expression first) ??? */
|
/* May we do it in this order (expression first) ??? */
|
||||||
struct desig ds;
|
struct desig ds;
|
||||||
|
|
||||||
WalkExpr(right, NO_LABEL, NO_LABEL);
|
if (!chk_expr(right)) return;
|
||||||
if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return;
|
if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return;
|
||||||
|
TryToString(right, left->nd_type);
|
||||||
|
Desig = InitDesig;
|
||||||
|
CodeExpr(right, &Desig, NO_LABEL, NO_LABEL);
|
||||||
|
|
||||||
if (! TstAssCompat(left->nd_type, right->nd_type)) {
|
if (! TstAssCompat(left->nd_type, right->nd_type)) {
|
||||||
node_error(nd, "type incompatibility in assignment");
|
node_error(nd, "type incompatibility in assignment");
|
||||||
|
|
Loading…
Reference in a new issue