CCF's Symbol Table

Currently I keep all the defined names in one doubly-linked list. If this proves to be a bottleneck it can be replaced with something more fancy without upsetting the rest of the program.

#include	<ctype.h>
#include	<stdio.h>
#include	<string.h>

#include	"iofns.h"
#include	"memfns.h"
#include	"syms.h"


/* symbol table entry */

typedef struct Symbol
{
  char	*name;
  long	 value;

  struct Symbol	*next;
  struct Symbol	*prev;
} Symbol;


static	Symbol	*base, *last;

static Symbol *find_entry (char *name)
{
  Symbol *p;
  for (p = base; p; p = p -> next)
    if (strcmp (p -> name, name) == 0)
      break;
  return (p);
}


int IsDefined (char *name)
{
  return (!! find_entry (name));
}

long GetValue (char *name)
{
  Symbol *p = find_entry (name);
  if (! p)
    FatalPrintf (1, "uninitialised variable (%.100s) used", name);
  return (p -> value);
}

void Unset (char *name)
{
  Symbol *p = find_entry (name);
  if (p)
  {
    my_free (p -> name);
    p -> name = NULL;
    if (p -> next)
      p -> next -> prev = p -> prev;
    else
      last = p -> prev;
    if (p -> prev)
      p -> prev -> next = p -> next;
    else
      base = p -> next;
  }
}

void SetValue (char *name, long value)
{
  Symbol *p = find_entry (name);
  if (! p)
  {
    p = my_malloc (sizeof (Symbol));
    p -> name = my_malloc (1 + strlen (name));
    strcpy (p -> name, name);
    p -> next = base;
    if (base)
      base -> prev = p;
    p -> prev = NULL;
    base = p;
  }
  p -> value = value;
}

void ListSymbols (void)
{
  Symbol *p;
  for (p = base; p; p = p -> next)
    fprintf (stderr, "%s: %ld\n", p -> name, p -> value);
}