LOBJ = tokenfile.o program.o declar.o expression.o statement.o
COBJ = LLlex.o LLmessage.o char.o error.o main.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
GENFILES= tokenfile.c \
program.c declar.c expression.c statement.c \
LLmessage.o: LLlex.h Lpars.h idf.h
char.o: class.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
tokenname.o: Lpars.h idf.h tokenname.h
idf.o: idf.h
input.o: f_info.h input.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
misc.o: LLlex.h f_info.h idf.h misc.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
-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
expression.o: LLlex.h Lpars.h def.h idf.h scope.h
statement.o: Lpars.h
open_scope(OPENSCOPE, 0);
}
}
- FormalParameters(type, ¶ms, &tp)?
+ FormalParameters(type == D_PROCEDURE, ¶ms, &tp)?
{
(*pdf)->df_type = tp = construct_type(PROCEDURE, tp);
tp->prc_params = params;
{ df->df_type = tp;
if ((df->df_flags&D_EXPORTED) &&
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);
+ }
+
}
;
RecordType(struct type **ptp;)
{
- int scopenr;
+ struct scope scope;
}
:
RECORD
- { scopenr = uniq_scope(); }
- FieldListSequence(scopenr)
+ { scope.sc_scope = uniq_scope();
+ scope.next = CurrentScope;
+ }
+ FieldListSequence(&scope)
{
*ptp = standard_type(RECORD, record_align, (arith) 0 /* ???? */);
- (*ptp)->rec_scopenr = scopenr;
+ (*ptp)->rec_scope = scope.sc_scope;
}
END
;
-FieldListSequence(int scopenr;):
- FieldList(scopenr)
+FieldListSequence(struct scope *scope;):
+ FieldList(scope)
[
- ';' FieldList(scopenr)
+ ';' FieldList(scope)
]*
;
-FieldList(int scopenr;)
+FieldList(struct scope *scope;)
{
struct id_list *FldList;
struct idf *id;
{ id = gen_anon_idf(); }
] /* Changed rule in new modula-2 */
':' 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;
}
- OF variant(scopenr)
+ OF variant(scope)
[
- '|' variant(scopenr)
+ '|' variant(scope)
]*
- [ ELSE FieldListSequence(scopenr)
+ [ ELSE FieldListSequence(scope)
]?
END
]?
;
-variant(int scopenr;):
- [ CaseLabelList ':' FieldListSequence(scopenr) ]?
+variant(struct scope *scope;):
+ [ CaseLabelList ':' FieldListSequence(scope) ]?
/* Changed rule in new modula-2 */
;
struct def *lookfor();
} :
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
in this scope, so this is the correct identification
*/
}
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)
|
IDENT
struct def *
define(id, scope, kind)
register struct idf *id;
+ struct scope *scope;
{
/* Declare an identifier in a scope, but first check if it
already has been defined. If so, error message.
register struct def *df;
register struct scope *sc;
- DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope));
- df = lookup(id, scope);
+ DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope->sc_scope));
+ df = lookup(id, scope->sc_scope);
if ( /* Already in this scope */
df
|| /* A closed scope, and id defined in the pervasive scope */
( CurrentScope == scope
&&
- scopeclosed(currscope)
+ scopeclosed(CurrentScope)
&&
(df = lookup(id, 0)))
) {
}
df = new_def();
df->df_idf = id;
- df->df_scope = scope;
+ df->df_scope = scope->sc_scope;
df->df_kind = kind;
df->next = id->id_def;
id->id_def = df;
/* enter the definition in the list of definitions in this scope */
- sc = currscope;
- while (sc->sc_scope != scope) {
- sc = sc->next;
- assert(sc != 0);
- }
- df->df_nextinscope = sc->sc_def;
- sc->sc_def = df;
+ df->df_nextinscope = scope->sc_def;
+ scope->sc_def = df;
return df;
}
}
else {
df->df_flags |= D_EXPORTED;
- df = define(ids->id_ptr, enclosing(currscope)->sc_scope,
+ df = define(ids->id_ptr, enclosing(CurrentScope),
D_IMPORT);
}
ids = ids->next;
int imp_kind;
#define FROM_MODULE 0
#define FROM_ENCLOSING 1
- struct def *lookfor();
+ struct def *lookfor(), *GetDefinitionModule();
- if (local) {
- kind = D_IMPORT;
- scope = enclosing(currscope)->sc_scope;
- if (!id) imp_kind = FROM_ENCLOSING;
- else {
- 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) {
+ kind = D_IMPORT;
+ scope = enclosing(CurrentScope)->sc_scope;
+ if (!id) imp_kind = FROM_ENCLOSING;
+ else {
+ imp_kind = FROM_MODULE;
+ if (local) df = lookfor(id, enclosing(CurrentScope), 1);
+ else df = GetDefinitionModule(id);
+ 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);
- }
}
- else scope = df->mod_scope;
}
- while (ids) {
- if (imp_kind == FROM_MODULE) {
- if (!(df = lookup(ids->id_ptr, scope))) {
+ else scope = df->mod_scope;
+ }
+ while (ids) {
+ 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))) {
+ 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) {
+ }
+ else {
+ 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",
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)
as an import from the scope "toscope".
*/
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;
}
}
--- /dev/null
+/* 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;
+}
#include "scope.h"
#include "misc.h"
-extern struct idf *str2idf();
-extern struct def *define();
-
struct def *
Enter(name, kind, type, pnam)
char *name;
EnterIdList(idlist, kind, flags, type, scope)
register struct id_list *idlist;
struct type *type;
+ struct scope *scope;
{
register struct def *df;
struct def *first = 0, *last = 0;
if (df) return df;
sc = nextvisible(sc);
}
- if (give_error) error("Identifier \"%s\" not declared", id->id_text);
- return define(id, scope->sc_scope, D_ERROR);
+ if (give_error) error("identifier \"%s\" not declared", id->id_text);
+ return define(id, scope, D_ERROR);
}
struct def *lookfor();
} :
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;
}
}
#define INP_NPUSHBACK 2
#define INP_TYPE struct f_info
#define INP_VAR file_info
-#define INP_READ_IN_ONE
+
#include <inp_pkg.spec>
#include "debug.h"
#include "type.h"
#include "def.h"
+#include "scope.h"
#include "standards.h"
char options[128];
char *ProgName;
int state;
extern int err_occurred;
+char *DEFPATH[128];
+char *getenv();
main(argc, argv)
char *argv[];
extern struct tokenname tkidf[];
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);
return 0;
}
LineNumber = 1;
FileName = src;
+ init_DEFPATH();
init_idf();
reserve(tkidf);
init_scope();
LexScan();
else if (options['T'])
TimeScan();
- else
+ else {
#endif DEBUG
+ (void) open_scope(CLOSEDSCOPE, 0);
+ GlobalScope = CurrentScope;
CompUnit();
#ifdef DEBUG
+ }
if (options['h']) hash_stat();
#endif DEBUG
if (err_occurred) return 0;
df->df_value.df_enum.en_val = 1;
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();
+}
#include "scope.h"
#include "def.h"
#include "type.h"
+#include "debug.h"
}
/*
The grammar as given by Wirth is already almost LL(1); the
%lexical LLlex;
%start CompUnit, CompilationUnit;
+%start DefModule, DefinitionModule;
ModuleDeclaration
{
id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE);
open_scope(CLOSEDSCOPE, 0);
- df->mod_scope = CurrentScope;
+ df->mod_scope = CurrentScope->sc_scope;
}
priority? ';'
import(1)*
- export?
+ export(0)?
block
IDENT { close_scope();
match_id(id, dot.TOK_IDF);
'[' ConstExpression ']'
;
-export
+export(int def;)
{
struct id_list *ExportList;
int QUALflag = 0;
]?
IdentList(&ExportList) ';'
{
- Export(ExportList, QUALflag);
+ if (!def) Export(ExportList, QUALflag);
+ else warning("export list in definition module ignored");
FreeIdList(ExportList);
}
;
DefinitionModule
{
- struct def *df;
+ register struct def *df;
struct idf *id;
} :
DEFINITION { state = DEFINITION; }
MODULE IDENT { id = dot.TOK_IDF;
- df = define(id, CurrentScope, D_MODULE);
+ df = define(id, GlobalScope, D_MODULE);
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)*
- /* 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 '.'
- { 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);
}
;
CONST [ ConstantDeclaration ';' ]*
|
TYPE
- [ IDENT
+ [ IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
[ '=' type(&tp)
| /* empty */
/*
The export is said to be opaque.
It is restricted to pointer types.
*/
+ { df->df_kind = D_HIDDEN; }
]
';'
]*
ProcedureHeading(&df, D_PROCHEAD) ';'
;
-ProgramModule {
+ProgramModule
+{
struct idf *id;
+ struct def *df, *GetDefinitionModule();
+ int scope = 0;
} :
MODULE { if (state != IMPLEMENTATION) state = PROGRAM; }
- IDENT { if (state == IMPLEMENTATION) {
- /* ????
- Read definition module,
- Look for current identifier,
- and find out its scope number
- */
- }
+ IDENT {
id = dot.TOK_IDF;
- open_scope(CLOSEDSCOPE, 0);
+ if (state == IMPLEMENTATION) {
+ df = GetDefinitionModule(id);
+ scope = df->mod_scope;
+ }
+ open_scope(CLOSEDSCOPE, scope);
}
priority?
';' import(0)*
static int maxscope; /* maximum assigned scope number */
-struct scope *currscope;
+struct scope *CurrentScope, *GlobalScope;
/* STATICALLOCDEF "scope" */
-/* 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.
-*/
-open_scope(scopetype, scopenr)
+open_scope(scopetype, scope)
{
+ /* 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 *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);
- DO_DEBUG(debug(1, "Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed"));
- sc1 = currscope;
+ DO_DEBUG(debug(1, "Opening a %s scope",
+ scopetype == OPENSCOPE ? "open" : "closed"));
+ sc1 = CurrentScope;
if (scopetype == CLOSEDSCOPE) {
sc1 = new_scope();
sc1->sc_scope = 0; /* Pervasive scope nr */
- sc1->next = currscope;
+ sc1->sc_forw = 0; sc1->sc_def = 0;
+ sc1->next = CurrentScope;
}
sc->next = sc1;
- currscope = sc;
+ CurrentScope = sc;
}
static rem_forwards();
close_scope()
{
- register struct scope *sc = currscope;
+ register struct scope *sc = CurrentScope;
assert(sc != 0);
DO_DEBUG(debug(1, "Closing a scope"));
sc = sc->next;
free_scope(sc1);
}
- currscope = sc->next;
+ CurrentScope = sc->next;
free_scope(sc);
}
register struct scope *sc = new_scope();
sc->sc_scope = 0;
- sc->next = 0;
- currscope = sc;
+ sc->sc_forw = 0;
+ sc->sc_def = 0;
+ CurrentScope = sc;
}
int
/* 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)
struct token *tk;
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();
f->fo_tok = *tk;
f->fo_ptyp = ptp;
- f->next = currscope->sc_forw;
- currscope->sc_forw = f;
+ f->next = CurrentScope->sc_forw;
+ CurrentScope->sc_forw = f;
}
-/* When closing a scope, all forward references must be resolved
-*/
static
rem_forwards(fo)
struct forwards *fo;
{
+ /* When closing a scope, all forward references must be resolved
+ */
register struct forwards *f;
struct token savetok;
register struct def *df;
savetok = dot;
while (f = fo) {
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))) {
- 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;
fo = f->next;
};
extern struct scope
- *currscope;
+ *CurrentScope,
+ *GlobalScope;
#define nextvisible(x) ((x)->sc_scope ? (x)->next : (struct scope *) 0)
#define scopeclosed(x) ((x)->next->sc_scope == 0)
#define enclosing(x) (scopeclosed(x) ? (x)->next->next : (x)->next)
-#define CurrentScope (currscope->sc_scope)
};
struct record {
- int rc_scopenr; /* Scope number of this record */
+ int rc_scope; /* Scope number of this record */
/* 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 {
register struct type *tp = df->df_type;
if (tp->tp_fund == RECORD) {
- return tp->rec_scopenr;
+ return tp->rec_scope;
}
break;
}