2024-10-04 15:26:19 +03:00
|
|
|
/*********************************************************************/
|
|
|
|
|
/* pC++/Sage++ Copyright (C) 1993 */
|
|
|
|
|
/* Indiana University University of Oregon University of Rennes */
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* hash.c -- hash table routines
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#include "compatible.h"
|
|
|
|
|
#ifdef SYS5
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <strings.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
|
#include "symb.h"
|
|
|
|
|
#include "defines.h"
|
|
|
|
|
#include "bif.h"
|
|
|
|
|
#include "extern.h"
|
|
|
|
|
|
|
|
|
|
extern int parstate;
|
|
|
|
|
extern PTR_BFND cur_bfnd, pred_bfnd, global_bfnd;
|
|
|
|
|
extern PTR_TYPE vartype, global_default, impltype[];
|
|
|
|
|
extern void make_prog_header();
|
|
|
|
|
PTR_TYPE install_array();
|
|
|
|
|
PTR_LLND make_llnd();
|
|
|
|
|
PTR_SYMB make_symb();
|
|
|
|
|
char *chkalloc();
|
|
|
|
|
void free();
|
|
|
|
|
void errstr();
|
|
|
|
|
|
|
|
|
|
PTR_HASH hash_table[hashMax];
|
|
|
|
|
|
|
|
|
|
#ifdef __SPF
|
|
|
|
|
extern void removeFromCollection(void *pointer);
|
|
|
|
|
#endif
|
|
|
|
|
/*
|
|
|
|
|
* init_hash -- initialize the hash table
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
init_hash()
|
|
|
|
|
{
|
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < hashMax; i++)
|
|
|
|
|
hash_table[i] = HSNULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Hash(string) -- compute hash value of string.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
hash(string)
|
|
|
|
|
register char *string;
|
|
|
|
|
{
|
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; *string;)
|
|
|
|
|
i += *string++;
|
|
|
|
|
return (i % hashMax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* look_up(string) -- lookup string in the hash table and
|
|
|
|
|
* install it if not there
|
|
|
|
|
*/
|
|
|
|
|
PTR_HASH
|
|
|
|
|
look_up(string, decl_type)
|
|
|
|
|
register char *string;
|
|
|
|
|
int decl_type;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
register PTR_HASH entry;
|
|
|
|
|
PTR_BFND cur_scope(), p;
|
|
|
|
|
|
|
|
|
|
i = hash(string);
|
|
|
|
|
p = cur_scope();
|
|
|
|
|
for (entry = hash_table[i]; entry; entry = entry->next_entry) {
|
|
|
|
|
if (!strcmp(string, entry->ident) && (entry->id_attr)) {
|
|
|
|
|
if ((entry->id_attr->scope == p) ||
|
|
|
|
|
((entry->id_attr->variant==FUNCTION_NAME) &&
|
|
|
|
|
(p->variant==FUNC_HEDR) &&
|
|
|
|
|
(p->entry.Template.symbol==entry->id_attr)))
|
|
|
|
|
return (entry);
|
|
|
|
|
if (decl_type == SOFT) {
|
|
|
|
|
for (p=cur_scope(); NEW_SCOPE(p); p = p->control_parent) {
|
|
|
|
|
if (entry->id_attr->scope == p)
|
|
|
|
|
return (entry);
|
|
|
|
|
}
|
|
|
|
|
if (entry->id_attr->scope == p)
|
|
|
|
|
return (entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
entry = (struct hash_entry *) chkalloc(sizeof(struct hash_entry));
|
|
|
|
|
entry->ident = copys(string);
|
|
|
|
|
entry->next_entry = hash_table[i];
|
|
|
|
|
hash_table[i] = entry;
|
|
|
|
|
return (entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PTR_HASH
|
|
|
|
|
correct_symtab(h, type)
|
|
|
|
|
PTR_HASH h;
|
|
|
|
|
int type;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
PTR_HASH entry;
|
|
|
|
|
|
|
|
|
|
i = hash(h->ident);
|
|
|
|
|
for (entry = hash_table[i]; entry; entry = entry->next_entry) {
|
|
|
|
|
if (!strcmp(h->ident, entry->ident)
|
|
|
|
|
&& ( !(entry->id_attr)
|
|
|
|
|
||(entry->id_attr->variant==type))
|
|
|
|
|
&& (h != entry))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!entry) return h;
|
|
|
|
|
if (hash_table[i] != h) {
|
|
|
|
|
fprintf (stderr, "Bug in correct_symtab\n");
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
|
hash_table[i] = hash_table[i]->next_entry;
|
|
|
|
|
#ifdef __SPF
|
|
|
|
|
removeFromCollection(h);
|
|
|
|
|
#endif
|
|
|
|
|
free((char *)h);
|
|
|
|
|
return hash_table[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Checks whether the "name" is installed and installs as a SOFT
|
|
|
|
|
* entry if not.
|
|
|
|
|
*/
|
|
|
|
|
PTR_LLND
|
|
|
|
|
check_and_install(h, d, ndim)
|
|
|
|
|
PTR_HASH h;
|
|
|
|
|
PTR_LLND d;
|
|
|
|
|
int ndim;
|
|
|
|
|
{
|
|
|
|
|
PTR_BFND cur_scope();
|
|
|
|
|
PTR_SYMB install_entry();
|
|
|
|
|
PTR_TYPE p = NULL;
|
|
|
|
|
PTR_SYMB s;
|
|
|
|
|
PTR_LLND r;
|
|
|
|
|
void set_type(), err();
|
|
|
|
|
|
|
|
|
|
/* Check if the variable is already declared */
|
|
|
|
|
if ((s = h->id_attr) && (s->scope == cur_scope()) && s->type) {
|
|
|
|
|
if (d && s->type->variant != T_ARRAY) {
|
|
|
|
|
p = install_array(d, s->type, ndim);
|
|
|
|
|
s->type = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (h->id_attr && h->id_attr->type)
|
|
|
|
|
p = h->id_attr->type;
|
|
|
|
|
else if (!undeftype)
|
|
|
|
|
p = impltype[*h->ident - 'a'];
|
|
|
|
|
else
|
|
|
|
|
err("Variable type unknown",327);
|
|
|
|
|
if (d)
|
|
|
|
|
p = install_array(d, p, ndim);
|
|
|
|
|
s = install_entry(h, SOFT);
|
|
|
|
|
set_type(s, p, LOCAL);
|
|
|
|
|
}
|
|
|
|
|
if (d) {
|
|
|
|
|
r = p->entry.ar_decl.ranges
|
|
|
|
|
= make_llnd(fi,ARRAY_REF, d, LLNULL, s);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
r = make_llnd(fi,VAR_REF, LLNULL, LLNULL, s);
|
|
|
|
|
return make_llnd(fi,EXPR_LIST, r, LLNULL, SMNULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* install_entry takes a pointer to a hash entry and
|
|
|
|
|
* makes another symbol table entry for the same id
|
|
|
|
|
*/
|
|
|
|
|
PTR_SYMB
|
|
|
|
|
install_entry(entry, decl_type)
|
|
|
|
|
PTR_HASH entry;
|
|
|
|
|
int decl_type;
|
|
|
|
|
{
|
|
|
|
|
register PTR_SYMB symb_ptr;
|
|
|
|
|
PTR_BFND cur_scope();
|
|
|
|
|
PTR_BFND p;
|
|
|
|
|
void err();
|
|
|
|
|
|
|
|
|
|
if (decl_type == HARD && entry->id_attr &&
|
|
|
|
|
entry->id_attr->scope != cur_scope())
|
|
|
|
|
entry = look_up(entry->ident, HARD);
|
|
|
|
|
if ((entry->id_attr) && ((entry->id_attr->scope == cur_scope()) ||
|
|
|
|
|
((entry->id_attr->variant==FUNCTION_NAME) &&
|
|
|
|
|
(entry->id_attr->scope->variant==FUNC_HEDR))))
|
|
|
|
|
{
|
|
|
|
|
if (entry->id_attr->decl == SOFT) {
|
|
|
|
|
entry->id_attr->decl = decl_type;
|
|
|
|
|
return(entry->id_attr);
|
|
|
|
|
}
|
|
|
|
|
if (decl_type == SOFT)
|
|
|
|
|
return(entry->id_attr);
|
|
|
|
|
/* else */
|
|
|
|
|
errstr("Redeclaration of identifier: %s",entry->id_attr->ident,328);
|
|
|
|
|
/*(void)fprintf(stderr, "id: %s\n", entry->id_attr->ident);*/
|
|
|
|
|
return (SMNULL);
|
|
|
|
|
}
|
|
|
|
|
symb_ptr = make_symb(fi,DEFAULT, entry->ident);
|
|
|
|
|
for (p=cur_scope();
|
|
|
|
|
NEW_SCOPE(p) && (decl_type==SOFT);
|
|
|
|
|
p = p->control_parent)
|
|
|
|
|
;
|
|
|
|
|
symb_ptr->scope = p;
|
|
|
|
|
symb_ptr->outer = entry->id_attr;
|
|
|
|
|
symb_ptr->parent = entry;
|
|
|
|
|
symb_ptr->decl = decl_type;
|
|
|
|
|
entry->id_attr = symb_ptr;
|
|
|
|
|
symb_ptr->id_list = SMNULL;
|
|
|
|
|
return (symb_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PTR_SYMB
|
|
|
|
|
get_proc_symbol(entry)
|
|
|
|
|
PTR_HASH entry;
|
|
|
|
|
{
|
|
|
|
|
register PTR_SYMB symb_ptr;
|
|
|
|
|
PTR_BFND cur_scope();
|
|
|
|
|
|
|
|
|
|
symb_ptr = make_symb(fi, PROCEDURE_NAME, entry->ident);
|
|
|
|
|
symb_ptr->scope = global_bfnd;
|
|
|
|
|
symb_ptr->outer = entry->id_attr;
|
|
|
|
|
symb_ptr->parent = entry;
|
|
|
|
|
entry->id_attr = symb_ptr;
|
|
|
|
|
return (symb_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
PTR_BFND
|
|
|
|
|
cur_scope()
|
|
|
|
|
{
|
|
|
|
|
register PTR_BFND p;
|
|
|
|
|
*/
|
|
|
|
|
/* Takes cares of main program unit begining without a PROGRAM
|
|
|
|
|
statement. After rewrite of statement processing has been done,
|
|
|
|
|
strengthen ( weaken? ) the test.
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
if ((pred_bfnd->variant == GLOBAL) && (parstate == OUTSIDE))
|
|
|
|
|
{
|
|
|
|
|
make_prog_header();
|
|
|
|
|
return (pred_bfnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (p = pred_bfnd;
|
|
|
|
|
(p->variant != PROG_HEDR) &&
|
|
|
|
|
(p->variant != PROC_HEDR) &&
|
|
|
|
|
(p->variant != PROS_HEDR) &&
|
|
|
|
|
(p->variant != FUNC_HEDR) &&
|
|
|
|
|
(p->variant != BLOCK_DATA) &&
|
|
|
|
|
(p->variant != FORALL_NODE) &&
|
|
|
|
|
(p->variant != GLOBAL) &&
|
|
|
|
|
(p->variant != CDOALL_NODE) &&
|
|
|
|
|
(p->variant != SDOALL_NODE) &&
|
|
|
|
|
(p->variant != DOACROSS_NODE) &&
|
|
|
|
|
(p->variant != STRUCT_DECL);
|
|
|
|
|
p = p->control_parent);
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
return (p);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|