Files
SAPFOR/projects/dvm/fdvm/trunk/parser/hash.c
2025-03-25 21:09:12 +03:00

287 lines
6.1 KiB
C

/*********************************************************************/
/* 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);
}
*/