ack/lang/m2/comp/def.c

336 lines
6.9 KiB
C
Raw Normal View History

1986-03-26 15:11:02 +00:00
/* D E F I N I T I O N M E C H A N I S M */
1986-05-01 19:06:53 +00:00
#ifndef NORCSID
1986-03-26 15:11:02 +00:00
static char *RcsId = "$Header$";
1986-05-01 19:06:53 +00:00
#endif
#include "debug.h"
1986-03-26 15:11:02 +00:00
#include <alloc.h>
#include <em_arith.h>
#include <em_label.h>
1986-03-29 01:04:49 +00:00
#include <assert.h>
1986-04-21 17:27:06 +00:00
1986-04-08 18:15:46 +00:00
#include "main.h"
1986-03-26 15:11:02 +00:00
#include "def.h"
1986-04-02 17:34:21 +00:00
#include "type.h"
1986-03-26 15:11:02 +00:00
#include "idf.h"
#include "scope.h"
1986-04-06 17:42:56 +00:00
#include "LLlex.h"
#include "node.h"
1986-05-28 18:36:51 +00:00
#include "Lpars.h"
1986-04-21 17:27:06 +00:00
1986-05-30 18:48:00 +00:00
struct def *h_def; /* pointer to free list of def structures */
#ifdef DEBUG
int cnt_def; /* count number of allocated ones */
#endif
1986-03-26 15:11:02 +00:00
1986-05-01 19:06:53 +00:00
struct def *ill_df;
1986-03-27 17:37:41 +00:00
1986-04-18 17:53:47 +00:00
struct def *
MkDef(id, scope, kind)
struct idf *id;
1986-06-04 09:01:48 +00:00
register struct scope *scope;
1986-04-18 17:53:47 +00:00
{
/* Create a new definition structure in scope "scope", with
id "id" and kind "kind".
*/
register struct def *df;
df = new_def();
1986-04-28 18:06:58 +00:00
clear((char *) df, sizeof (*df));
1986-04-18 17:53:47 +00:00
df->df_idf = id;
df->df_scope = 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
*/
df->df_nextinscope = scope->sc_def;
scope->sc_def = df;
return df;
}
1986-05-01 19:06:53 +00:00
InitDef()
{
/* Initialize this module. Easy, the only thing to be initialized
1986-06-04 09:01:48 +00:00
is "ill_df".
1986-05-01 19:06:53 +00:00
*/
struct idf *gen_anon_idf();
ill_df = MkDef(gen_anon_idf(), CurrentScope, D_ERROR);
1986-09-25 19:39:06 +00:00
ill_df->df_type = error_type;
1986-05-01 19:06:53 +00:00
}
1986-03-26 15:11:02 +00:00
struct def *
define(id, scope, kind)
register struct idf *id;
1986-04-08 18:15:46 +00:00
register struct scope *scope;
1986-03-26 15:11:02 +00:00
{
/* Declare an identifier in a scope, but first check if it
already has been defined. If so, error message.
*/
1986-03-27 17:37:41 +00:00
register struct def *df;
1986-03-26 15:11:02 +00:00
1986-04-15 17:51:53 +00:00
df = lookup(id, scope);
1986-03-26 17:53:13 +00:00
if ( /* Already in this scope */
df
|| /* A closed scope, and id defined in the pervasive scope */
1986-04-28 18:06:58 +00:00
(
1986-04-15 17:51:53 +00:00
scopeclosed(scope)
1986-03-27 17:37:41 +00:00
&&
1986-04-15 17:51:53 +00:00
(df = lookup(id, PervasiveScope)))
1986-03-26 17:53:13 +00:00
) {
1986-03-26 15:11:02 +00:00
switch(df->df_kind) {
case D_HIDDEN:
1986-06-04 09:01:48 +00:00
/* An opaque type. We may now have found the
definition of this type.
*/
1986-04-03 17:41:26 +00:00
if (kind == D_TYPE && !DefinitionModule) {
1986-05-28 18:36:51 +00:00
df->df_kind = D_TYPE;
1986-03-26 15:11:02 +00:00
return df;
}
break;
1986-04-28 18:06:58 +00:00
1986-04-11 11:57:19 +00:00
case D_FORWMODULE:
1986-06-04 09:01:48 +00:00
/* A forward reference to a module. We may have found
another one, or we may have found the definition
for this module.
*/
1986-04-12 02:21:24 +00:00
if (kind == D_FORWMODULE) {
return df;
}
1986-04-28 18:06:58 +00:00
1986-04-12 02:21:24 +00:00
if (kind == D_MODULE) {
FreeNode(df->for_node);
1986-04-28 18:06:58 +00:00
df->mod_vis = df->for_vis;
1986-04-11 11:57:19 +00:00
df->df_kind = kind;
1986-05-28 18:36:51 +00:00
DefInFront(df);
1986-04-11 11:57:19 +00:00
return df;
}
break;
1986-04-28 18:06:58 +00:00
1986-04-11 11:57:19 +00:00
case D_FORWARD:
1986-06-04 09:01:48 +00:00
/* A forward reference, for which we may now have
found a definition.
*/
1986-04-12 02:21:24 +00:00
if (kind != D_FORWARD) {
FreeNode(df->for_node);
}
1986-04-28 18:06:58 +00:00
1986-06-04 09:01:48 +00:00
/* Fall through */
1986-04-28 18:06:58 +00:00
1986-04-12 02:21:24 +00:00
case D_ERROR:
1986-06-04 09:01:48 +00:00
/* A definition generated by the compiler, because
it found an error. Maybe, the user gives a
definition after all.
*/
1986-03-26 15:11:02 +00:00
df->df_kind = kind;
return df;
}
1986-04-28 18:06:58 +00:00
1986-04-02 17:34:21 +00:00
if (kind != D_ERROR) {
1986-06-04 09:01:48 +00:00
/* Avoid spurious error messages
*/
1986-04-06 17:42:56 +00:00
error("identifier \"%s\" already declared", id->id_text);
1986-04-02 17:34:21 +00:00
}
1986-04-28 18:06:58 +00:00
1986-03-26 15:11:02 +00:00
return df;
}
1986-04-28 18:06:58 +00:00
1986-04-18 17:53:47 +00:00
return MkDef(id, scope, kind);
1986-03-26 15:11:02 +00:00
}
1986-06-04 09:01:48 +00:00
RemoveImports(pdf)
1986-04-03 17:41:26 +00:00
struct def **pdf;
{
/* Remove all imports from a definition module. This is
neccesary because the implementation module might import
them again.
*/
1986-04-12 02:21:24 +00:00
register struct def *df = *pdf;
1986-04-03 17:41:26 +00:00
while (df) {
if (df->df_kind == D_IMPORT) {
1986-06-04 09:01:48 +00:00
RemoveFromIdList(df);
1986-04-12 02:21:24 +00:00
*pdf = df->df_nextinscope;
free_def(df);
1986-04-03 17:41:26 +00:00
}
else {
1986-04-12 02:21:24 +00:00
pdf = &(df->df_nextinscope);
1986-04-03 17:41:26 +00:00
}
1986-04-12 02:21:24 +00:00
df = *pdf;
1986-04-03 17:41:26 +00:00
}
}
1986-06-04 09:01:48 +00:00
RemoveFromIdList(df)
1986-04-03 17:41:26 +00:00
struct def *df;
{
/* Remove definition "df" from the definition list
*/
register struct idf *id = df->df_idf;
register struct def *df1;
if (id->id_def == df) id->id_def = df->next;
else {
df1 = id->id_def;
while (df1->next != df) {
assert(df1->next != 0);
df1 = df1->next;
}
df1->next = df->next;
}
}
1986-04-15 17:51:53 +00:00
1986-04-21 17:27:06 +00:00
struct def *
DeclProc(type)
{
/* A procedure is declared, either in a definition or a program
1986-06-04 09:01:48 +00:00
module. Create a def structure for it (if neccessary).
Also create a name for it.
1986-04-21 17:27:06 +00:00
*/
register struct def *df;
1986-05-28 18:36:51 +00:00
extern char *sprint();
1986-06-06 02:22:09 +00:00
static int nmcount;
1986-04-21 17:27:06 +00:00
char buf[256];
assert(type & (D_PROCEDURE | D_PROCHEAD));
if (type == D_PROCHEAD) {
/* In a definition module
*/
df = define(dot.TOK_IDF, CurrentScope, type);
1986-06-04 09:01:48 +00:00
df->for_node = MkLeaf(Name, &dot);
1986-04-21 17:27:06 +00:00
sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text);
1986-06-06 02:22:09 +00:00
df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1));
1986-06-17 12:04:05 +00:00
if (CurrVis == Defined->mod_vis) C_exp(df->for_name);
1986-04-21 17:27:06 +00:00
}
else {
df = lookup(dot.TOK_IDF, CurrentScope);
if (df && df->df_kind == D_PROCHEAD) {
/* C_exp already generated when we saw the definition
in the definition module
*/
1986-04-22 22:36:16 +00:00
df->df_kind = D_PROCEDURE;
open_scope(OPENSCOPE);
CurrentScope->sc_name = df->for_name;
1986-04-28 18:06:58 +00:00
df->prc_vis = CurrVis;
1986-05-28 18:36:51 +00:00
DefInFront(df);
1986-04-21 17:27:06 +00:00
}
else {
df = define(dot.TOK_IDF, CurrentScope, type);
1986-04-22 22:36:16 +00:00
open_scope(OPENSCOPE);
1986-04-28 18:06:58 +00:00
df->prc_vis = CurrVis;
1986-06-06 02:22:09 +00:00
sprint(buf,"_%d_%s",++nmcount,df->df_idf->id_text);
CurrentScope->sc_name =
Salloc(buf, (unsigned)(strlen(buf)+1));
1986-04-21 17:27:06 +00:00
C_inp(buf);
}
}
return df;
}
1986-05-28 18:36:51 +00:00
AddModule(id)
struct idf *id;
{
/* Add the name of a module to the Module list. This list is
maintained to create the initialization routine of the
program/implementation module currently defined.
*/
static struct node *nd_end; /* to remember end of list */
register struct node *n;
extern struct node *Modules;
1986-06-04 09:01:48 +00:00
n = MkLeaf(Name, &dot);
1986-05-28 18:36:51 +00:00
n->nd_IDF = id;
n->nd_symb = IDENT;
if (nd_end) nd_end->next = n;
1986-06-04 09:01:48 +00:00
else Modules = n;
1986-05-28 18:36:51 +00:00
nd_end = n;
}
DefInFront(df)
register struct def *df;
{
/* Put definition "df" in front of the list of definitions
in its scope.
This is neccessary because in some cases the order in this
list is important.
*/
1986-06-04 09:01:48 +00:00
register struct def *df1 = df->df_scope->sc_def;
1986-05-28 18:36:51 +00:00
1986-06-04 09:01:48 +00:00
if (df1 != df) {
/* Definition "df" is not in front of the list
*/
1986-05-28 18:36:51 +00:00
while (df1 && df1->df_nextinscope != df) {
1986-06-04 09:01:48 +00:00
/* Find definition "df"
*/
1986-05-28 18:36:51 +00:00
df1 = df1->df_nextinscope;
}
1986-06-04 09:01:48 +00:00
if (df1) {
/* It already was in the list. Remove it
*/
df1->df_nextinscope = df->df_nextinscope;
}
/* Now put it in front
*/
1986-05-28 18:36:51 +00:00
df->df_nextinscope = df->df_scope->sc_def;
df->df_scope->sc_def = df;
}
}
1986-06-17 12:04:05 +00:00
struct def *
DefineLocalModule(id)
struct idf *id;
{
/* Create a definition for a local module. Also give it
a name to be used for code generation.
*/
register struct def *df = define(id, CurrentScope, D_MODULE);
register struct scope *sc;
static int modulecount = 0;
char buf[256];
extern char *sprint();
extern int proclevel;
sprint(buf, "_%d%s", ++modulecount, id->id_text);
if (!df->mod_vis) {
/* We never saw the name of this module before. Create a
scope for it.
*/
open_scope(CLOSEDSCOPE);
df->mod_vis = CurrVis;
}
CurrVis = df->mod_vis;
sc = CurrentScope;
sc->sc_level = proclevel;
sc->sc_definedby = df;
sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
/* Create a type for it
*/
1986-08-26 14:33:24 +00:00
df->df_type = standard_type(T_RECORD, 0, (arith) 0);
df->df_type->rec_scope = sc;
1986-06-17 12:04:05 +00:00
/* Generate code that indicates that the initialization procedure
for this module is local.
*/
C_inp(buf);
return df;
}
1986-04-15 17:51:53 +00:00
#ifdef DEBUG
PrDef(df)
register struct def *df;
{
1986-05-01 19:06:53 +00:00
print("n: %s, k: %d\n", df->df_idf->id_text, df->df_kind);
1986-04-15 17:51:53 +00:00
}
#endif DEBUG