Newer version, safety commit

This commit is contained in:
ceriel 1986-04-03 00:44:39 +00:00
parent b89155a64a
commit 52d743f223
13 changed files with 261 additions and 134 deletions

View file

@ -14,7 +14,7 @@ LFLAGS = -p
LOBJ = tokenfile.o program.o declar.o expression.o statement.o LOBJ = tokenfile.o program.o declar.o expression.o statement.o
COBJ = LLlex.o LLmessage.o char.o error.o main.o \ COBJ = LLlex.o LLmessage.o char.o error.o main.o \
symbol2str.o tokenname.o idf.o input.o type.o def.o \ symbol2str.o tokenname.o idf.o input.o type.o def.o \
scope.o misc.o print.o enter.o scope.o misc.o print.o enter.o defmodule.o
OBJ = $(COBJ) $(LOBJ) Lpars.o OBJ = $(COBJ) $(LOBJ) Lpars.o
GENFILES= tokenfile.c \ GENFILES= tokenfile.c \
program.c declar.c expression.c statement.c \ program.c declar.c expression.c statement.c \
@ -69,18 +69,19 @@ LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h
LLmessage.o: LLlex.h Lpars.h idf.h LLmessage.o: LLlex.h Lpars.h idf.h
char.o: class.h char.o: class.h
error.o: LLlex.h f_info.h input.h error.o: LLlex.h f_info.h input.h
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h standards.h type.h main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h scope.h standards.h type.h
symbol2str.o: Lpars.h symbol2str.o: Lpars.h
tokenname.o: Lpars.h idf.h tokenname.h tokenname.o: Lpars.h idf.h tokenname.h
idf.o: idf.h idf.o: idf.h
input.o: f_info.h input.h input.o: f_info.h input.h
type.o: Lpars.h def.h def_sizes.h idf.h misc.h type.h type.o: Lpars.h def.h def_sizes.h idf.h misc.h type.h
def.o: Lpars.h debug.h def.h idf.h main.h misc.h scope.h def.o: Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
scope.o: LLlex.h debug.h def.h idf.h scope.h type.h scope.o: LLlex.h debug.h def.h idf.h scope.h type.h
misc.o: LLlex.h f_info.h idf.h misc.h misc.o: LLlex.h f_info.h idf.h misc.h
enter.o: def.h idf.h misc.h scope.h type.h enter.o: def.h idf.h misc.h scope.h type.h
defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h
tokenfile.o: Lpars.h tokenfile.o: Lpars.h
program.o: LLlex.h Lpars.h def.h idf.h main.h misc.h scope.h type.h program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h
expression.o: LLlex.h Lpars.h def.h idf.h scope.h expression.o: LLlex.h Lpars.h def.h idf.h scope.h
statement.o: Lpars.h statement.o: Lpars.h

View file

@ -37,7 +37,7 @@ ProcedureHeading(struct def **pdf; int type;)
open_scope(OPENSCOPE, 0); open_scope(OPENSCOPE, 0);
} }
} }
FormalParameters(type, &params, &tp)? FormalParameters(type == D_PROCEDURE, &params, &tp)?
{ {
(*pdf)->df_type = tp = construct_type(PROCEDURE, tp); (*pdf)->df_type = tp = construct_type(PROCEDURE, tp);
tp->prc_params = params; tp->prc_params = params;
@ -133,8 +133,14 @@ TypeDeclaration
{ df->df_type = tp; { df->df_type = tp;
if ((df->df_flags&D_EXPORTED) && if ((df->df_flags&D_EXPORTED) &&
tp->tp_fund == ENUMERATION) { tp->tp_fund == ENUMERATION) {
exprt_literals(tp->enm_enums, enclosing(currscope)); exprt_literals(tp->enm_enums,
enclosing(CurrentScope));
} }
if (df->df_kind == D_HTYPE &&
tp->tp_fund != POINTER) {
error("Opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
}
} }
; ;
@ -246,27 +252,29 @@ ArrayType(struct type **ptp;)
RecordType(struct type **ptp;) RecordType(struct type **ptp;)
{ {
int scopenr; struct scope scope;
} }
: :
RECORD RECORD
{ scopenr = uniq_scope(); } { scope.sc_scope = uniq_scope();
FieldListSequence(scopenr) scope.next = CurrentScope;
}
FieldListSequence(&scope)
{ {
*ptp = standard_type(RECORD, record_align, (arith) 0 /* ???? */); *ptp = standard_type(RECORD, record_align, (arith) 0 /* ???? */);
(*ptp)->rec_scopenr = scopenr; (*ptp)->rec_scope = scope.sc_scope;
} }
END END
; ;
FieldListSequence(int scopenr;): FieldListSequence(struct scope *scope;):
FieldList(scopenr) FieldList(scope)
[ [
';' FieldList(scopenr) ';' FieldList(scope)
]* ]*
; ;
FieldList(int scopenr;) FieldList(struct scope *scope;)
{ {
struct id_list *FldList; struct id_list *FldList;
struct idf *id; struct idf *id;
@ -283,21 +291,21 @@ FieldList(int scopenr;)
{ id = gen_anon_idf(); } { id = gen_anon_idf(); }
] /* Changed rule in new modula-2 */ ] /* Changed rule in new modula-2 */
':' qualident(D_TYPE|D_HTYPE, &df, "type") ':' qualident(D_TYPE|D_HTYPE, &df, "type")
{ df1 = define(id, scopenr, D_FIELD); { df1 = define(id, scope, D_FIELD);
df1->df_type = df->df_type; df1->df_type = df->df_type;
} }
OF variant(scopenr) OF variant(scope)
[ [
'|' variant(scopenr) '|' variant(scope)
]* ]*
[ ELSE FieldListSequence(scopenr) [ ELSE FieldListSequence(scope)
]? ]?
END END
]? ]?
; ;
variant(int scopenr;): variant(struct scope *scope;):
[ CaseLabelList ':' FieldListSequence(scopenr) ]? [ CaseLabelList ':' FieldListSequence(scope) ]?
/* Changed rule in new modula-2 */ /* Changed rule in new modula-2 */
; ;
@ -330,7 +338,7 @@ PointerType(struct type **ptp;)
struct def *lookfor(); struct def *lookfor();
} : } :
POINTER TO POINTER TO
[ %if ( (df = lookup(dot.TOK_IDF, CurrentScope))) [ %if ( (df = lookup(dot.TOK_IDF, CurrentScope->sc_scope)))
/* Either a Module or a Type, but in both cases defined /* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification in this scope, so this is the correct identification
*/ */
@ -343,7 +351,8 @@ PointerType(struct type **ptp;)
} }
else tp = df->df_type; else tp = df->df_type;
} }
| %if (df = lookfor(dot.TOK_IDF, currscope, 0), df->df_kind == D_MODULE) | %if (df = lookfor(dot.TOK_IDF, CurrentScope, 0),
df->df_kind == D_MODULE)
type(&tp) type(&tp)
| |
IDENT IDENT

View file

@ -25,6 +25,7 @@ struct def *ill_df = &illegal_def;
struct def * struct def *
define(id, scope, kind) define(id, scope, kind)
register struct idf *id; register struct idf *id;
struct scope *scope;
{ {
/* Declare an identifier in a scope, but first check if it /* Declare an identifier in a scope, but first check if it
already has been defined. If so, error message. already has been defined. If so, error message.
@ -32,14 +33,14 @@ define(id, scope, kind)
register struct def *df; register struct def *df;
register struct scope *sc; register struct scope *sc;
DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope)); DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope->sc_scope));
df = lookup(id, scope); df = lookup(id, scope->sc_scope);
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 ( CurrentScope == scope
&& &&
scopeclosed(currscope) scopeclosed(CurrentScope)
&& &&
(df = lookup(id, 0))) (df = lookup(id, 0)))
) { ) {
@ -68,19 +69,14 @@ define(id, scope, kind)
} }
df = new_def(); df = new_def();
df->df_idf = id; df->df_idf = id;
df->df_scope = scope; df->df_scope = scope->sc_scope;
df->df_kind = kind; df->df_kind = kind;
df->next = id->id_def; df->next = id->id_def;
id->id_def = df; id->id_def = df;
/* enter the definition in the list of definitions in this scope */ /* enter the definition in the list of definitions in this scope */
sc = currscope; df->df_nextinscope = scope->sc_def;
while (sc->sc_scope != scope) { scope->sc_def = df;
sc = sc->next;
assert(sc != 0);
}
df->df_nextinscope = sc->sc_def;
sc->sc_def = df;
return df; return df;
} }
@ -135,7 +131,7 @@ Export(ids, qualified)
} }
else { else {
df->df_flags |= D_EXPORTED; df->df_flags |= D_EXPORTED;
df = define(ids->id_ptr, enclosing(currscope)->sc_scope, df = define(ids->id_ptr, enclosing(CurrentScope),
D_IMPORT); D_IMPORT);
} }
ids = ids->next; ids = ids->next;
@ -164,55 +160,56 @@ Import(ids, id, local)
int imp_kind; int imp_kind;
#define FROM_MODULE 0 #define FROM_MODULE 0
#define FROM_ENCLOSING 1 #define FROM_ENCLOSING 1
struct def *lookfor(); struct def *lookfor(), *GetDefinitionModule();
if (local) { kind = D_IMPORT;
kind = D_IMPORT; scope = enclosing(CurrentScope)->sc_scope;
scope = enclosing(currscope)->sc_scope; if (!id) imp_kind = FROM_ENCLOSING;
if (!id) imp_kind = FROM_ENCLOSING; else {
else { imp_kind = FROM_MODULE;
imp_kind = FROM_MODULE; if (local) df = lookfor(id, enclosing(CurrentScope), 1);
df = lookfor(id, enclosing(currscope), 1); else df = GetDefinitionModule(id);
if (df->df_kind != D_MODULE) { if (df->df_kind != D_MODULE) {
/* enter all "ids" with type D_ERROR */ /* enter all "ids" with type D_ERROR */
kind = 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);
}
} }
else scope = df->mod_scope;
} }
while (ids) { else scope = df->mod_scope;
if (imp_kind == FROM_MODULE) { }
if (!(df = lookup(ids->id_ptr, scope))) { while (ids) {
if (imp_kind == FROM_MODULE) {
if (!(df = lookup(ids->id_ptr, scope))) {
error("identifier \"%s\" not declared in qualifying module", error("identifier \"%s\" not declared in qualifying module",
ids->id_ptr->id_text); ids->id_ptr->id_text);
df = ill_df; df = ill_df;
} }
else else
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) { if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
error("identifier \"%s\" not exported from qualifying module", error("identifier \"%s\" not exported from qualifying module",
ids->id_ptr->id_text); ids->id_ptr->id_text);
}
} }
else { }
df = lookfor(ids->id_ptr, enclosing(currscope), 0); else {
if (df->df_kind == D_ERROR) { if (local) {
df = lookfor(ids->id_ptr,
enclosing(CurrentScope), 0);
} else df = GetDefinitionModule(ids->id_ptr);
if (df->df_kind == D_ERROR) {
error("identifier \"%s\" not visible in enclosing scope", error("identifier \"%s\" not visible in enclosing scope",
ids->id_ptr->id_text); 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);
}
ids = ids->next;
} }
return; 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,
CurrentScope);
}
ids = ids->next;
} }
/* ???? */
} }
exprt_literals(df, toscope) exprt_literals(df, toscope)
@ -223,7 +220,7 @@ exprt_literals(df, toscope)
as an import from the scope "toscope". as an import from the scope "toscope".
*/ */
while (df) { while (df) {
define(df->df_idf, toscope->sc_scope, D_IMPORT)->imp_def = df; define(df->df_idf, toscope, D_IMPORT)->imp_def = df;
df = df->enm_next; df = df->enm_next;
} }
} }

66
lang/m2/comp/defmodule.c Normal file
View file

@ -0,0 +1,66 @@
/* D E F I N I T I O N M O D U L E S */
#include <assert.h>
#include <em_arith.h>
#include <em_label.h>
#include "idf.h"
#include "input.h"
#include "scope.h"
#include "def.h"
#include "LLlex.h"
#include "f_info.h"
GetFile(name)
char *name;
{
/* Try to find a file with basename "name" and extension ".def",
in the directories mentioned in "DEFPATH".
*/
extern char *DEFPATH[];
char buf[256];
(void) strcpy(buf, name);
if (strlen(buf) > 10) {
(void) strcpy(&buf[10], ".def");
}
else (void) strcat(buf, ".def");
if (! InsertFile(buf, DEFPATH, &(FileName))) {
fatal("Could'nt find a DEFINITION MODULE for \"%s\"", name);
}
LineNumber = 1;
}
struct def *
GetDefinitionModule(id)
struct idf *id;
{
/* Return a pointer to the "def" structure of the definition
module indicated by "id".
We may have to read the definition module itself.
*/
struct def *df;
df = lookup(id, GlobalScope->sc_scope);
if (!df) {
/* Read definition module. Make an exception for SYSTEM.
*/
if (!strcmp(id->id_text, "SYSTEM")) {
do_SYSTEM();
}
else {
GetFile(id->id_text);
DefModule();
}
df = lookup(id, GlobalScope->sc_scope);
}
assert(df != 0 && df->df_kind == D_MODULE);
return df;
}
AtEoIF()
{
/* Make the unstacking of input streams noticable by the
lexical analyzer
*/
return 1;
}

View file

@ -11,9 +11,6 @@ static char *RcsId = "$Header$";
#include "scope.h" #include "scope.h"
#include "misc.h" #include "misc.h"
extern struct idf *str2idf();
extern struct def *define();
struct def * struct def *
Enter(name, kind, type, pnam) Enter(name, kind, type, pnam)
char *name; char *name;
@ -35,6 +32,7 @@ Enter(name, kind, type, pnam)
EnterIdList(idlist, kind, flags, type, scope) EnterIdList(idlist, kind, flags, type, scope)
register struct id_list *idlist; register struct id_list *idlist;
struct type *type; struct type *type;
struct scope *scope;
{ {
register struct def *df; register struct def *df;
struct def *first = 0, *last = 0; struct def *first = 0, *last = 0;
@ -78,6 +76,6 @@ lookfor(id, scope, give_error)
if (df) return df; if (df) return df;
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, scope->sc_scope, D_ERROR); return define(id, scope, D_ERROR);
} }

View file

@ -26,7 +26,8 @@ qualident(int types; struct def **pdf; char *str;)
struct def *lookfor(); struct def *lookfor();
} : } :
IDENT { if (types) { IDENT { if (types) {
*pdf = df = lookfor(dot.TOK_IDF, currscope, 1); df = lookfor(dot.TOK_IDF, CurrentScope, 1);
*pdf = df;
if (df->df_kind == D_ERROR) types = 0; if (df->df_kind == D_ERROR) types = 0;
} }
} }

View file

@ -5,5 +5,5 @@
#define INP_NPUSHBACK 2 #define INP_NPUSHBACK 2
#define INP_TYPE struct f_info #define INP_TYPE struct f_info
#define INP_VAR file_info #define INP_VAR file_info
#define INP_READ_IN_ONE
#include <inp_pkg.spec> #include <inp_pkg.spec>

View file

@ -14,12 +14,15 @@ static char *RcsId = "$Header$";
#include "debug.h" #include "debug.h"
#include "type.h" #include "type.h"
#include "def.h" #include "def.h"
#include "scope.h"
#include "standards.h" #include "standards.h"
char options[128]; char options[128];
char *ProgName; char *ProgName;
int state; int state;
extern int err_occurred; extern int err_occurred;
char *DEFPATH[128];
char *getenv();
main(argc, argv) main(argc, argv)
char *argv[]; char *argv[];
@ -53,12 +56,13 @@ Compile(src)
extern struct tokenname tkidf[]; extern struct tokenname tkidf[];
DO_DEBUG(debug(1,"Filename : %s", src)); DO_DEBUG(debug(1,"Filename : %s", src));
if (! InsertFile(src, (char **) 0)) { if (! InsertFile(src, (char **) 0, &src)) {
fprintf(STDERR,"%s: cannot open %s\n", ProgName, src); fprintf(STDERR,"%s: cannot open %s\n", ProgName, src);
return 0; return 0;
} }
LineNumber = 1; LineNumber = 1;
FileName = src; FileName = src;
init_DEFPATH();
init_idf(); init_idf();
reserve(tkidf); reserve(tkidf);
init_scope(); init_scope();
@ -69,10 +73,13 @@ Compile(src)
LexScan(); LexScan();
else if (options['T']) else if (options['T'])
TimeScan(); TimeScan();
else else {
#endif DEBUG #endif DEBUG
(void) open_scope(CLOSEDSCOPE, 0);
GlobalScope = CurrentScope;
CompUnit(); CompUnit();
#ifdef DEBUG #ifdef DEBUG
}
if (options['h']) hash_stat(); if (options['h']) hash_stat();
#endif DEBUG #endif DEBUG
if (err_occurred) return 0; if (err_occurred) return 0;
@ -169,3 +176,33 @@ add_standards()
df->df_value.df_enum.en_val = 1; df->df_value.df_enum.en_val = 1;
df->df_value.df_enum.en_next = 0; df->df_value.df_enum.en_next = 0;
} }
init_DEFPATH()
{
register char *p = getenv("M2path");
register int i = 0;
if (p) {
while (*p) {
DEFPATH[i++] = p;
while (*p && *p != ':') p++;
if (*p) *p++ = '\0';
}
}
DEFPATH[i] = 0;
}
do_SYSTEM()
{
/* Simulate the reading of the SYSTEM definition module
*/
struct def *df;
struct idf *sys_id;
sys_id = str2idf("SYSTEM", 0);
df = define(sys_id, GlobalScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0);
df->mod_scope = CurrentScope->sc_scope;
/* ???? */
close_scope();
}

View file

@ -13,6 +13,7 @@ static char *RcsId = "$Header$";
#include "scope.h" #include "scope.h"
#include "def.h" #include "def.h"
#include "type.h" #include "type.h"
#include "debug.h"
} }
/* /*
The grammar as given by Wirth is already almost LL(1); the The grammar as given by Wirth is already almost LL(1); the
@ -31,6 +32,7 @@ static char *RcsId = "$Header$";
%lexical LLlex; %lexical LLlex;
%start CompUnit, CompilationUnit; %start CompUnit, CompilationUnit;
%start DefModule, DefinitionModule;
ModuleDeclaration ModuleDeclaration
{ {
@ -41,11 +43,11 @@ ModuleDeclaration
id = dot.TOK_IDF; id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE); df = define(id, CurrentScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0); open_scope(CLOSEDSCOPE, 0);
df->mod_scope = CurrentScope; df->mod_scope = CurrentScope->sc_scope;
} }
priority? ';' priority? ';'
import(1)* import(1)*
export? export(0)?
block block
IDENT { close_scope(); IDENT { close_scope();
match_id(id, dot.TOK_IDF); match_id(id, dot.TOK_IDF);
@ -56,7 +58,7 @@ priority:
'[' ConstExpression ']' '[' ConstExpression ']'
; ;
export export(int def;)
{ {
struct id_list *ExportList; struct id_list *ExportList;
int QUALflag = 0; int QUALflag = 0;
@ -67,7 +69,8 @@ export
]? ]?
IdentList(&ExportList) ';' IdentList(&ExportList) ';'
{ {
Export(ExportList, QUALflag); if (!def) Export(ExportList, QUALflag);
else warning("export list in definition module ignored");
FreeIdList(ExportList); FreeIdList(ExportList);
} }
; ;
@ -95,23 +98,31 @@ import(int local;)
DefinitionModule DefinitionModule
{ {
struct def *df; register struct def *df;
struct idf *id; struct idf *id;
} : } :
DEFINITION { state = DEFINITION; } DEFINITION { state = DEFINITION; }
MODULE IDENT { id = dot.TOK_IDF; MODULE IDENT { id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE); df = define(id, GlobalScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0); open_scope(CLOSEDSCOPE, 0);
df->mod_scope = CurrentScope; df->mod_scope = CurrentScope->sc_scope;
DO_DEBUG(debug(1, "Definition module \"%s\"", id->id_text));
} }
';' ';'
import(0)* import(0)*
/* export? export(1)?
New Modula-2 does not have export lists in definition modules. /* New Modula-2 does not have export lists in definition modules.
*/ */
definition* END IDENT '.' definition* END IDENT '.'
{ close_scope(); {
df = CurrentScope->sc_def;
while (df) {
/* Make all definitions "QUALIFIED EXPORT" */
df->df_flags |= D_QEXPORTED;
df = df->df_nextinscope;
}
close_scope();
match_id(id, dot.TOK_IDF); match_id(id, dot.TOK_IDF);
} }
; ;
@ -124,7 +135,7 @@ definition
CONST [ ConstantDeclaration ';' ]* CONST [ ConstantDeclaration ';' ]*
| |
TYPE TYPE
[ IDENT [ IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
[ '=' type(&tp) [ '=' type(&tp)
| /* empty */ | /* empty */
/* /*
@ -132,6 +143,7 @@ definition
The export is said to be opaque. The export is said to be opaque.
It is restricted to pointer types. It is restricted to pointer types.
*/ */
{ df->df_kind = D_HIDDEN; }
] ]
';' ';'
]* ]*
@ -141,19 +153,20 @@ definition
ProcedureHeading(&df, D_PROCHEAD) ';' ProcedureHeading(&df, D_PROCHEAD) ';'
; ;
ProgramModule { ProgramModule
{
struct idf *id; struct idf *id;
struct def *df, *GetDefinitionModule();
int scope = 0;
} : } :
MODULE { if (state != IMPLEMENTATION) state = PROGRAM; } MODULE { if (state != IMPLEMENTATION) state = PROGRAM; }
IDENT { if (state == IMPLEMENTATION) { IDENT {
/* ????
Read definition module,
Look for current identifier,
and find out its scope number
*/
}
id = dot.TOK_IDF; id = dot.TOK_IDF;
open_scope(CLOSEDSCOPE, 0); if (state == IMPLEMENTATION) {
df = GetDefinitionModule(id);
scope = df->mod_scope;
}
open_scope(CLOSEDSCOPE, scope);
} }
priority? priority?
';' import(0)* ';' import(0)*

View file

@ -15,41 +15,44 @@ static char *RcsId = "$Header$";
static int maxscope; /* maximum assigned scope number */ static int maxscope; /* maximum assigned scope number */
struct scope *currscope; struct scope *CurrentScope, *GlobalScope;
/* STATICALLOCDEF "scope" */ /* STATICALLOCDEF "scope" */
/* Open a scope that is either open (automatic imports) or closed. open_scope(scopetype, scope)
A closed scope is handled by adding an extra entry to the list
with scope number 0. This has two purposes: it makes scope 0
visible, and it marks the end of a visibility list.
Scope 0 is the pervasive scope, the one that is always visible.
A disadvantage of this method is that we cannot open scope 0
explicitly.
*/
open_scope(scopetype, scopenr)
{ {
/* Open a scope that is either open (automatic imports) or closed.
A closed scope is handled by adding an extra entry to the list
with scope number 0. This has two purposes: it makes scope 0
visible, and it marks the end of a visibility list.
Scope 0 is the pervasive scope, the one that is always visible.
A disadvantage of this method is that we cannot open scope 0
explicitly.
*/
register struct scope *sc = new_scope(); register struct scope *sc = new_scope();
register struct scope *sc1; register struct scope *sc1;
sc->sc_scope = scopenr == 0 ? ++maxscope : scopenr; sc->sc_scope = scope == 0 ? ++maxscope : scope;
sc->sc_forw = 0; sc->sc_def = 0;
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
DO_DEBUG(debug(1, "Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed")); DO_DEBUG(debug(1, "Opening a %s scope",
sc1 = currscope; scopetype == OPENSCOPE ? "open" : "closed"));
sc1 = CurrentScope;
if (scopetype == CLOSEDSCOPE) { if (scopetype == CLOSEDSCOPE) {
sc1 = new_scope(); sc1 = new_scope();
sc1->sc_scope = 0; /* Pervasive scope nr */ sc1->sc_scope = 0; /* Pervasive scope nr */
sc1->next = currscope; sc1->sc_forw = 0; sc1->sc_def = 0;
sc1->next = CurrentScope;
} }
sc->next = sc1; sc->next = sc1;
currscope = sc; CurrentScope = sc;
} }
static rem_forwards(); static rem_forwards();
close_scope() close_scope()
{ {
register struct scope *sc = currscope; register struct scope *sc = CurrentScope;
assert(sc != 0); assert(sc != 0);
DO_DEBUG(debug(1, "Closing a scope")); DO_DEBUG(debug(1, "Closing a scope"));
@ -60,7 +63,7 @@ close_scope()
sc = sc->next; sc = sc->next;
free_scope(sc1); free_scope(sc1);
} }
currscope = sc->next; CurrentScope = sc->next;
free_scope(sc); free_scope(sc);
} }
@ -69,8 +72,9 @@ init_scope()
register struct scope *sc = new_scope(); register struct scope *sc = new_scope();
sc->sc_scope = 0; sc->sc_scope = 0;
sc->next = 0; sc->sc_forw = 0;
currscope = sc; sc->sc_def = 0;
CurrentScope = sc;
} }
int int
@ -87,29 +91,29 @@ struct forwards {
/* STATICALLOCDEF "forwards" */ /* STATICALLOCDEF "forwards" */
/* Enter a forward reference into a list belonging to the
current scope. This is used for POINTER declarations, which
may have forward references that must howewer be declared in the
same scope.
*/
Forward(tk, ptp) Forward(tk, ptp)
struct token *tk; struct token *tk;
struct type **ptp; struct type **ptp;
{ {
/* Enter a forward reference into a list belonging to the
current scope. This is used for POINTER declarations, which
may have forward references that must howewer be declared in the
same scope.
*/
register struct forwards *f = new_forwards(); register struct forwards *f = new_forwards();
f->fo_tok = *tk; f->fo_tok = *tk;
f->fo_ptyp = ptp; f->fo_ptyp = ptp;
f->next = currscope->sc_forw; f->next = CurrentScope->sc_forw;
currscope->sc_forw = f; CurrentScope->sc_forw = f;
} }
/* When closing a scope, all forward references must be resolved
*/
static static
rem_forwards(fo) rem_forwards(fo)
struct forwards *fo; struct forwards *fo;
{ {
/* When closing a scope, all forward references must be resolved
*/
register struct forwards *f; register struct forwards *f;
struct token savetok; struct token savetok;
register struct def *df; register struct def *df;
@ -118,9 +122,10 @@ 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, currscope, 1); df = lookfor(dot.TOK_IDF, CurrentScope, 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);
} }
*(f->fo_ptyp) = df->df_type; *(f->fo_ptyp) = df->df_type;
fo = f->next; fo = f->next;

View file

@ -16,9 +16,9 @@ struct scope {
}; };
extern struct scope extern struct scope
*currscope; *CurrentScope,
*GlobalScope;
#define nextvisible(x) ((x)->sc_scope ? (x)->next : (struct scope *) 0) #define nextvisible(x) ((x)->sc_scope ? (x)->next : (struct scope *) 0)
#define scopeclosed(x) ((x)->next->sc_scope == 0) #define scopeclosed(x) ((x)->next->sc_scope == 0)
#define enclosing(x) (scopeclosed(x) ? (x)->next->next : (x)->next) #define enclosing(x) (scopeclosed(x) ? (x)->next->next : (x)->next)
#define CurrentScope (currscope->sc_scope)

View file

@ -38,9 +38,9 @@ struct array {
}; };
struct record { struct record {
int rc_scopenr; /* Scope number of this record */ int rc_scope; /* Scope number of this record */
/* Members are in the symbol table */ /* Members are in the symbol table */
#define rec_scopenr tp_value.tp_record.rc_scopenr #define rec_scope tp_value.tp_record.rc_scope
}; };
struct proc { struct proc {

View file

@ -144,7 +144,7 @@ has_selectors(df)
register struct type *tp = df->df_type; register struct type *tp = df->df_type;
if (tp->tp_fund == RECORD) { if (tp->tp_fund == RECORD) {
return tp->rec_scopenr; return tp->rec_scope;
} }
break; break;
} }