scyther/src/symbols.c

166 lines
2.6 KiB
C
Raw Normal View History

2004-04-23 11:58:43 +01:00
#include <stdio.h>
#include <stdlib.h>
#include "symbols.h"
#include "memory.h"
/*
Symbol processor.
Stores symbols for the lexical scanner. Can later print them.
Implementation uses a hashtable, the size of which is defined in
symbols.h.
*/
extern int yylineno;
/* global declarations */
2004-05-15 16:45:08 +01:00
//! Symbol hash table.
2004-04-23 11:58:43 +01:00
Symbol symbtab[HASHSIZE];
2004-05-15 16:45:08 +01:00
//! List of available (freed) symbol blocks.
2004-04-23 11:58:43 +01:00
Symbol symb_list;
2004-05-15 16:45:08 +01:00
//! List of all allocated symbol blocks.
2004-04-23 11:58:43 +01:00
Symbol symb_alloc;
/* main code */
2004-05-15 16:45:08 +01:00
//! Open symbols code.
2004-04-23 11:58:43 +01:00
void
symbolsInit (void)
{
int i;
for (i = 0; i < HASHSIZE; i++)
symbtab[i] = NULL;
symb_list = NULL;
symb_alloc = NULL;
}
2004-05-15 16:45:08 +01:00
//! Close symbols code.
2004-04-23 11:58:43 +01:00
void
symbolsDone (void)
{
Symbol s;
while (symb_alloc != NULL)
{
s = symb_alloc;
symb_alloc = s->allocnext;
memFree (s, sizeof (struct symbol));
}
}
2004-05-15 16:45:08 +01:00
//! Create a memory block for a symbol.
/**
* Internal memory management is used.
*@return A pointer to a memory block of size struct.
*/
2004-04-23 11:58:43 +01:00
Symbol
get_symb (void)
{
Symbol t;
if (symb_list != NULL)
{
t = symb_list;
symb_list = symb_list->next;
}
else
{
t = (Symbol) memAlloc (sizeof (struct symbol));
t->allocnext = symb_alloc;
symb_alloc = t;
}
return t;
}
2004-05-15 16:45:08 +01:00
//! Declare a symbol to be freed.
2004-04-23 11:58:43 +01:00
void
free_symb (Symbol s)
{
if (s == NULL)
return;
s->next = symb_list;
symb_list = s;
}
2004-05-15 16:45:08 +01:00
//! Return the index in the hash table for the string.
2004-04-23 11:58:43 +01:00
int
hash (char *s)
{
int hv = 0;
int i;
for (i = 0; s[i] != EOS; i++)
{
int v = (hv >> 28) ^ (s[i] & 0xf);
hv = (hv << 4) | v;
}
hv = hv & 0x7fffffff;
return hv % HASHSIZE;
}
2004-05-15 16:45:08 +01:00
//! Insert a string into the hash table.
2004-04-23 11:58:43 +01:00
void
insert (Symbol s)
{
if (s == NULL)
return; /* illegal insertion of empty stuff */
int hv = hash (s->text);
s->next = symbtab[hv];
symbtab[hv] = s;
}
2004-05-15 16:45:08 +01:00
//! Find a string in the hash table.
2004-04-23 11:58:43 +01:00
Symbol
lookup (char *s)
{
if (s == NULL)
return NULL;
int hv = hash (s);
Symbol t = symbtab[hv];
while (t != NULL)
{
if (strcmp (t->text, s) == 0)
break;
else
t = t->next;
}
return t;
}
2004-05-15 16:45:08 +01:00
//! Print a symbol.
2004-04-23 11:58:43 +01:00
void
symbolPrint (Symbol s)
{
if (s == NULL)
return;
/* TODO maybe action depending on type? */
printf ("%s", s->text);
}
2004-05-15 16:45:08 +01:00
//! Insert a string into the symbol table, if it wasn't there yet.
/**
* Also sets line numbers and type.
*\sa T_SYSCONST
*/
2004-04-23 11:58:43 +01:00
Symbol
symbolSysConst (char *str)
{
Symbol symb;
symb = lookup (str);
if (symb == NULL)
{
symb = get_symb ();
symb->lineno = yylineno;
symb->type = T_SYSCONST;
symb->text = str;
}
return symb;
}