newer version, safety commit

This commit is contained in:
ceriel 1986-04-02 17:34:21 +00:00
parent 66c571d217
commit b89155a64a
8 changed files with 103 additions and 49 deletions

View file

@ -4,6 +4,7 @@ static char *RcsId = "$Header$";
#include <alloc.h>
#include <em_arith.h>
#include <assert.h>
#include "input.h"
#include "f_info.h"
#include "Lpars.h"
@ -179,7 +180,7 @@ again:
return tk->tk_symb = ch;
default :
crash("bad STCOMP");
assert(0);
}
case STIDF:
@ -373,7 +374,7 @@ Sdec:
case STCHAR:
default:
crash("bad character class %d", class(ch));
assert(0);
}
/*NOTREACHED*/
}

View file

@ -130,7 +130,12 @@ TypeDeclaration
}:
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
'=' type(&tp)
{ df->df_type = tp; }
{ df->df_type = tp;
if ((df->df_flags&D_EXPORTED) &&
tp->tp_fund == ENUMERATION) {
exprt_literals(tp->enm_enums, enclosing(currscope));
}
}
;
type(struct type **ptp;):
@ -338,7 +343,7 @@ PointerType(struct type **ptp;)
}
else tp = df->df_type;
}
| %if (df = lookfor(dot.TOK_IDF, 0), df->df_kind == D_MODULE)
| %if (df = lookfor(dot.TOK_IDF, currscope, 0), df->df_kind == D_MODULE)
type(&tp)
|
IDENT

View file

@ -38,8 +38,8 @@ struct field {
};
struct import {
int im_scopenr; /* Scope number from which imported */
#define imp_scopenr df_value.df_import.im_scopenr
struct def *im_def; /* Scope number from which imported */
#define imp_def df_value.df_import.im_def
};
struct def { /* list of definitions for a name */

View file

@ -8,6 +8,7 @@ static char *RcsId = "$Header$";
#include <assert.h>
#include "Lpars.h"
#include "def.h"
#include "type.h"
#include "idf.h"
#include "misc.h"
#include "main.h"
@ -60,7 +61,9 @@ define(id, scope, kind)
df->df_kind = kind;
return df;
}
error("identifier \"%s\" already declared", id->id_text);
if (kind != D_ERROR) {
error("identifier \"%s\" already declared", id->id_text);
}
return df;
}
df = new_def();
@ -98,12 +101,9 @@ lookup(id, scope)
while (df) {
if (df->df_scope == scope) {
if (df->df_kind == D_IMPORT) {
df = lookup(id, df->imp_scopenr);
df = df->imp_def;
assert(df != 0);
return df;
/* ??? But this does damage to the self-
organizing character of the list
*/
}
if (df1) {
df1->next = df->next;
@ -118,14 +118,14 @@ lookup(id, scope)
return 0;
}
/* From the current scope, the list of identifiers "ids" is
exported. Note this fact. If the export is not qualified, make
all the "ids" visible in the enclosing scope by defining them
in this scope as "imported".
*/
Export(ids, qualified)
register struct id_list *ids;
{
/* From the current scope, the list of identifiers "ids" is
exported. Note this fact. If the export is not qualified, make
all the "ids" visible in the enclosing scope by defining them
in this scope as "imported".
*/
register struct def *df;
while (ids) {
@ -142,53 +142,88 @@ Export(ids, qualified)
}
}
/* "ids" is a list of imported identifiers.
If "id" is a null-pointer, the identifiers are imported from the
enclosing scope. Otherwise they are imported from the module
indicated by "id", ehich must be visible in the enclosing scope.
An exception must be made for imports of the Compilation Unit.
This case is indicated by the value 0 of the flag "local".
In this case, if "id" is a null pointer, the "ids" identifiers
are all module identifiers. Their Definition Modules must be read.
Otherwise "id" is a module identifier whose Definition Module must
be read. "ids" then represents a list of identifiers defined in
this module.
*/
Import(ids, id, local)
register struct id_list *ids;
struct idf *id;
{
/* "ids" is a list of imported identifiers.
If "id" is a null-pointer, the identifiers are imported from the
enclosing scope. Otherwise they are imported from the module
indicated by "id", ehich must be visible in the enclosing scope.
An exception must be made for imports of the Compilation Unit.
This case is indicated by the value 0 of the flag "local".
In this case, if "id" is a null pointer, the "ids" identifiers
are all module identifiers. Their Definition Modules must be
read. Otherwise "id" is a module identifier whose Definition
Module must be read. "ids" then represents a list of
identifiers defined in this module.
*/
register struct def *df;
int scope;
int kind;
int imp_kind;
#define FROM_MODULE 0
#define FROM_ENCLOSING 1
struct def *lookfor();
if (local) {
kind = D_IMPORT;
if (!id) scope = enclosing(currscope)->sc_scope;
scope = enclosing(currscope)->sc_scope;
if (!id) imp_kind = FROM_ENCLOSING;
else {
df = lookfor(id, 1);
imp_kind = FROM_MODULE;
df = lookfor(id, enclosing(currscope), 1);
if (df->df_kind != D_MODULE) {
/* enter all "ids" with type D_ERROR */
kind = D_ERROR;
if (df->df_kind != D_ERROR) {
error("identifier \"%s\" does not represent a module", id->id_text);
}
/* enter all "ids" with type D_ERROR */
kind = D_ERROR;
scope = enclosing(currscope)->sc_scope;
}
else scope = df->mod_scope;
}
while (ids) {
df = lookup(ids->id_ptr, scope);
if (!df) {
error("identifier \"%s\" not declared",
ids->id_ptr->id_text);
if (imp_kind == FROM_MODULE) {
if (!(df = lookup(ids->id_ptr, scope))) {
error("identifier \"%s\" not declared in qualifying module",
ids->id_ptr->id_text);
df = ill_df;
}
else
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
error("identifier \"%s\" not exported from qualifying module",
ids->id_ptr->id_text);
}
}
else {
df = lookfor(ids->id_ptr, enclosing(currscope), 0);
if (df->df_kind == D_ERROR) {
error("identifier \"%s\" not visible in enclosing scope",
ids->id_ptr->id_text);
}
}
define(ids->id_ptr, CurrentScope, kind)->imp_def = df;
if (df->df_kind == D_TYPE &&
df->df_type->tp_fund == ENUMERATION) {
/* Also import all enumeration literals */
exprt_literals(df->df_type->enm_enums, currscope);
}
df = define(ids->id_ptr, CurrentScope, D_IMPORT);
df->imp_scopenr = scope;
ids = ids->next;
}
return;
}
/* ???? */
}
exprt_literals(df, toscope)
register struct def *df;
register struct scope *toscope;
{
/* A list of enumeration literals is exported. This is implemented
as an import from the scope "toscope".
*/
while (df) {
define(df->df_idf, toscope->sc_scope, D_IMPORT)->imp_def = df;
df = df->enm_next;
}
}

View file

@ -60,16 +60,18 @@ EnterIdList(idlist, kind, flags, type, scope)
}
}
/* Look for an identifier in the current visibility range.
If it is not defined, give an error message, and
create a dummy definition.
*/
struct def *
lookfor(id, give_error)
lookfor(id, scope, give_error)
struct idf *id;
struct scope *scope;
{
register struct scope *sc = currscope;
/* Look for an identifier in the visibility range started by
"scope".
If it is not defined, give an error message, and
create a dummy definition.
*/
struct def *df;
register struct scope *sc = scope;
while (sc) {
df = lookup(id, sc->sc_scope);
@ -77,5 +79,5 @@ lookfor(id, give_error)
sc = nextvisible(sc);
}
if (give_error) error("Identifier \"%s\" not declared", id->id_text);
return define(id, CurrentScope, D_ERROR);
return define(id, scope->sc_scope, D_ERROR);
}

View file

@ -21,11 +21,12 @@ number:
qualident(int types; struct def **pdf; char *str;)
{
int scope;
int module;
register struct def *df;
struct def *lookfor();
} :
IDENT { if (types) {
*pdf = df = lookfor(dot.TOK_IDF, 1);
*pdf = df = lookfor(dot.TOK_IDF, currscope, 1);
if (df->df_kind == D_ERROR) types = 0;
}
}
@ -38,6 +39,7 @@ qualident(int types; struct def **pdf; char *str;)
/* selector */
'.' IDENT
{ if (types) {
module = (df->df_kind == D_MODULE);
df = lookup(dot.TOK_IDF, scope);
if (!df) {
error("identifier \"%s\" not declared",
@ -45,6 +47,11 @@ qualident(int types; struct def **pdf; char *str;)
types = 0;
df = ill_df;
}
else
if (module &&
!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
error("identifier \"%s\" not exported from qualifying module", dot.TOK_IDF->id_text);
}
}
}
]*

View file

@ -35,9 +35,13 @@ static char *RcsId = "$Header$";
ModuleDeclaration
{
struct idf *id;
struct def *df;
} :
MODULE IDENT { open_scope(CLOSEDSCOPE, 0);
MODULE IDENT {
id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0);
df->mod_scope = CurrentScope;
}
priority? ';'
import(1)*

View file

@ -118,7 +118,7 @@ rem_forwards(fo)
savetok = dot;
while (f = fo) {
dot = f->fo_tok;
df = lookfor(dot.TOK_IDF, 1);
df = lookfor(dot.TOK_IDF, currscope, 1);
if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
error("identifier \"%s\" not a type", df->df_idf->id_text);
}