newer version
This commit is contained in:
parent
dd5b8dfabf
commit
53e3cd60d0
16 changed files with 379 additions and 228 deletions
|
@ -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(str->s_length = ISTRSIZE);
|
str->s_str = p = Malloc((unsigned int) (str->s_length = ISTRSIZE));
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
while (ch != upto) {
|
while (ch != upto) {
|
||||||
if (class(ch) == STNL) {
|
if (class(ch) == STNL) {
|
||||||
|
@ -91,7 +91,7 @@ GetString(upto)
|
||||||
*p++ = ch;
|
*p++ = ch;
|
||||||
if (p - str->s_str == str->s_length) {
|
if (p - str->s_str == str->s_length) {
|
||||||
str->s_str = Srealloc(str->s_str,
|
str->s_str = Srealloc(str->s_str,
|
||||||
str->s_length + RSTRSIZE);
|
(unsigned int) str->s_length + RSTRSIZE);
|
||||||
p = str->s_str + str->s_length;
|
p = str->s_str + str->s_length;
|
||||||
str->s_length += RSTRSIZE;
|
str->s_length += RSTRSIZE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
struct string {
|
struct string {
|
||||||
unsigned int s_length; /* length of a string */
|
arith s_length; /* length of a string */
|
||||||
char *s_str; /* the string itself */
|
char *s_str; /* the string itself */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -388,6 +388,8 @@ FlagCheck(expp, df, flag)
|
||||||
"flag". Here, a definition "df" is checked against it.
|
"flag". Here, a definition "df" is checked against it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (df->df_kind == D_ERROR) return 0;
|
||||||
|
|
||||||
if ((flag & VARIABLE) &&
|
if ((flag & VARIABLE) &&
|
||||||
!(df->df_kind & (D_FIELD|D_VARIABLE))) {
|
!(df->df_kind & (D_FIELD|D_VARIABLE))) {
|
||||||
node_error(expp, "variable expected");
|
node_error(expp, "variable expected");
|
||||||
|
@ -432,7 +434,7 @@ chk_designator(expp, flag)
|
||||||
expp->nd_type = error_type;
|
expp->nd_type = error_type;
|
||||||
|
|
||||||
if (expp->nd_class == Name) {
|
if (expp->nd_class == Name) {
|
||||||
expp->nd_def = lookfor(expp, CurrentScope, 1);
|
expp->nd_def = lookfor(expp, CurrVis, 1);
|
||||||
expp->nd_class = Def;
|
expp->nd_class = Def;
|
||||||
expp->nd_type = expp->nd_def->df_type;
|
expp->nd_type = expp->nd_def->df_type;
|
||||||
if (expp->nd_type == error_type) return 0;
|
if (expp->nd_type == error_type) return 0;
|
||||||
|
@ -489,8 +491,15 @@ df->df_idf->id_text);
|
||||||
expp->nd_symb = INTEGER;
|
expp->nd_symb = INTEGER;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
char *fn;
|
||||||
|
int ln;
|
||||||
|
|
||||||
assert(df->df_kind == D_CONST);
|
assert(df->df_kind == D_CONST);
|
||||||
|
ln = expp->nd_lineno;
|
||||||
|
fn = expp->nd_filename;
|
||||||
*expp = *(df->con_const);
|
*expp = *(df->con_const);
|
||||||
|
expp->nd_lineno = ln;
|
||||||
|
expp->nd_filename = fn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +600,7 @@ node_error(expp, "RHS of IN operator not a SET type");
|
||||||
}
|
}
|
||||||
if (!TstAssCompat(tpl, tpr->next)) {
|
if (!TstAssCompat(tpl, tpr->next)) {
|
||||||
/* Assignment compatible ???
|
/* Assignment compatible ???
|
||||||
I don't know! Should we be allowed th check
|
I don't know! Should we be allowed to check
|
||||||
if a CARDINAL is a member of a BITSET???
|
if a CARDINAL is a member of a BITSET???
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -620,6 +629,9 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
switch(tpl->tp_fund) {
|
switch(tpl->tp_fund) {
|
||||||
|
case T_POINTER:
|
||||||
|
if (tpl != address_type) break;
|
||||||
|
/* Fall through */
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
|
@ -654,7 +666,7 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
|
|
||||||
case DIV:
|
case DIV:
|
||||||
case MOD:
|
case MOD:
|
||||||
if (tpl->tp_fund & T_INTORCARD) {
|
if ((tpl->tp_fund & T_INTORCARD) || tpl == address_type) {
|
||||||
if (left->nd_class==Value && right->nd_class==Value) {
|
if (left->nd_class==Value && right->nd_class==Value) {
|
||||||
cstbin(expp);
|
cstbin(expp);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +748,8 @@ chk_uoper(expp)
|
||||||
{
|
{
|
||||||
/* Check an unary operation.
|
/* Check an unary operation.
|
||||||
*/
|
*/
|
||||||
register struct type *tpr = expp->nd_right->nd_type;
|
register struct node *right = expp->nd_right;
|
||||||
|
register struct type *tpr = right->nd_type;
|
||||||
|
|
||||||
if (tpr->tp_fund == T_SUBRANGE) tpr = tpr->next;
|
if (tpr->tp_fund == T_SUBRANGE) tpr = tpr->next;
|
||||||
expp->nd_type = tpr;
|
expp->nd_type = tpr;
|
||||||
|
@ -744,8 +757,8 @@ chk_uoper(expp)
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case '+':
|
case '+':
|
||||||
if (tpr->tp_fund & T_NUMERIC) {
|
if (tpr->tp_fund & T_NUMERIC) {
|
||||||
expp->nd_token = expp->nd_right->nd_token;
|
expp->nd_token = right->nd_token;
|
||||||
FreeNode(expp->nd_right);
|
FreeNode(right);
|
||||||
expp->nd_right = 0;
|
expp->nd_right = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -753,19 +766,19 @@ chk_uoper(expp)
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
if (tpr->tp_fund & T_INTORCARD) {
|
if (tpr->tp_fund & T_INTORCARD) {
|
||||||
if (expp->nd_right->nd_class == Value) {
|
if (right->nd_class == Value) {
|
||||||
cstunary(expp);
|
cstunary(expp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (tpr->tp_fund == T_REAL) {
|
else if (tpr->tp_fund == T_REAL) {
|
||||||
if (expp->nd_right->nd_class == Value) {
|
if (right->nd_class == Value) {
|
||||||
expp->nd_token = expp->nd_right->nd_token;
|
expp->nd_token = right->nd_token;
|
||||||
if (*(expp->nd_REL) == '-') {
|
if (*(expp->nd_REL) == '-') {
|
||||||
expp->nd_REL++;
|
expp->nd_REL++;
|
||||||
}
|
}
|
||||||
else expp->nd_REL--;
|
else expp->nd_REL--;
|
||||||
FreeNode(expp->nd_right);
|
FreeNode(right);
|
||||||
expp->nd_right = 0;
|
expp->nd_right = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -775,7 +788,7 @@ chk_uoper(expp)
|
||||||
case NOT:
|
case NOT:
|
||||||
case '~':
|
case '~':
|
||||||
if (tpr == bool_type) {
|
if (tpr == bool_type) {
|
||||||
if (expp->nd_right->nd_class == Value) {
|
if (right->nd_class == Value) {
|
||||||
cstunary(expp);
|
cstunary(expp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -794,19 +807,27 @@ struct node *
|
||||||
getvariable(arg)
|
getvariable(arg)
|
||||||
register struct node *arg;
|
register struct node *arg;
|
||||||
{
|
{
|
||||||
|
struct def *df;
|
||||||
|
register struct node *left;
|
||||||
|
|
||||||
arg = arg->nd_right;
|
arg = arg->nd_right;
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
node_error(arg, "too few parameters supplied");
|
node_error(arg, "too few parameters supplied");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! chk_designator(arg->nd_left, DESIGNATOR)) return 0;
|
left = arg->nd_left;
|
||||||
if (arg->nd_left->nd_class == Oper || arg->nd_left->nd_class == Uoper) {
|
|
||||||
|
if (! chk_designator(left, DESIGNATOR)) return 0;
|
||||||
|
if (left->nd_class == Oper || left->nd_class == Uoper) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg->nd_left->nd_class != Def ||
|
df = 0;
|
||||||
!(arg->nd_left->nd_def->df_kind & (D_VARIABLE|D_FIELD))) {
|
if (left->nd_class == Link) df = left->nd_right->nd_def;
|
||||||
|
else if (left->nd_class == Def) df = left->nd_def;
|
||||||
|
|
||||||
|
if (!df || !(df->df_kind & (D_VARIABLE|D_FIELD))) {
|
||||||
node_error(arg, "variable expected");
|
node_error(arg, "variable expected");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -947,7 +968,10 @@ node_error(arg, "EXCL and INCL expect a SET parameter");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(arg = getarg(arg, T_DISCRETE))) return 0;
|
if (!(arg = getarg(arg, T_DISCRETE))) return 0;
|
||||||
if (!TstCompat(tp->next, arg->nd_left->nd_type)) {
|
if (!TstAssCompat(tp->next, arg->nd_left->nd_type)) {
|
||||||
|
/* What type of compatibility do we want here?
|
||||||
|
apparently assignment compatibility! ??? ???
|
||||||
|
*/
|
||||||
node_error(arg, "unexpected type");
|
node_error(arg, "unexpected type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ ProcedureDeclaration
|
||||||
';' 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);
|
||||||
df->prc_scope = CurrentScope;
|
df->prc_vis = CurrVis;
|
||||||
close_scope(SC_CHKFORW|SC_REVERSE);
|
close_scope(SC_CHKFORW|SC_REVERSE);
|
||||||
proclevel--;
|
proclevel--;
|
||||||
currentdef = savecurr;
|
currentdef = savecurr;
|
||||||
|
@ -182,14 +182,9 @@ TypeDeclaration
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ if (df->df_type) free_type(df->df_type);
|
{ if (df->df_type) free_type(df->df_type);
|
||||||
df->df_type = tp;
|
df->df_type = tp;
|
||||||
if ((df->df_flags&D_EXPORTED) &&
|
|
||||||
tp->tp_fund == T_ENUMERATION) {
|
|
||||||
exprt_literals(tp->enm_enums,
|
|
||||||
enclosing(CurrentScope));
|
|
||||||
}
|
|
||||||
if (df->df_kind == D_HTYPE &&
|
if (df->df_kind == D_HTYPE &&
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -493,7 +488,7 @@ PointerType(struct type **ptp;)
|
||||||
else tp = df->df_type;
|
else tp = df->df_type;
|
||||||
}
|
}
|
||||||
| %if ( nd = new_node(), nd->nd_token = dot,
|
| %if ( nd = new_node(), nd->nd_token = dot,
|
||||||
df = lookfor(nd, CurrentScope, 0), free_node(nd),
|
df = lookfor(nd, CurrVis, 0), free_node(nd),
|
||||||
df->df_kind == D_MODULE)
|
df->df_kind == D_MODULE)
|
||||||
type(&tp)
|
type(&tp)
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
struct module {
|
struct module {
|
||||||
arith mo_priority; /* priority of a module */
|
arith mo_priority; /* priority of a module */
|
||||||
struct scope *mo_scope; /* scope of this module */
|
struct scopelist *mo_vis;/* scope of this module */
|
||||||
struct node *mo_body; /* body of this module */
|
struct node *mo_body; /* body of this module */
|
||||||
int mo_number; /* number of this module */
|
int mo_number; /* number of this module */
|
||||||
#define mod_priority df_value.df_module.mo_priority
|
#define mod_priority df_value.df_module.mo_priority
|
||||||
#define mod_scope df_value.df_module.mo_scope
|
#define mod_vis df_value.df_module.mo_vis
|
||||||
#define mod_body df_value.df_module.mo_body
|
#define mod_body df_value.df_module.mo_body
|
||||||
#define mod_number df_value.df_module.mo_number
|
#define mod_number df_value.df_module.mo_number
|
||||||
};
|
};
|
||||||
|
@ -51,11 +51,11 @@ struct field {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dfproc {
|
struct dfproc {
|
||||||
struct scope *pr_scope; /* scope of procedure */
|
struct scopelist *pr_vis; /* scope of procedure */
|
||||||
short pr_level; /* depth level of this procedure */
|
short pr_level; /* depth level of this procedure */
|
||||||
arith pr_nbpar; /* number of bytes parameters */
|
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_vis df_value.df_proc.pr_vis
|
||||||
#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
|
||||||
|
@ -67,11 +67,12 @@ struct import {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dforward {
|
struct dforward {
|
||||||
struct scope *fo_scope;
|
struct scopelist *fo_vis;
|
||||||
struct node *fo_node;
|
struct node *fo_node;
|
||||||
char *fo_name;
|
char *fo_name;
|
||||||
#define for_node df_value.df_forward.fo_node
|
#define for_node df_value.df_forward.fo_node
|
||||||
#define for_scope df_value.df_forward.fo_scope
|
#define for_vis df_value.df_forward.fo_vis
|
||||||
|
#define for_scopes df_value.df_forward.fo_scopes
|
||||||
#define for_name df_value.df_forward.fo_name
|
#define for_name df_value.df_forward.fo_name
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,10 @@ MkDef(id, scope, kind)
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
||||||
df = new_def();
|
df = new_def();
|
||||||
df->df_flags = 0;
|
clear((char *) df, sizeof (*df));
|
||||||
df->df_idf = id;
|
df->df_idf = id;
|
||||||
df->df_scope = scope;
|
df->df_scope = scope;
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
df->df_type = 0;
|
|
||||||
df->next = id->id_def;
|
df->next = id->id_def;
|
||||||
id->id_def = df;
|
id->id_def = df;
|
||||||
|
|
||||||
|
@ -66,8 +65,7 @@ define(id, scope, kind)
|
||||||
if ( /* Already in this scope */
|
if ( /* Already in this scope */
|
||||||
df
|
df
|
||||||
|| /* A closed scope, and id defined in the pervasive scope */
|
|| /* A closed scope, and id defined in the pervasive scope */
|
||||||
( CurrentScope == scope
|
(
|
||||||
&&
|
|
||||||
scopeclosed(scope)
|
scopeclosed(scope)
|
||||||
&&
|
&&
|
||||||
(df = lookup(id, PervasiveScope)))
|
(df = lookup(id, PervasiveScope)))
|
||||||
|
@ -79,31 +77,40 @@ define(id, scope, kind)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_FORWMODULE:
|
case D_FORWMODULE:
|
||||||
if (kind == D_FORWMODULE) {
|
if (kind == D_FORWMODULE) {
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == D_MODULE) {
|
if (kind == D_MODULE) {
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
df->mod_scope = df->for_scope;
|
df->mod_vis = df->for_vis;
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_FORWARD:
|
case D_FORWARD:
|
||||||
if (kind != D_FORWARD) {
|
if (kind != D_FORWARD) {
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
}
|
}
|
||||||
/* Fall Through */
|
|
||||||
|
df->df_kind = kind;
|
||||||
|
return df;
|
||||||
|
|
||||||
case D_ERROR:
|
case D_ERROR:
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind != D_ERROR) {
|
if (kind != D_ERROR) {
|
||||||
error("identifier \"%s\" already declared", id->id_text);
|
error("identifier \"%s\" already declared", id->id_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MkDef(id, scope, kind);
|
return MkDef(id, scope, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +136,6 @@ lookup(id, scope)
|
||||||
retval = df->imp_def;
|
retval = df->imp_def;
|
||||||
assert(retval != 0);
|
assert(retval != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (df1) {
|
if (df1) {
|
||||||
df1->next = df->next;
|
df1->next = df->next;
|
||||||
df->next = id->id_def;
|
df->next = id->id_def;
|
||||||
|
@ -143,8 +149,38 @@ lookup(id, scope)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Export(ids, qualified)
|
DoImport(df, scope)
|
||||||
|
struct def *df;
|
||||||
|
struct scope *scope;
|
||||||
|
{
|
||||||
|
register struct def *df1;
|
||||||
|
|
||||||
|
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
||||||
|
/* Also import all enumeration literals
|
||||||
|
*/
|
||||||
|
df1 = df->df_type->enm_enums;
|
||||||
|
while (df1) {
|
||||||
|
define(df1->df_idf, scope, D_IMPORT)->imp_def = df1;
|
||||||
|
df1 = df1->enm_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (df->df_kind == D_MODULE) {
|
||||||
|
/* Also import all definitions that are exported from this
|
||||||
|
module
|
||||||
|
*/
|
||||||
|
df1 = df->mod_vis->sc_scope->sc_def;
|
||||||
|
while (df1) {
|
||||||
|
if (df1->df_flags & D_EXPORTED) {
|
||||||
|
define(df1->df_idf, scope, D_IMPORT)->imp_def = df1;
|
||||||
|
}
|
||||||
|
df1 = df1->df_nextinscope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Export(ids, qualified, moddef)
|
||||||
register struct node *ids;
|
register struct node *ids;
|
||||||
|
struct def *moddef;
|
||||||
{
|
{
|
||||||
/* From the current scope, the list of identifiers "ids" is
|
/* From the current scope, the list of identifiers "ids" is
|
||||||
exported. Note this fact. If the export is not qualified, make
|
exported. Note this fact. If the export is not qualified, make
|
||||||
|
@ -152,47 +188,71 @@ Export(ids, qualified)
|
||||||
in this scope as "imported".
|
in this scope as "imported".
|
||||||
*/
|
*/
|
||||||
register struct def *df, *df1;
|
register struct def *df, *df1;
|
||||||
struct node *nd = ids;
|
register struct def *impmod;
|
||||||
|
|
||||||
while (ids) {
|
for (;ids; ids = ids->next) {
|
||||||
df = lookup(ids->nd_IDF, CurrentScope);
|
df = lookup(ids->nd_IDF, CurrentScope);
|
||||||
if (df && (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
|
|
||||||
|
if (!df) {
|
||||||
|
/* undefined item in export list
|
||||||
|
*/
|
||||||
|
node_error(ids, "identifier \"%s\" not defined", ids->nd_IDF->id_text);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
else if (!df) {
|
|
||||||
df = define(ids->nd_IDF, CurrentScope, D_FORWARD);
|
|
||||||
df->for_node = MkNode(Name,NULLNODE,NULLNODE,
|
|
||||||
&(ids->nd_token));
|
|
||||||
}
|
|
||||||
if (qualified) {
|
if (qualified) {
|
||||||
df->df_flags |= D_QEXPORTED;
|
df->df_flags |= D_QEXPORTED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* Export, but not qualified.
|
||||||
|
Find all imports of the module in which this export
|
||||||
|
occurs, and export the current definition to it
|
||||||
|
*/
|
||||||
|
impmod = moddef->df_idf->id_def;
|
||||||
|
while (impmod) {
|
||||||
|
if (impmod->df_kind == D_IMPORT &&
|
||||||
|
impmod->imp_def == moddef) {
|
||||||
|
DoImport(df, impmod->df_scope);
|
||||||
|
}
|
||||||
|
impmod = impmod->next;
|
||||||
|
}
|
||||||
|
|
||||||
df->df_flags |= D_EXPORTED;
|
df->df_flags |= D_EXPORTED;
|
||||||
df1 = lookup(ids->nd_IDF, enclosing(CurrentScope));
|
df1 = lookup(ids->nd_IDF, enclosing(CurrVis)->sc_scope);
|
||||||
if (! df1 || !(df1->df_kind & (D_PROCHEAD|D_HIDDEN))) {
|
if (df1 && df1->df_kind == D_PROCHEAD) {
|
||||||
df1 = define(ids->nd_IDF,
|
if (df->df_kind == D_PROCEDURE) {
|
||||||
enclosing(CurrentScope),
|
df1->df_kind = D_IMPORT;
|
||||||
|
df1->imp_def = df;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (df1 && df1->df_kind == D_HIDDEN) {
|
||||||
|
if (df->df_kind == D_TYPE) {
|
||||||
|
if (df->df_type->tp_fund != T_POINTER) {
|
||||||
|
error("Opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
|
}
|
||||||
|
df->df_kind = D_HTYPE;
|
||||||
|
df1->df_kind = D_IMPORT;
|
||||||
|
df1->imp_def = df;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
df1 = define(ids->nd_IDF,
|
||||||
|
enclosing(CurrVis)->sc_scope,
|
||||||
D_IMPORT);
|
D_IMPORT);
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* A hidden type or a procedure of which only
|
|
||||||
the head is seen. Apparently, they are
|
|
||||||
exported from a local module!
|
|
||||||
*/
|
|
||||||
df->df_kind = df1->df_kind;
|
|
||||||
df->df_value.df_forward = df1->df_value.df_forward;
|
|
||||||
df1->df_kind = D_IMPORT;
|
|
||||||
}
|
|
||||||
df1->imp_def = df;
|
df1->imp_def = df;
|
||||||
|
DoImport(df, enclosing(CurrVis)->sc_scope);
|
||||||
}
|
}
|
||||||
ids = ids->next;
|
|
||||||
}
|
}
|
||||||
FreeNode(nd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scope *
|
static struct scopelist *
|
||||||
ForwModule(df, idn)
|
ForwModule(df, idn)
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct node *idn;
|
struct node *idn;
|
||||||
|
@ -200,22 +260,22 @@ ForwModule(df, idn)
|
||||||
/* An import is done from a not yet defined module "idn".
|
/* An import is done from a not yet defined module "idn".
|
||||||
Create a declaration and a scope for this module.
|
Create a declaration and a scope for this module.
|
||||||
*/
|
*/
|
||||||
struct scope *scope;
|
struct scopelist *vis;
|
||||||
|
|
||||||
df->df_scope = enclosing(CurrentScope);
|
df->df_scope = enclosing(CurrVis)->sc_scope;
|
||||||
df->df_kind = D_FORWMODULE;
|
df->df_kind = D_FORWMODULE;
|
||||||
open_scope(CLOSEDSCOPE);
|
open_scope(CLOSEDSCOPE);
|
||||||
scope = CurrentScope; /* The new scope, but watch out, it's "next"
|
vis = CurrVis; /* The new scope, but watch out, it's "sc_encl"
|
||||||
field is not set right. It must indicate the
|
field is not set right. It must indicate the
|
||||||
enclosing scope, but this must be done AFTER
|
enclosing scope, but this must be done AFTER
|
||||||
closing this one
|
closing this one
|
||||||
*/
|
*/
|
||||||
df->for_scope = scope;
|
df->for_vis = vis;
|
||||||
df->for_node = MkNode(Name, NULLNODE, NULLNODE, &(idn->nd_token));
|
df->for_node = MkNode(Name, NULLNODE, NULLNODE, &(idn->nd_token));
|
||||||
close_scope(0);
|
close_scope(0);
|
||||||
scope->next = df->df_scope;
|
vis->sc_encl = enclosing(CurrVis);
|
||||||
/* Here ! */
|
/* Here ! */
|
||||||
return scope;
|
return vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct def *
|
static struct def *
|
||||||
|
@ -253,8 +313,7 @@ Import(ids, idn, local)
|
||||||
identifiers defined in this module.
|
identifiers defined in this module.
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct scope *scope = enclosing(CurrentScope);
|
struct scopelist *vis = enclosing(CurrVis);
|
||||||
int kind = D_IMPORT;
|
|
||||||
int forwflag = 0;
|
int forwflag = 0;
|
||||||
#define FROM_MODULE 0
|
#define FROM_MODULE 0
|
||||||
#define FROM_ENCLOSING 1
|
#define FROM_ENCLOSING 1
|
||||||
|
@ -264,7 +323,7 @@ Import(ids, idn, local)
|
||||||
if (idn) {
|
if (idn) {
|
||||||
imp_kind = FROM_MODULE;
|
imp_kind = FROM_MODULE;
|
||||||
if (local) {
|
if (local) {
|
||||||
df = lookfor(idn, scope, 0);
|
df = lookfor(idn, vis, 0);
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_ERROR:
|
case D_ERROR:
|
||||||
/* The module from which the import was done
|
/* The module from which the import was done
|
||||||
|
@ -272,23 +331,22 @@ Import(ids, idn, local)
|
||||||
accept this, but for the time being I will.
|
accept this, but for the time being I will.
|
||||||
???
|
???
|
||||||
*/
|
*/
|
||||||
scope = ForwModule(df, idn);
|
vis = ForwModule(df, idn);
|
||||||
forwflag = 1;
|
forwflag = 1;
|
||||||
break;
|
break;
|
||||||
case D_FORWMODULE:
|
case D_FORWMODULE:
|
||||||
scope = df->for_scope;
|
vis = df->for_vis;
|
||||||
break;
|
break;
|
||||||
case D_MODULE:
|
case D_MODULE:
|
||||||
scope = df->mod_scope;
|
vis = df->mod_vis;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
kind = D_ERROR;
|
|
||||||
node_error(idn, "identifier \"%s\" does not represent a module",
|
node_error(idn, "identifier \"%s\" does not represent a module",
|
||||||
idn->nd_IDF->id_text);
|
idn->nd_IDF->id_text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else scope = GetDefinitionModule(idn->nd_IDF)->mod_scope;
|
else vis = GetDefinitionModule(idn->nd_IDF)->mod_vis;
|
||||||
|
|
||||||
FreeNode(idn);
|
FreeNode(idn);
|
||||||
}
|
}
|
||||||
|
@ -297,9 +355,9 @@ idn->nd_IDF->id_text);
|
||||||
while (ids) {
|
while (ids) {
|
||||||
if (imp_kind == FROM_MODULE) {
|
if (imp_kind == FROM_MODULE) {
|
||||||
if (forwflag) {
|
if (forwflag) {
|
||||||
df = ForwDef(ids, scope);
|
df = ForwDef(ids, vis->sc_scope);
|
||||||
}
|
}
|
||||||
else if (!(df = lookup(ids->nd_IDF, scope))) {
|
else if (!(df = lookup(ids->nd_IDF, vis->sc_scope))) {
|
||||||
node_error(ids, "identifier \"%s\" not declared in qualifying module",
|
node_error(ids, "identifier \"%s\" not declared in qualifying module",
|
||||||
ids->nd_IDF->id_text);
|
ids->nd_IDF->id_text);
|
||||||
df = ill_df;
|
df = ill_df;
|
||||||
|
@ -310,40 +368,20 @@ ids->nd_IDF->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (local) df = ForwDef(ids, scope);
|
if (local) df = ForwDef(ids, vis->sc_scope);
|
||||||
else df = GetDefinitionModule(ids->nd_IDF);
|
else df = GetDefinitionModule(ids->nd_IDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text,
|
DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text,
|
||||||
df->df_kind));
|
df->df_kind));
|
||||||
define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
|
define(df->df_idf, CurrentScope, D_IMPORT)->imp_def = df;
|
||||||
if (df->df_kind == D_TYPE &&
|
DoImport(df, CurrentScope);
|
||||||
df->df_type->tp_fund == T_ENUMERATION) {
|
|
||||||
/* Also import all enumeration literals
|
|
||||||
*/
|
|
||||||
exprt_literals(df->df_type->enm_enums, CurrentScope);
|
|
||||||
}
|
|
||||||
ids = ids->next;
|
ids = ids->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeNode(idn);
|
FreeNode(idn);
|
||||||
}
|
}
|
||||||
|
|
||||||
exprt_literals(df, toscope)
|
|
||||||
register struct def *df;
|
|
||||||
struct scope *toscope;
|
|
||||||
{
|
|
||||||
/* A list of enumeration literals is exported. This is implemented
|
|
||||||
as an import from the scope "toscope".
|
|
||||||
*/
|
|
||||||
DO_DEBUG(3, debug("enumeration import:"));
|
|
||||||
while (df) {
|
|
||||||
DO_DEBUG(3, debug(df->df_idf->id_text));
|
|
||||||
define(df->df_idf, toscope, D_IMPORT)->imp_def = df;
|
|
||||||
df = df->enm_next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RemImports(pdf)
|
RemImports(pdf)
|
||||||
struct def **pdf;
|
struct def **pdf;
|
||||||
{
|
{
|
||||||
|
@ -417,18 +455,18 @@ DeclProc(type)
|
||||||
df->df_kind = D_PROCEDURE;
|
df->df_kind = D_PROCEDURE;
|
||||||
open_scope(OPENSCOPE);
|
open_scope(OPENSCOPE);
|
||||||
CurrentScope->sc_name = df->for_name;
|
CurrentScope->sc_name = df->for_name;
|
||||||
df->prc_scope = CurrentScope;
|
df->prc_vis = CurrVis;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = define(dot.TOK_IDF, CurrentScope, type);
|
df = define(dot.TOK_IDF, CurrentScope, type);
|
||||||
if (CurrentScope != Defined->mod_scope) {
|
if (CurrVis != Defined->mod_vis) {
|
||||||
sprint(buf, "_%d_%s", ++nmcount,
|
sprint(buf, "_%d_%s", ++nmcount,
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
else (sprint(buf, "%s_%s",df->df_scope->sc_name,
|
else (sprint(buf, "%s_%s",CurrentScope->sc_name,
|
||||||
df->df_idf->id_text));
|
df->df_idf->id_text));
|
||||||
open_scope(OPENSCOPE);
|
open_scope(OPENSCOPE);
|
||||||
df->prc_scope = CurrentScope;
|
df->prc_vis = CurrVis;
|
||||||
CurrentScope->sc_name = Malloc((unsigned)(strlen(buf)+1));
|
CurrentScope->sc_name = Malloc((unsigned)(strlen(buf)+1));
|
||||||
strcpy(CurrentScope->sc_name, buf);
|
strcpy(CurrentScope->sc_name, buf);
|
||||||
C_inp(buf);
|
C_inp(buf);
|
||||||
|
|
|
@ -103,17 +103,17 @@ EnterVarList(IdList, type, local)
|
||||||
procedure
|
procedure
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
register struct scope *scope;
|
register struct scopelist *sc;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
extern char *sprint(), *Malloc(), *strcpy();
|
extern char *sprint(), *Malloc(), *strcpy();
|
||||||
|
|
||||||
scope = CurrentScope;
|
sc = CurrVis;
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
/* Find the closest enclosing open scope. This
|
/* Find the closest enclosing open scope. This
|
||||||
is the procedure that we are dealing with
|
is the procedure that we are dealing with
|
||||||
*/
|
*/
|
||||||
while (scope->sc_scopeclosed) scope = scope->next;
|
while (sc->sc_scope->sc_scopeclosed) sc = enclosing(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (IdList) {
|
while (IdList) {
|
||||||
|
@ -133,23 +133,25 @@ node_error(IdList->nd_left,"Illegal type for address");
|
||||||
as the variable list exists only local to a
|
as the variable list exists only local to a
|
||||||
procedure
|
procedure
|
||||||
*/
|
*/
|
||||||
scope->sc_off = -align(type->tp_size - scope->sc_off,
|
sc->sc_scope->sc_off =
|
||||||
|
-align(type->tp_size - sc->sc_scope->sc_off,
|
||||||
type->tp_align);
|
type->tp_align);
|
||||||
df->var_off = scope->sc_off;
|
df->var_off = sc->sc_scope->sc_off;
|
||||||
}
|
}
|
||||||
else if (!DefinitionModule &&
|
else if (!DefinitionModule &&
|
||||||
CurrentScope != Defined->mod_scope) {
|
CurrVis != Defined->mod_vis) {
|
||||||
/* variable list belongs to an internal global
|
/* variable list belongs to an internal global
|
||||||
module. Align offset and add size
|
module. Align offset and add size
|
||||||
*/
|
*/
|
||||||
scope->sc_off = align(scope->sc_off, type->tp_align);
|
sc->sc_scope->sc_off =
|
||||||
df->var_off = scope->sc_off;
|
align(sc->sc_scope->sc_off, type->tp_align);
|
||||||
scope->sc_off += type->tp_size;
|
df->var_off = sc->sc_scope->sc_off;
|
||||||
|
sc->sc_scope->sc_off += type->tp_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Global name, possibly external
|
/* Global name, possibly external
|
||||||
*/
|
*/
|
||||||
sprint(buf,"%s_%s", df->df_scope->sc_name,
|
sprint(buf,"%s_%s", sc->sc_scope->sc_name,
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
df->var_name = Malloc((unsigned)(strlen(buf)+1));
|
df->var_name = Malloc((unsigned)(strlen(buf)+1));
|
||||||
strcpy(df->var_name, buf);
|
strcpy(df->var_name, buf);
|
||||||
|
@ -165,26 +167,26 @@ node_error(IdList->nd_left,"Illegal type for address");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
lookfor(id, scope, give_error)
|
lookfor(id, vis, give_error)
|
||||||
struct node *id;
|
struct node *id;
|
||||||
struct scope *scope;
|
struct scopelist *vis;
|
||||||
{
|
{
|
||||||
/* Look for an identifier in the visibility range started by
|
/* Look for an identifier in the visibility range started by
|
||||||
"scope".
|
"vis".
|
||||||
If it is not defined, maybe 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 scopelist *sc = vis;
|
||||||
struct def *MkDef();
|
struct def *MkDef();
|
||||||
|
|
||||||
while (sc) {
|
while (sc) {
|
||||||
df = lookup(id->nd_IDF, sc);
|
df = lookup(id->nd_IDF, sc->sc_scope);
|
||||||
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 MkDef(id->nd_IDF, scope, D_ERROR);
|
return MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ static char *RcsId = "$Header$";
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "scope.h"
|
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
@ -170,6 +169,7 @@ factor(struct node **p;)
|
||||||
{
|
{
|
||||||
struct def *df;
|
struct def *df;
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
|
register struct type *tp;
|
||||||
} :
|
} :
|
||||||
qualident(0, &df, (char *) 0, p)
|
qualident(0, &df, (char *) 0, p)
|
||||||
[
|
[
|
||||||
|
@ -189,18 +189,20 @@ factor(struct node **p;)
|
||||||
| %default
|
| %default
|
||||||
number(p)
|
number(p)
|
||||||
|
|
|
|
||||||
STRING {
|
STRING {
|
||||||
*p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
*p = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
||||||
if (dot.TOK_SLE == 1) {
|
if (dot.TOK_SLE == 1) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = *(dot.TOK_STR) & 0377;
|
tp = charc_type;
|
||||||
(*p)->nd_type = charc_type;
|
i = *(dot.TOK_STR) & 0377;
|
||||||
free(dot.TOK_STR);
|
free(dot.TOK_STR);
|
||||||
dot.TOK_INT = i;
|
free((char *) dot.tk_data.tk_str);
|
||||||
}
|
dot.TOK_INT = i;
|
||||||
else (*p)->nd_type = string_type;
|
}
|
||||||
}
|
else tp = standard_type(T_STRING, 1, dot.TOK_SLE);
|
||||||
|
(*p)->nd_type = tp;
|
||||||
|
}
|
||||||
|
|
|
|
||||||
'(' expression(p) ')'
|
'(' expression(p) ')'
|
||||||
|
|
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ ModuleDeclaration
|
||||||
static int modulecount = 0;
|
static int modulecount = 0;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
|
struct node *exportlist = 0;
|
||||||
|
int qualified;
|
||||||
extern char *sprint(), *Malloc(), *strcpy();
|
extern char *sprint(), *Malloc(), *strcpy();
|
||||||
} :
|
} :
|
||||||
MODULE IDENT {
|
MODULE IDENT {
|
||||||
|
@ -59,14 +61,14 @@ ModuleDeclaration
|
||||||
df = define(id, CurrentScope, D_MODULE);
|
df = define(id, CurrentScope, D_MODULE);
|
||||||
currentdef = df;
|
currentdef = df;
|
||||||
|
|
||||||
if (!df->mod_scope) {
|
if (!df->mod_vis) {
|
||||||
open_scope(CLOSEDSCOPE);
|
open_scope(CLOSEDSCOPE);
|
||||||
df->mod_scope = CurrentScope;
|
df->mod_vis = CurrVis;
|
||||||
}
|
}
|
||||||
else CurrentScope = df->mod_scope;
|
else CurrVis = df->mod_vis;
|
||||||
|
|
||||||
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_vis->sc_scope;
|
||||||
df->mod_number = ++modulecount;
|
df->mod_number = ++modulecount;
|
||||||
sprint(buf, "__%d%s", df->mod_number, id->id_text);
|
sprint(buf, "__%d%s", df->mod_number, id->id_text);
|
||||||
CurrentScope->sc_name =
|
CurrentScope->sc_name =
|
||||||
|
@ -78,9 +80,13 @@ ModuleDeclaration
|
||||||
priority(&(df->mod_priority))?
|
priority(&(df->mod_priority))?
|
||||||
';'
|
';'
|
||||||
import(1)*
|
import(1)*
|
||||||
export(0)?
|
export(&qualified, &exportlist, 0)?
|
||||||
block(&nd)
|
block(&nd)
|
||||||
IDENT { InitProc(nd, df);
|
IDENT { InitProc(nd, df);
|
||||||
|
if (exportlist) {
|
||||||
|
Export(exportlist, qualified, df);
|
||||||
|
FreeNode(exportlist);
|
||||||
|
}
|
||||||
close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
|
close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
|
||||||
match_id(id, dot.TOK_IDF);
|
match_id(id, dot.TOK_IDF);
|
||||||
currentdef = savecurr;
|
currentdef = savecurr;
|
||||||
|
@ -100,24 +106,21 @@ priority(arith *pprio;)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
export(int def;)
|
export(int *QUALflag; struct node **ExportList; int def;)
|
||||||
{
|
{
|
||||||
struct node *ExportList;
|
|
||||||
int QUALflag = 0;
|
|
||||||
} :
|
} :
|
||||||
EXPORT
|
EXPORT
|
||||||
[
|
[
|
||||||
QUALIFIED
|
QUALIFIED
|
||||||
{ QUALflag = 1; }
|
{ *QUALflag = 1; }
|
||||||
]?
|
|
|
||||||
IdentList(&ExportList) ';'
|
{ *QUALflag = 0; }
|
||||||
|
]
|
||||||
|
IdentList(ExportList) ';'
|
||||||
{
|
{
|
||||||
if (!def) {
|
if (def) {
|
||||||
Export(ExportList, QUALflag);
|
node_warning(*ExportList, "export list in definition module ignored");
|
||||||
}
|
FreeNode(*ExportList);
|
||||||
else {
|
|
||||||
node_warning(ExportList, "export list in definition module ignored");
|
|
||||||
FreeNode(ExportList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -146,6 +149,8 @@ DefinitionModule
|
||||||
{
|
{
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
struct node *exportlist;
|
||||||
|
int dummy;
|
||||||
} :
|
} :
|
||||||
DEFINITION
|
DEFINITION
|
||||||
MODULE IDENT {
|
MODULE IDENT {
|
||||||
|
@ -153,18 +158,18 @@ DefinitionModule
|
||||||
df = define(id, GlobalScope, D_MODULE);
|
df = define(id, GlobalScope, D_MODULE);
|
||||||
if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
|
if (!SYSTEMModule) open_scope(CLOSEDSCOPE);
|
||||||
if (!Defined) Defined = df;
|
if (!Defined) Defined = df;
|
||||||
df->mod_scope = CurrentScope;
|
df->mod_vis = CurrVis;
|
||||||
df->mod_number = 0;
|
df->mod_number = 0;
|
||||||
CurrentScope->sc_name = id->id_text;
|
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_vis->sc_scope;
|
||||||
DefinitionModule++;
|
DefinitionModule++;
|
||||||
DO_DEBUG(1, debug("Definition module \"%s\" %d",
|
DO_DEBUG(1, debug("Definition module \"%s\" %d",
|
||||||
id->id_text, DefinitionModule));
|
id->id_text, DefinitionModule));
|
||||||
}
|
}
|
||||||
';'
|
';'
|
||||||
import(0)*
|
import(0)*
|
||||||
export(1)?
|
export(&dummy, &exportlist, 1)?
|
||||||
/* New Modula-2 does not have export lists in definition modules.
|
/* New Modula-2 does not have export lists in definition modules.
|
||||||
For the time being, we ignore export lists here, and a
|
For the time being, we ignore export lists here, and a
|
||||||
warning is issued.
|
warning is issued.
|
||||||
|
@ -237,14 +242,15 @@ ProgramModule(int state;)
|
||||||
DEFofIMPL = 1;
|
DEFofIMPL = 1;
|
||||||
df = GetDefinitionModule(id);
|
df = GetDefinitionModule(id);
|
||||||
currentdef = df;
|
currentdef = df;
|
||||||
CurrentScope = df->mod_scope;
|
CurrVis = df->mod_vis;
|
||||||
|
CurrentScope = CurrVis->sc_scope;
|
||||||
DEFofIMPL = 0;
|
DEFofIMPL = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = define(id, CurrentScope, D_MODULE);
|
df = define(id, CurrentScope, D_MODULE);
|
||||||
Defined = df;
|
Defined = df;
|
||||||
open_scope(CLOSEDSCOPE);
|
open_scope(CLOSEDSCOPE);
|
||||||
df->mod_scope = CurrentScope;
|
df->mod_vis = CurrVis;
|
||||||
df->mod_number = 0;
|
df->mod_number = 0;
|
||||||
CurrentScope->sc_name = id->id_text;
|
CurrentScope->sc_name = id->id_text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,21 @@ static char *RcsId = "$Header$";
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
struct scope *CurrentScope, *PervasiveScope, *GlobalScope;
|
struct scope *PervasiveScope, *GlobalScope;
|
||||||
|
struct scopelist *CurrVis;
|
||||||
static int scp_level;
|
static int scp_level;
|
||||||
|
static struct scopelist *PervVis;
|
||||||
|
|
||||||
/* STATICALLOCDEF "scope" */
|
/* STATICALLOCDEF "scope" */
|
||||||
|
|
||||||
|
/* STATICALLOCDEF "scopelist" */
|
||||||
|
|
||||||
open_scope(scopetype)
|
open_scope(scopetype)
|
||||||
{
|
{
|
||||||
/* Open a scope that is either open (automatic imports) or closed.
|
/* Open a scope that is either open (automatic imports) or closed.
|
||||||
*/
|
*/
|
||||||
register struct scope *sc = new_scope();
|
register struct scope *sc = new_scope();
|
||||||
|
register struct scopelist *ls = new_scopelist();
|
||||||
|
|
||||||
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
|
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
|
||||||
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
|
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
|
||||||
|
@ -33,26 +38,30 @@ open_scope(scopetype)
|
||||||
sc->sc_forw = 0;
|
sc->sc_forw = 0;
|
||||||
sc->sc_def = 0;
|
sc->sc_def = 0;
|
||||||
sc->sc_off = 0;
|
sc->sc_off = 0;
|
||||||
sc->next = 0;
|
if (scopetype == OPENSCOPE) {
|
||||||
DO_DEBUG(1, debug("Opening a %s scope",
|
ls->next = CurrVis;
|
||||||
scopetype == OPENSCOPE ? "open" : "closed"));
|
|
||||||
if (CurrentScope != PervasiveScope) {
|
|
||||||
sc->next = CurrentScope;
|
|
||||||
}
|
}
|
||||||
CurrentScope = sc;
|
else ls->next = PervVis;
|
||||||
|
ls->sc_scope = sc;
|
||||||
|
ls->sc_encl = CurrVis;
|
||||||
|
CurrVis = ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_scope()
|
init_scope()
|
||||||
{
|
{
|
||||||
register struct scope *sc = new_scope();
|
register struct scope *sc = new_scope();
|
||||||
|
register struct scopelist *ls = new_scopelist();
|
||||||
|
|
||||||
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->sc_level = scp_level++;
|
||||||
sc->next = 0;
|
|
||||||
PervasiveScope = sc;
|
PervasiveScope = sc;
|
||||||
CurrentScope = sc;
|
ls->next = 0;
|
||||||
|
ls->sc_encl = 0;
|
||||||
|
ls->sc_scope = PervasiveScope;
|
||||||
|
PervVis = ls;
|
||||||
|
CurrVis = ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct forwards {
|
struct forwards {
|
||||||
|
@ -127,15 +136,15 @@ node_error((*pdf)->for_node, "identifier \"%s\" has not been declared",
|
||||||
Maybe the definitions are in the
|
Maybe the definitions are in the
|
||||||
enclosing scope?
|
enclosing scope?
|
||||||
*/
|
*/
|
||||||
struct scope *sc;
|
struct scopelist *ls;
|
||||||
|
|
||||||
sc = enclosing(CurrentScope);
|
ls = nextvisible(CurrVis);
|
||||||
if ((*pdf)->df_kind == D_FORWMODULE) {
|
if ((*pdf)->df_kind == D_FORWMODULE) {
|
||||||
(*pdf)->for_scope->next = sc;
|
(*pdf)->for_vis->next = ls;
|
||||||
}
|
}
|
||||||
(*pdf)->df_nextinscope = sc->sc_def;
|
(*pdf)->df_nextinscope = ls->sc_scope->sc_def;
|
||||||
sc->sc_def = *pdf;
|
ls->sc_scope->sc_def = *pdf;
|
||||||
(*pdf)->df_scope = sc;
|
(*pdf)->df_scope = ls->sc_scope;
|
||||||
*pdf = df1;
|
*pdf = df1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +163,7 @@ rem_forwards(fo)
|
||||||
struct def *lookfor();
|
struct def *lookfor();
|
||||||
|
|
||||||
while (f = fo) {
|
while (f = fo) {
|
||||||
df = lookfor(&(f->fo_tok), CurrentScope, 1);
|
df = lookfor(&(f->fo_tok), CurrVis, 1);
|
||||||
if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) {
|
if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) {
|
||||||
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
|
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
|
@ -216,7 +225,7 @@ close_scope(flag)
|
||||||
if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def));
|
if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def));
|
||||||
if (flag & SC_REVERSE) Reverse(&(sc->sc_def));
|
if (flag & SC_REVERSE) Reverse(&(sc->sc_def));
|
||||||
}
|
}
|
||||||
CurrentScope = sc->next;
|
CurrVis = enclosing(CurrVis);
|
||||||
scp_level = CurrentScope->sc_level;
|
scp_level = CurrentScope->sc_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,20 @@ struct scope {
|
||||||
int sc_level; /* level of this scope */
|
int sc_level; /* level of this scope */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct scopelist {
|
||||||
|
struct scopelist *next;
|
||||||
|
struct scopelist *sc_encl;
|
||||||
|
struct scope *sc_scope;
|
||||||
|
};
|
||||||
|
|
||||||
extern struct scope
|
extern struct scope
|
||||||
*CurrentScope,
|
|
||||||
*PervasiveScope,
|
*PervasiveScope,
|
||||||
*GlobalScope;
|
*GlobalScope;
|
||||||
|
|
||||||
#define enclosing(x) ((x)->next)
|
extern struct scopelist
|
||||||
|
*CurrVis;
|
||||||
|
|
||||||
|
#define CurrentScope (CurrVis->sc_scope)
|
||||||
|
#define enclosing(x) ((x)->sc_encl)
|
||||||
#define scopeclosed(x) ((x)->sc_scopeclosed)
|
#define scopeclosed(x) ((x)->sc_scopeclosed)
|
||||||
#define nextvisible(x) (scopeclosed(x) ? PervasiveScope : enclosing(x))
|
#define nextvisible(x) ((x)->next) /* use with scopelists */
|
||||||
|
|
|
@ -5,6 +5,7 @@ static char *RcsId = "$Header$";
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
|
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
|
|
@ -97,7 +97,6 @@ extern struct type
|
||||||
*word_type,
|
*word_type,
|
||||||
*address_type,
|
*address_type,
|
||||||
*intorcard_type,
|
*intorcard_type,
|
||||||
*string_type,
|
|
||||||
*bitset_type,
|
*bitset_type,
|
||||||
*std_type,
|
*std_type,
|
||||||
*error_type; /* All from type.c */
|
*error_type; /* All from type.c */
|
||||||
|
@ -130,3 +129,5 @@ struct type
|
||||||
*subr_type(); /* All from type.c */
|
*subr_type(); /* All from type.c */
|
||||||
|
|
||||||
#define NULLTYPE ((struct type *) 0)
|
#define NULLTYPE ((struct type *) 0)
|
||||||
|
|
||||||
|
#define IsConformantArray(tpx) ((tpx)->tp_fund == T_ARRAY && (tpx)->next == 0)
|
||||||
|
|
|
@ -50,7 +50,6 @@ struct type
|
||||||
*word_type,
|
*word_type,
|
||||||
*address_type,
|
*address_type,
|
||||||
*intorcard_type,
|
*intorcard_type,
|
||||||
*string_type,
|
|
||||||
*bitset_type,
|
*bitset_type,
|
||||||
*std_type,
|
*std_type,
|
||||||
*error_type;
|
*error_type;
|
||||||
|
@ -152,8 +151,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;
|
||||||
|
|
||||||
/* character constant, different from char because of compatibility
|
/* character constant type, different from character type because
|
||||||
with ARRAY OF CHAR
|
of compatibility with character array's
|
||||||
*/
|
*/
|
||||||
charc_type = standard_type(T_CHAR, 1, (arith) 1);
|
charc_type = standard_type(T_CHAR, 1, (arith) 1);
|
||||||
charc_type->enm_ncst = 256;
|
charc_type->enm_ncst = 256;
|
||||||
|
@ -176,10 +175,6 @@ init_types()
|
||||||
real_type = standard_type(T_REAL, float_align, float_size);
|
real_type = standard_type(T_REAL, float_align, float_size);
|
||||||
longreal_type = standard_type(T_REAL, double_align, double_size);
|
longreal_type = standard_type(T_REAL, double_align, double_size);
|
||||||
|
|
||||||
/* string constant type
|
|
||||||
*/
|
|
||||||
string_type = standard_type(T_STRING, 1, (arith) -1);
|
|
||||||
|
|
||||||
/* SYSTEM types
|
/* SYSTEM types
|
||||||
*/
|
*/
|
||||||
word_type = standard_type(T_WORD, word_align, word_size);
|
word_type = standard_type(T_WORD, word_align, word_size);
|
||||||
|
|
|
@ -39,13 +39,9 @@ TstParEquiv(tp1, tp2)
|
||||||
TstTypeEquiv(tp1, tp2)
|
TstTypeEquiv(tp1, tp2)
|
||||||
||
|
||
|
||||||
(
|
(
|
||||||
tp1->tp_fund == T_ARRAY
|
IsConformantArray(tp1)
|
||||||
&&
|
&&
|
||||||
tp1->next == 0
|
IsConformantArray(tp2)
|
||||||
&&
|
|
||||||
tp2->tp_fund == T_ARRAY
|
|
||||||
&&
|
|
||||||
tp2->next == 0
|
|
||||||
&&
|
&&
|
||||||
TstTypeEquiv(tp1->arr_elem, tp2->arr_elem)
|
TstTypeEquiv(tp1->arr_elem, tp2->arr_elem)
|
||||||
);
|
);
|
||||||
|
@ -61,11 +57,15 @@ TstProcEquiv(tp1, tp2)
|
||||||
*/
|
*/
|
||||||
register struct paramlist *p1, *p2;
|
register struct paramlist *p1, *p2;
|
||||||
|
|
||||||
if (!TstTypeEquiv(tp1->next, tp2->next)) return 0;
|
/* First check if the result types are equivalent
|
||||||
|
*/
|
||||||
|
if (! TstTypeEquiv(tp1->next, tp2->next)) return 0;
|
||||||
|
|
||||||
p1 = tp1->prc_params;
|
p1 = tp1->prc_params;
|
||||||
p2 = tp2->prc_params;
|
p2 = tp2->prc_params;
|
||||||
|
|
||||||
|
/* Now check the parameters
|
||||||
|
*/
|
||||||
while (p1 && p2) {
|
while (p1 && p2) {
|
||||||
if (p1->par_var != p2->par_var ||
|
if (p1->par_var != p2->par_var ||
|
||||||
!TstParEquiv(p1->par_type, p2->par_type)) return 0;
|
!TstParEquiv(p1->par_type, p2->par_type)) return 0;
|
||||||
|
@ -123,10 +123,12 @@ TstCompat(tp1, tp2)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TstAssCompat(tp1, tp2)
|
int
|
||||||
|
TstAssCompat(tp1, tp2)
|
||||||
struct type *tp1, *tp2;
|
struct type *tp1, *tp2;
|
||||||
{
|
{
|
||||||
/* Test if two types are assignment compatible.
|
/* Test if two types are assignment compatible.
|
||||||
|
See Def 9.1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (TstCompat(tp1, tp2)) return 1;
|
if (TstCompat(tp1, tp2)) return 1;
|
||||||
|
@ -138,24 +140,39 @@ int TstAssCompat(tp1, tp2)
|
||||||
(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 == char_type && tp2 == charc_type) return 1;
|
||||||
if (tp1->tp_fund == T_ARRAY &&
|
|
||||||
(tp2 == charc_type || tp2 == string_type)) {
|
if (tp1->tp_fund == T_ARRAY) {
|
||||||
/* Unfortunately the length of the string is not
|
arith size;
|
||||||
available here, so this must be tested somewhere else (???)
|
|
||||||
*/
|
if (! tp1->next) return 0;
|
||||||
|
|
||||||
|
size = tp1->arr_ub - tp1->arr_lb + 1;
|
||||||
tp1 = tp1->arr_elem;
|
tp1 = tp1->arr_elem;
|
||||||
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
if (tp1->tp_fund == T_SUBRANGE) tp1 = tp1->next;
|
||||||
return tp1 == char_type;
|
return
|
||||||
|
tp1 == char_type
|
||||||
|
&&
|
||||||
|
(
|
||||||
|
tp2 == charc_type
|
||||||
|
||
|
||||||
|
(tp2->tp_fund == T_STRING && size >= tp2->tp_size)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TstParCompat(formaltype, actualtype, VARflag)
|
int
|
||||||
|
TstParCompat(formaltype, actualtype, VARflag)
|
||||||
struct type *formaltype, *actualtype;
|
struct type *formaltype, *actualtype;
|
||||||
{
|
{
|
||||||
/* Check type compatibility for a parameter in a procedure
|
/* Check type compatibility for a parameter in a procedure
|
||||||
call
|
call. Ordinary type compatibility is sufficient in any case.
|
||||||
|
Assignment compatibility may do if the parameter is
|
||||||
|
a value parameter.
|
||||||
|
Otherwise, a conformant array may do, or an ARRAY OF WORD
|
||||||
|
may do too.
|
||||||
|
Or: a WORD may do.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -163,8 +180,19 @@ int TstParCompat(formaltype, actualtype, VARflag)
|
||||||
||
|
||
|
||||||
( !VARflag && TstAssCompat(formaltype, actualtype))
|
( !VARflag && TstAssCompat(formaltype, actualtype))
|
||||||
||
|
||
|
||||||
( formaltype->tp_fund == T_ARRAY
|
( formaltype == word_type && actualtype->tp_size == word_size)
|
||||||
&& formaltype->next == 0
|
||
|
||||||
&& actualtype->tp_fund == T_ARRAY
|
( IsConformantArray(formaltype)
|
||||||
&& TstTypeEquiv(formaltype->arr_elem, actualtype->arr_elem));
|
&&
|
||||||
|
( formaltype->arr_elem == word_type
|
||||||
|
||
|
||||||
|
( actualtype->tp_fund == T_ARRAY
|
||||||
|
&& TstTypeEquiv(formaltype->arr_elem,actualtype->arr_elem)
|
||||||
|
)
|
||||||
|
||
|
||||||
|
( actualtype->tp_fund == T_STRING
|
||||||
|
&& TstTypeEquiv(formaltype->arr_elem, char_type)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,11 @@ WalkModule(module)
|
||||||
/* Walk through a module, and all its local definitions.
|
/* Walk through a module, and all its local definitions.
|
||||||
Also generate code for its body.
|
Also generate code for its body.
|
||||||
*/
|
*/
|
||||||
register struct def *df = module->mod_scope->sc_def;
|
register struct def *df = module->mod_vis->sc_scope->sc_def;
|
||||||
struct scope *scope;
|
struct scopelist *vis;
|
||||||
|
|
||||||
scope = CurrentScope;
|
vis = CurrVis;
|
||||||
CurrentScope = module->mod_scope;
|
CurrVis = module->mod_vis;
|
||||||
|
|
||||||
if (!prclev && module->mod_number) {
|
if (!prclev && module->mod_number) {
|
||||||
/* This module is a local module, but not within a
|
/* This module is a local module, but not within a
|
||||||
|
@ -46,13 +46,13 @@ WalkModule(module)
|
||||||
variables. This is done by generating a "bss",
|
variables. This is done by generating a "bss",
|
||||||
with label "_<modulenumber><modulename>".
|
with label "_<modulenumber><modulename>".
|
||||||
*/
|
*/
|
||||||
arith size = align(CurrentScope->sc_off, word_size);
|
arith size = align(CurrentScope->sc_off, word_align);
|
||||||
|
|
||||||
if (size == 0) size = word_size;
|
if (size == 0) size = word_size;
|
||||||
C_df_dnam(&(CurrentScope->sc_name[1]));
|
C_df_dnam(&(CurrentScope->sc_name[1]));
|
||||||
C_bss_cst(size, (arith) 0, 0);
|
C_bss_cst(size, (arith) 0, 0);
|
||||||
}
|
}
|
||||||
else if (CurrentScope == Defined->mod_scope) {
|
else if (CurrVis == Defined->mod_vis) {
|
||||||
/* This module is the module currently being compiled.
|
/* This module is the module currently being compiled.
|
||||||
Again, generate code to allocate storage for its
|
Again, generate code to allocate storage for its
|
||||||
variables, which all have an explicit name.
|
variables, which all have an explicit name.
|
||||||
|
@ -83,9 +83,9 @@ WalkModule(module)
|
||||||
WalkNode(module->mod_body, (label) 0);
|
WalkNode(module->mod_body, (label) 0);
|
||||||
C_df_ilb(return_label);
|
C_df_ilb(return_label);
|
||||||
C_ret((label) 0);
|
C_ret((label) 0);
|
||||||
C_end(align(-CurrentScope->sc_off, word_size));
|
C_end(align(-CurrentScope->sc_off, word_align));
|
||||||
|
|
||||||
CurrentScope = scope;
|
CurrVis = vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkProcedure(procedure)
|
WalkProcedure(procedure)
|
||||||
|
@ -94,11 +94,10 @@ WalkProcedure(procedure)
|
||||||
/* Walk through the definition of a procedure and all its
|
/* Walk through the definition of a procedure and all its
|
||||||
local definitions
|
local definitions
|
||||||
*/
|
*/
|
||||||
struct scope *scope = CurrentScope;
|
struct scopelist *vis = CurrVis;
|
||||||
register struct def *df;
|
|
||||||
|
|
||||||
prclev++;
|
prclev++;
|
||||||
CurrentScope = procedure->prc_scope;
|
CurrVis = procedure->prc_vis;
|
||||||
|
|
||||||
WalkDef(CurrentScope->sc_def);
|
WalkDef(CurrentScope->sc_def);
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ WalkProcedure(procedure)
|
||||||
if (func_type) C_ret((arith) align(func_type->tp_size, word_align));
|
if (func_type) C_ret((arith) align(func_type->tp_size, word_align));
|
||||||
else C_ret((arith) 0);
|
else C_ret((arith) 0);
|
||||||
C_end(align(-CurrentScope->sc_off, word_size));
|
C_end(align(-CurrentScope->sc_off, word_size));
|
||||||
CurrentScope = scope;
|
CurrVis = vis;
|
||||||
prclev--;
|
prclev--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +125,7 @@ WalkDef(df)
|
||||||
{
|
{
|
||||||
/* Walk through a list of definitions
|
/* Walk through a list of definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (df) {
|
while (df) {
|
||||||
if (df->df_kind == D_MODULE) {
|
if (df->df_kind == D_MODULE) {
|
||||||
WalkModule(df);
|
WalkModule(df);
|
||||||
|
@ -142,10 +142,11 @@ MkCalls(df)
|
||||||
{
|
{
|
||||||
/* Generate calls to initialization routines of modules
|
/* Generate calls to initialization routines of modules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (df) {
|
while (df) {
|
||||||
if (df->df_kind == D_MODULE) {
|
if (df->df_kind == D_MODULE) {
|
||||||
C_lxl((arith) 0);
|
C_lxl((arith) 0);
|
||||||
C_cal(df->mod_scope->sc_name);
|
C_cal(df->mod_vis->sc_scope->sc_name);
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +161,7 @@ WalkNode(nd, lab)
|
||||||
"lab" represents the label that must be jumped to on
|
"lab" represents the label that must be jumped to on
|
||||||
encountering an EXIT statement.
|
encountering an EXIT statement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (nd->nd_class == Link) { /* statement list */
|
while (nd->nd_class == Link) { /* statement list */
|
||||||
WalkStat(nd->nd_left, lab);
|
WalkStat(nd->nd_left, lab);
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
|
@ -191,8 +192,13 @@ WalkStat(nd, lab)
|
||||||
|
|
||||||
switch(nd->nd_symb) {
|
switch(nd->nd_symb) {
|
||||||
case BECOMES:
|
case BECOMES:
|
||||||
WalkExpr(nd->nd_right);
|
WalkDesignator(left);
|
||||||
WalkDesignator(nd->nd_left);
|
WalkExpr(right);
|
||||||
|
|
||||||
|
if (! TstAssCompat(left->nd_type, right->nd_type)) {
|
||||||
|
node_error(nd, "type incompatibility in assignment");
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* ??? */
|
/* ??? */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -217,8 +223,23 @@ WalkStat(nd, lab)
|
||||||
}
|
}
|
||||||
|
|
||||||
case CASE:
|
case CASE:
|
||||||
/* ??? */
|
{
|
||||||
break;
|
WalkExpr(left);
|
||||||
|
|
||||||
|
while (right) {
|
||||||
|
if (right->nd_class == Link && right->nd_symb == '|') {
|
||||||
|
WalkNode(right->nd_left->nd_right, lab);
|
||||||
|
right = right->nd_right;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WalkNode(right, lab);
|
||||||
|
right = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ??? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WHILE:
|
case WHILE:
|
||||||
{ label l1, l2;
|
{ label l1, l2;
|
||||||
|
@ -259,11 +280,27 @@ WalkStat(nd, lab)
|
||||||
|
|
||||||
case FOR:
|
case FOR:
|
||||||
/* ??? */
|
/* ??? */
|
||||||
|
WalkNode(right, lab);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WITH:
|
case WITH:
|
||||||
/* ??? */
|
{
|
||||||
break;
|
struct scopelist link;
|
||||||
|
|
||||||
|
WalkDesignator(left);
|
||||||
|
if (left->nd_type->tp_fund != T_RECORD) {
|
||||||
|
node_error(left, "record variable expected");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.sc_scope = left->nd_type->rec_scope;
|
||||||
|
link.next = CurrVis;
|
||||||
|
CurrVis = &link;
|
||||||
|
WalkNode(right, lab);
|
||||||
|
CurrVis = link.next;
|
||||||
|
/* ??? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EXIT:
|
case EXIT:
|
||||||
assert(lab != 0);
|
assert(lab != 0);
|
||||||
|
@ -274,7 +311,10 @@ WalkStat(nd, lab)
|
||||||
case RETURN:
|
case RETURN:
|
||||||
if (right) {
|
if (right) {
|
||||||
WalkExpr(right);
|
WalkExpr(right);
|
||||||
if (!TstCompat(right->nd_type, func_type)) {
|
/* What kind of compatibility do we need here ???
|
||||||
|
assignment compatibility?
|
||||||
|
*/
|
||||||
|
if (!TstAssCompat(func_type, right->nd_type)) {
|
||||||
node_error(right, "type incompatibility in RETURN statement");
|
node_error(right, "type incompatibility in RETURN statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue