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

View file

@ -130,7 +130,12 @@ TypeDeclaration
}: }:
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); } IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
'=' type(&tp) '=' 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;): type(struct type **ptp;):
@ -338,7 +343,7 @@ PointerType(struct type **ptp;)
} }
else tp = df->df_type; 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) type(&tp)
| |
IDENT IDENT

View file

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

View file

@ -8,6 +8,7 @@ static char *RcsId = "$Header$";
#include <assert.h> #include <assert.h>
#include "Lpars.h" #include "Lpars.h"
#include "def.h" #include "def.h"
#include "type.h"
#include "idf.h" #include "idf.h"
#include "misc.h" #include "misc.h"
#include "main.h" #include "main.h"
@ -60,7 +61,9 @@ define(id, scope, kind)
df->df_kind = kind; df->df_kind = kind;
return df; return df;
} }
error("identifier \"%s\" already declared", id->id_text); if (kind != D_ERROR) {
error("identifier \"%s\" already declared", id->id_text);
}
return df; return df;
} }
df = new_def(); df = new_def();
@ -98,12 +101,9 @@ lookup(id, scope)
while (df) { while (df) {
if (df->df_scope == scope) { if (df->df_scope == scope) {
if (df->df_kind == D_IMPORT) { if (df->df_kind == D_IMPORT) {
df = lookup(id, df->imp_scopenr); df = df->imp_def;
assert(df != 0); assert(df != 0);
return df; return df;
/* ??? But this does damage to the self-
organizing character of the list
*/
} }
if (df1) { if (df1) {
df1->next = df->next; df1->next = df->next;
@ -118,14 +118,14 @@ lookup(id, scope)
return 0; 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) Export(ids, qualified)
register struct id_list *ids; 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; register struct def *df;
while (ids) { 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) Import(ids, id, local)
register struct id_list *ids; register struct id_list *ids;
struct idf *id; 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; register struct def *df;
int scope; int scope;
int kind; int kind;
int imp_kind;
#define FROM_MODULE 0
#define FROM_ENCLOSING 1
struct def *lookfor(); struct def *lookfor();
if (local) { if (local) {
kind = D_IMPORT; kind = D_IMPORT;
if (!id) scope = enclosing(currscope)->sc_scope; scope = enclosing(currscope)->sc_scope;
if (!id) imp_kind = FROM_ENCLOSING;
else { else {
df = lookfor(id, 1); imp_kind = FROM_MODULE;
df = lookfor(id, enclosing(currscope), 1);
if (df->df_kind != D_MODULE) { if (df->df_kind != D_MODULE) {
/* enter all "ids" with type D_ERROR */
kind = D_ERROR;
if (df->df_kind != D_ERROR) { if (df->df_kind != D_ERROR) {
error("identifier \"%s\" does not represent a module", id->id_text); 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; else scope = df->mod_scope;
} }
while (ids) { while (ids) {
df = lookup(ids->id_ptr, scope); if (imp_kind == FROM_MODULE) {
if (!df) { if (!(df = lookup(ids->id_ptr, scope))) {
error("identifier \"%s\" not declared", error("identifier \"%s\" not declared in qualifying module",
ids->id_ptr->id_text); 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; ids = ids->next;
} }
return; 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 * struct def *
lookfor(id, give_error) lookfor(id, scope, give_error)
struct idf *id; 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; struct def *df;
register struct scope *sc = scope;
while (sc) { while (sc) {
df = lookup(id, sc->sc_scope); df = lookup(id, sc->sc_scope);
@ -77,5 +79,5 @@ lookfor(id, give_error)
sc = nextvisible(sc); sc = nextvisible(sc);
} }
if (give_error) error("Identifier \"%s\" not declared", id->id_text); 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;) qualident(int types; struct def **pdf; char *str;)
{ {
int scope; int scope;
int module;
register struct def *df; register struct def *df;
struct def *lookfor(); struct def *lookfor();
} : } :
IDENT { if (types) { 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; if (df->df_kind == D_ERROR) types = 0;
} }
} }
@ -38,6 +39,7 @@ qualident(int types; struct def **pdf; char *str;)
/* selector */ /* selector */
'.' IDENT '.' IDENT
{ if (types) { { if (types) {
module = (df->df_kind == D_MODULE);
df = lookup(dot.TOK_IDF, scope); df = lookup(dot.TOK_IDF, scope);
if (!df) { if (!df) {
error("identifier \"%s\" not declared", error("identifier \"%s\" not declared",
@ -45,6 +47,11 @@ qualident(int types; struct def **pdf; char *str;)
types = 0; types = 0;
df = ill_df; 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 ModuleDeclaration
{ {
struct idf *id; struct idf *id;
struct def *df;
} : } :
MODULE IDENT { open_scope(CLOSEDSCOPE, 0); MODULE IDENT {
id = dot.TOK_IDF; id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0);
df->mod_scope = CurrentScope;
} }
priority? ';' priority? ';'
import(1)* import(1)*

View file

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