Newer version, safety commit
This commit is contained in:
parent
b89155a64a
commit
52d743f223
13 changed files with 261 additions and 134 deletions
|
@ -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
|
||||||
|
|
|
@ -37,7 +37,7 @@ ProcedureHeading(struct def **pdf; int type;)
|
||||||
open_scope(OPENSCOPE, 0);
|
open_scope(OPENSCOPE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FormalParameters(type, ¶ms, &tp)?
|
FormalParameters(type == D_PROCEDURE, ¶ms, &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
|
||||||
|
|
|
@ -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
66
lang/m2/comp/defmodule.c
Normal 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;
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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)*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue