#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "struct.h"

/*
 *	System Name binder - basically a rip off of vocab.c at the moment
 */

struct Word *NameList=NULL;

extern char *emalloc();

void AddName(x,t,v)
char *x;
tag t;
int v;
{
	extern char *estralloc();
	struct Word *nwd=(struct Word *)emalloc(sizeof(struct Word));
	nwd->wd_Text=estralloc(x);
	nwd->wd_Type=v;
	nwd->wd_Code=t;
	nwd->wd_Next=NameList;
	NameList=nwd;
}

struct Word *FindName(v,t)
int t;
char *v;
{
	struct Word *w=NameList;
	while(w)
	{
/*		printf("Trying '%s' %d\n",w->wd_Text,w->wd_Type);	*/
		if((t==w->wd_Type||t==0)&&(strcmp(v,w->wd_Text)==0))
			return(w);
		w=w->wd_Next;
	}
	return(NULL);
}

char *TrueName(x)
tag x;
{
	struct Word *w=NameList;
	while(w)
	{
		if(x==VAL(w->wd_Code)&&w->wd_Type!=2)
			return(w->wd_Text);
		w=w->wd_Next;
	}
	return(NULL);
}

char *MsgName(x)
int x;
{
	struct Word *w=NameList;
	while(w)
	{
		if(x==VAL(w->wd_Code)&&w->wd_Type==2)
			return(w->wd_Text);
		w=w->wd_Next;
	}
	return(NULL);
}


void DelName(wp)
struct Word *wp;
{
	struct Word *w=NameList;
	if(w==wp)
	{
		NameList=w->wd_Next;
		free(wp->wd_Text);
		free(wp);
		return;
	}
	while(w->wd_Next!=NULL)
	{
		if(w->wd_Next==wp)
		{
			w->wd_Next=w->wd_Next->wd_Next;
			free(wp->wd_Text);
			free(wp);
			return;
		}
		w=w->wd_Next;
	}
	fprintf(stderr,"DelName:Trash pointer\n");
	log_error("[PANIC]: DelName - trash pointer\n");
	panic();
}

/* ---- Resolution Of Forward Names ---- */

struct Resolve
{
	tag re_Item;
	short re_Offset;
	char *re_Dest;
	struct Resolve *re_Next;
};

static struct Resolve *ResList=NULL;

void Push_Resolution(i,o,x)
tag i;
int o;
char *x;
{
	extern char *estralloc(),*emalloc();
	struct Resolve *r=(struct Resolve *)emalloc(sizeof(struct Resolve));
	r->re_Item=i;
	r->re_Offset=o;
	r->re_Dest=estralloc(x);
	r->re_Next=ResList;
	ResList=r;
}

void ResolveReferences()
{
	struct Resolve *r=ResList;
	struct Resolve *n;
	struct Word *w;
	while(r)
	{
		n=r->re_Next;
		w=FindName(r->re_Dest,0);
		if(w)
		{
			OBJECT(r->re_Item)->ob_Data[r->re_Offset]=w->wd_Code;
			if(r->re_Offset==1)
				Tree_Link(r->re_Item,LOC(r->re_Item));
		}
		else
		{
			ELine();
			printf("[ERROR]: Unresolved symbol '%s' used in '%s'.\n",
				r->re_Dest,NAME(r->re_Item));
			exit(0);
		}
		free(r->re_Dest);
		free(r);
		r=n;
	}
}