#include "e.h"
#include "y.tab.h"

tbl	*keytbl[TBLSIZE];	/* key words */
tbl	*restbl[TBLSIZE];	/* reserved words */
tbl	*deftbl[TBLSIZE];	/* user-defined names */

struct keyword {
	char	*key;
	int	keyval;
} keyword[]	={
	"sub", 		SUB, 
	"sup", 		SUP, 
	".EN", 		DOTEN,
	".EQ",		DOTEQ, 
	"from", 	FROM, 
	"to", 		TO, 
	"sum", 		SUM, 
	"hat", 		HAT, 
	"vec", 		VEC, 
	"dyad", 	DYAD, 
	"dot", 		DOT, 
	"dotdot", 	DOTDOT, 
	"bar", 		BAR,
	"lowbar",	LOWBAR,
	"highbar",	HIGHBAR, 
	"tilde", 	TILDE, 
	"utilde", 	UTILDE, 
	"under", 	UNDER, 
	"prod", 	PROD, 
	"int", 		INT, 
	"integral", 	INT, 
	"union", 	UNION, 
	"inter", 	INTER, 
	"matrix", 	MATRIX, 
	"col", 		COL, 
	"lcol", 	LCOL, 
	"ccol", 	CCOL, 
	"rcol", 	RCOL, 
	"pile", 	COL,	/* synonyms ... */ 
	"lpile", 	LCOL, 
	"cpile", 	CCOL, 
	"rpile", 	RCOL, 
	"over", 	OVER, 
	"sqrt", 	SQRT, 
	"above", 	ABOVE, 
	"size", 	SIZE, 
	"font", 	FONT, 
	"fat", 		FAT, 
	"roman", 	ROMAN, 
	"italic", 	ITALIC, 
	"bold", 	BOLD, 
	"left", 	LEFT, 
	"right", 	RIGHT, 
	"delim", 	DELIM, 
	"define", 	DEFINE, 
	"tdefine", 	DEFINE, 
	"ndefine", 	NDEFINE, 
	"ifdef",	IFDEF,
	"gsize", 	GSIZE, 
	".gsize", 	GSIZE, 
	"gfont", 	GFONT, 
	"include", 	INCLUDE, 
	"copy", 	INCLUDE, 
	"space",	SPACE,
	"up", 		UP, 
	"down", 	DOWN, 
	"fwd", 		FWD, 
	"back", 	BACK, 
	"mark", 	MARK, 
	"lineup", 	LINEUP, 
	0, 	0
};

struct resword {
	char	*res;
	char	*resval;
} resword[]	={
	">=",		"\\(>=",
	"<=",		"\\(<=",
	"==",		"\\(==",
	"!=",		"\\(!=",
	"+-",		"\\(+-",
	"->",		"\\(->",
	"<-",		"\\(<-",
	"inf",		"\\(if",
	"infinity",	"\\(if",
	"partial",	"\\(pd",
	"half",		"\\f1\\(12\\fP",
	"prime",	"\\f1\\v'.5m'\\s+3\\(fm\\s-3\\v'-.5m'\\fP",
	"dollar",	"\\f1$\\fP",
	"nothing",	"",
	"times",	"\\(mu",
	"del",		"\\(gr",
	"grad",		"\\(gr",
	"approx",	"\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'",
	"cdot",		"\\v'-.3m'.\\v'.3m'",
	"...",		"\\v'-.25m'\\ .\\ .\\ .\\ \\v'.25m'",
	",...,",	"\\f1,\\fP\\ .\\ .\\ .\\ \\f1,\\fP\\|",
	"alpha",	"\\(*a",
	"beta",		"\\(*b",
	"gamma",	"\\(*g",
	"GAMMA",	"\\(*G",
	"delta",	"\\(*d",
	"DELTA",	"\\(*D",
	"epsilon",	"\\(*e",
	"EPSILON",	"\\f1E\\fP",
	"omega",	"\\(*w",
	"OMEGA",	"\\(*W",
	"lambda",	"\\(*l",
	"LAMBDA",	"\\(*L",
	"mu",		"\\(*m",
	"nu",		"\\(*n",
	"theta",	"\\(*h",
	"THETA",	"\\(*H",
	"phi",		"\\(*f",
	"PHI",		"\\(*F",
	"pi",		"\\(*p",
	"PI",		"\\(*P",
	"sigma",	"\\(*s",
	"SIGMA",	"\\(*S",
	"xi",		"\\(*c",
	"XI",		"\\(*C",
	"zeta",		"\\(*z",
	"iota",		"\\(*i",
	"eta",		"\\(*y",
	"kappa",	"\\(*k",
	"rho",		"\\(*r",
	"tau",		"\\(*t",
	"omicron",	"\\(*o",
	"upsilon",	"\\(*u",
	"UPSILON",	"\\(*U",
	"psi",		"\\(*q",
	"PSI",		"\\(*Q",
	"chi",		"\\(*x",
	"and",		"\\f1and\\fP",
	"for",		"\\f1for\\fP",
	"if",		"\\f1if\\fP",
	"Re",		"\\f1Re\\fP",
	"Im",		"\\f1Im\\fP",
	"sin",		"\\f1sin\\fP",
	"cos",		"\\f1cos\\fP",
	"tan",		"\\f1tan\\fP",
	"arc",		"\\f1arc\\fP",
	"sinh",		"\\f1sinh\\fP",
	"coth",		"\\f1coth\\fP",
	"tanh",		"\\f1tanh\\fP",
	"cosh",		"\\f1cosh\\fP",
	"lim",		"\\f1lim\\fP",
	"log",		"\\f1log\\fP",
	"ln",		"\\f1ln\\fP",
	"max",		"\\f1max\\fP",
	"min",		"\\f1min\\fP",
	"exp",		"\\f1exp\\fP",
	"det",		"\\f1det\\fP",
	0,	0
};

#ifndef UNANSI
int hash(char *s)
#else /* UNANSI */
int hash(s)
	char *s;
#endif /* UNANSI */
{
	register unsigned int h;

	for (h = 0; *s != '\0'; )
		h += *s++;
	h %= TBLSIZE;
	return h;
}

#ifndef UNANSI
tbl *lookup(tbl **tblp, char *name)	/* find name in tbl */
#else /* UNANSI */
tbl *lookup(tblp, name)	/* find name in tbl */
	tbl **tblp; char *name;
#endif /* UNANSI */
{
	register tbl *p;

	for (p = tblp[hash(name)]; p != NULL; p = p->next)
		if (strcmp(name, p->name) == 0)
			return(p);
	return(NULL);
}

#ifndef UNANSI
void install(tbl **tblp, char *name, char *cval, int ival)	/* install name, vals in tblp */
#else /* UNANSI */
void install(tblp, name, cval, ival)	/* install name, vals in tblp */
	tbl **tblp; char *name; char *cval; int ival;
#endif /* UNANSI */
{
	register tbl *p;
	int h;

	if ((p = lookup(tblp, name)) == NULL) {
		p = (tbl *) malloc(sizeof(tbl));
		if (p == NULL)
			ERROR "out of space in install" FATAL;
		h = hash(name);	/* bad visibility here */
		p->name = name;
		p->next = tblp[h];
		tblp[h] = p;
	}
	p->cval = cval;
	p->ival = ival;
}

#ifndef UNANSI
void init_tbl(void)	/* initialize tables */
#else /* UNANSI */
void init_tbl()	/* initialize tables */
#endif /* UNANSI */
{
	int i;
#ifndef UNANSI
	extern int init_tune(void);
#else /* UNANSI */
	extern int init_tune();
#endif /* UNANSI */

	for (i = 0; keyword[i].key != NULL; i++)
		install(keytbl, keyword[i].key, (char *) 0, keyword[i].keyval);
	for (i = 0; resword[i].res != NULL; i++)
		install(restbl, resword[i].res, resword[i].resval, 0);
	init_tune();	/* tuning table done in tuning.c */
}
