/* symbol.c */

#include "picasm.h"

static char lookupstrtmp[10];

void cpsym(SYMBOL *dest, SYMBOL *src)
{
	dest->lexptr = src->lexptr;
	dest->token  = src->token;
	dest->type   = src->type;
	dest->value  = src->value;
}

SYMBOL *lookup(char *s)
{
	int p;
	SYMBOL *tmp;

	tmp = (SYMBOL *)0;

	for(p = lastentry; p > 0; p--)
		if (strcmp(symtable[p].lexptr, s) == 0)
			tmp = &symtable[p];

	return tmp;
}

char *lookupstr(int t)
{
	int	p;

	if (t > 1000)
		for(p = lastentry; p > 0; p--)
			if (symtable[p].token==t)
				return symtable[p].lexptr;
	if (t<128)
	{
		sprintf(lookupstrtmp,"%c",t);
		return lookupstrtmp;
	}

	switch(t)
	{
		case NUM:	return "Number";
		case ID:	return "ID";
		case DONE:	return "End of File";
		case STRING:	return "String";
		case PERIOD:	return ".";
		case COMMA:	return ",";
		case SEMICOLON:	return ";";
		case COLON:	return ":";
		case LPAREN:	return "(";
		case RPAREN:	return ")";
		case LBLOCK:	return "[";
		case RBLOCK:	return "]";
		case LBRACE:	return "{";
		case RBRACE:	return "}";
		case PLUS:	return "+";
		case INCSY:	return "++";
		case MINUS:	return "-";
		case DECSY:	return "--";
		case MUL:	return "*";
		case DIV:	return "/";
		case MOD:	return "%";
		case ASSIGN:	return "=";
		case SAME:	return "==";
		case GTR:	return ">";
		case GTREQ:	return ">=";
		case SHR:	return ">>";
		case LESS:	return "<";
		case LESSEQ:	return "<=";
		case SHL:	return "<<";
		case NOT:	return "!";
		case NOTEQ:	return "!=";
		case COMP:	return "~";
		case BAND:	return "&";
		case ANDSY:	return "&&";
		case BOR:	return "|";
		case ORSY:	return "||";
		case BXOR:	return "^";

		default:	return "Something(!)";
	}
}

void PrintCurrentSymbol()
{
	printf("Token is %d (%s)  ",current_symbol.token, lookupstr(current_symbol.token));

	switch(current_symbol.token)
	{
		case NUM:	printf("value = %d (0x%04x)\n", current_symbol.value, current_symbol.value);
				break;

		case ID:	printf("name is \'%s\'", current_symbol.lexptr);
				if (current_symbol.type == VALUE_DEF)
					printf("  value = %d (0x%04x)\n",current_symbol.value,current_symbol.value);
				else
					printf("\n");
				break;

		case STRING:	printf("string = \"%s\"\n", lexstrings[current_symbol.value]);
				break;

		default:	printf("type = %d, value = %d\n",current_symbol.type,current_symbol.value);
				break;
	}
}

void SaveSymbols(char *filename)
{
	int p;
	FILE *symfile;

	if ((symfile=fopen(filename,"w"))==NULL)
		printf("Could not open symbol file %s\n",filename);
	else
	{
		fprintf(symfile,"-------- Symbol Table Contains ---------\n");

		for(p = 0; p <= lastentry; p++)
			switch(symtable[p].type)
			{
				case KEYWORD:		break;

				case VALUE_DEF:		fprintf(symfile,"%s\t\t%04x\n",symtable[p].lexptr,symtable[p].value);
							break;

				case VALUE_UNDEF:	fprintf(symfile,"%s\t\tNot Initialised\n",symtable[p].lexptr);
							break;

				case MACRO_DEF:		fprintf(symfile,"%s\t\tMacro Definition\n",symtable[p].lexptr);
							break;

				default:		error("eh!","","","");
			}

		fprintf(symfile,"----------------------------------------\n");

		fclose(symfile);
	}
}

SYMBOL *insert(char *s,int tok,int type)	/* returns position of entry for s */
{
	int len;
	SYMBOL *ptr;

	/* check we have room */

	len = strlen(s);
	lastentry++;

	if (lastentry >= SYMMAX)
		error("symbol table full","","","");

	if (lastchar+len+1 >= STRMAX)
		error("lexemes array full","","","");


	/* enter this identifier into the table */

	ptr = &symtable[lastentry];

	ptr->token  = tok;
	ptr->lexptr = &lexemes[lastchar+1];
	ptr->type   = type;
	ptr->value  = 0;

	/* enter pattern into lex array */

	lastchar += len + 1;
	strcpy(symtable[lastentry].lexptr, s);

	return ptr;	/* return pointer to the symbol */
}

/* ... The End ... */
