ack/lang/m2/comp/def.c

100 lines
2 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 */
static char *RcsId = "$Header$";
#include <alloc.h>
#include <em_arith.h>
#include <em_label.h>
#include "Lpars.h"
#include "def.h"
#include "idf.h"
#include "main.h"
#include "scope.h"
1986-03-26 22:46:48 +00:00
#include "debug.h"
1986-03-26 15:11:02 +00:00
struct def *h_def; /* Pointer to free list of def structures */
1986-03-27 17:37:41 +00:00
static struct def illegal_def =
{0, 0, -20 /* Illegal scope */, D_ERROR};
struct def *ill_df = &illegal_def;
1986-03-26 15:11:02 +00:00
struct def *
define(id, scope, kind)
register struct idf *id;
{
/* 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-03-27 17:37:41 +00:00
DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope));
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-03-27 17:37:41 +00:00
( CurrentScope == scope
&&
scopeclosed(currscope)
&&
(df = lookup(id, 0)))
1986-03-26 17:53:13 +00:00
) {
1986-03-26 15:11:02 +00:00
switch(df->df_kind) {
case D_PROCHEAD:
if (kind == D_PROCEDURE) {
df->df_kind = D_PROCEDURE;
return df;
}
break;
case D_HIDDEN:
if (kind == D_TYPE && state == IMPLEMENTATION) {
df->df_kind = D_HTYPE;
return df;
}
break;
1986-03-27 17:37:41 +00:00
case D_ERROR:
1986-03-26 15:11:02 +00:00
case D_ISEXPORTED:
df->df_kind = kind;
return df;
}
1986-03-27 17:37:41 +00:00
error("identifier \"%s\" already declared", id->id_text);
1986-03-26 15:11:02 +00:00
return df;
}
df = new_def();
df->df_idf = id;
1986-03-27 17:37:41 +00:00
df->df_scope = scope;
1986-03-26 15:11:02 +00:00
df->df_kind = kind;
df->next = id->id_def;
id->id_def = df;
return df;
}
struct def *
lookup(id, scope)
register struct idf *id;
{
/* Look up a definition of an identifier in scope "scope".
Make the "def" list self-organizing.
Return a pointer to its "def" structure if it exists,
otherwise return 0.
*/
register struct def *df, *df1;
df1 = 0;
df = id->id_def;
1986-03-27 17:37:41 +00:00
DO_DEBUG(debug(4,"Looking for identifier %s in scope %d", id->id_text, scope));
1986-03-26 15:11:02 +00:00
while (df) {
1986-03-26 17:53:13 +00:00
if (df->df_scope == scope) {
1986-03-26 15:11:02 +00:00
if (df1) {
df1->next = df->next;
df->next = id->id_def;
id->id_def = df;
}
return df;
}
1986-03-26 22:46:48 +00:00
df1 = df;
1986-03-26 15:11:02 +00:00
df = df->next;
}
return 0;
}