// Inferno utils/cc/lexbody
// http://code.google.com/p/inferno-os/source/browse/utils/cc/lexbody
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/*
 * common code for all the assemblers
 */

void
pragpack(void)
{
	while(getnsc() != '\n')
		;
}

void
pragvararg(void)
{
	while(getnsc() != '\n')
		;
}

void
pragfpround(void)
{
	while(getnsc() != '\n')
		;
}

void
pragprofile(void)
{
	while(getnsc() != '\n')
		;
}

void
pragincomplete(void)
{
	while(getnsc() != '\n')
		;
}

void
gethunk(void)
{
	hunk = malloc(NHUNK);
	memset(hunk, 0, NHUNK);
	nhunk = NHUNK;
}

void*
alloc(long n)
{
	void *p;

	while((uintptr)hunk & MAXALIGN) {
		hunk++;
		nhunk--;
	}
	while(nhunk < n)
		gethunk();
	p = hunk;
	nhunk -= n;
	hunk += n;
	return p;
}

void*
allocn(void *p, long on, long n)
{
	void *q;

	q = (uchar*)p + on;
	if(q != hunk || nhunk < n) {
		while(nhunk < on+n)
			gethunk();
		memmove(hunk, p, on);
		p = hunk;
		hunk += on;
		nhunk -= on;
	}
	hunk += n;
	nhunk -= n;
	return p;
}

void
setinclude(char *p)
{
	int i;

	if(p == 0)
		return;
	for(i=1; i < ninclude; i++)
		if(strcmp(p, include[i]) == 0)
			return;

	if(ninclude >= nelem(include)) {
		yyerror("ninclude too small %d", nelem(include));
		exits("ninclude");
	}
	include[ninclude++] = p;
}

void
errorexit(void)
{

	if(outfile)
		remove(outfile);
	exits("error");
}

void
pushio(void)
{
	Io *i;

	i = iostack;
	if(i == I) {
		yyerror("botch in pushio");
		errorexit();
	}
	i->p = fi.p;
	i->c = fi.c;
}

void
newio(void)
{
	Io *i;
	static int pushdepth = 0;

	i = iofree;
	if(i == I) {
		pushdepth++;
		if(pushdepth > 1000) {
			yyerror("macro/io expansion too deep");
			errorexit();
		}
		i = alloc(sizeof(*i));
	} else
		iofree = i->link;
	i->c = 0;
	i->f = -1;
	ionext = i;
}

void
newfile(char *s, int f)
{
	Io *i;

	i = ionext;
	i->link = iostack;
	iostack = i;
	i->f = f;
	if(f < 0)
		i->f = open(s, 0);
	if(i->f < 0) {
		yyerror("%ca: %r: %s", thechar, s);
		errorexit();
	}
	fi.c = 0;
	linehist(s, 0);
}

Sym*
slookup(char *s)
{

	strcpy(symb, s);
	return lookup();
}

Sym*
lookup(void)
{
	Sym *s;
	long h;
	char *p;
	int c, l;

	h = 0;
	for(p=symb; c = *p; p++)
		h = h+h+h + c;
	l = (p - symb) + 1;
	if(h < 0)
		h = ~h;
	h %= NHASH;
	c = symb[0];
	for(s = hash[h]; s != S; s = s->link) {
		if(s->name[0] != c)
			continue;
		if(memcmp(s->name, symb, l) == 0)
			return s;
	}
	s = alloc(sizeof(*s));
	s->name = alloc(l);
	memmove(s->name, symb, l);

	s->link = hash[h];
	hash[h] = s;
	syminit(s);
	return s;
}

int
ISALPHA(int c)
{
	if(isalpha(c))
		return 1;
	if(c >= Runeself)
		return 1;
	return 0;
}

long
yylex(void)
{
	int c, c1;
	char *cp;
	Sym *s;

	c = peekc;
	if(c != IGN) {
		peekc = IGN;
		goto l1;
	}
l0:
	c = GETC();

l1:
	if(c == EOF) {
		peekc = EOF;
		return -1;
	}
	if(isspace(c)) {
		if(c == '\n') {
			lineno++;
			return ';';
		}
		goto l0;
	}
	if(ISALPHA(c))
		goto talph;
	if(isdigit(c))
		goto tnum;
	switch(c)
	{
	case '\n':
		lineno++;
		return ';';

	case '#':
		domacro();
		goto l0;

	case '.':
		c = GETC();
		if(ISALPHA(c)) {
			cp = symb;
			*cp++ = '.';
			goto aloop;
		}
		if(isdigit(c)) {
			cp = symb;
			*cp++ = '.';
			goto casedot;
		}
		peekc = c;
		return '.';

	talph:
	case '_':
	case '@':
		cp = symb;

	aloop:
		*cp++ = c;
		c = GETC();
		if(ISALPHA(c) || isdigit(c) || c == '_' || c == '$')
			goto aloop;
		*cp = 0;
		peekc = c;
		s = lookup();
		if(s->macro) {
			newio();
			cp = ionext->b;
			macexpand(s, cp);
			pushio();
			ionext->link = iostack;
			iostack = ionext;
			fi.p = cp;
			fi.c = strlen(cp);
			if(peekc != IGN) {
				cp[fi.c++] = peekc;
				cp[fi.c] = 0;
				peekc = IGN;
			}
			goto l0;
		}
		if(s->type == 0)
			s->type = LNAME;
		if(s->type == LNAME ||
		   s->type == LVAR ||
		   s->type == LLAB) {
			yylval.sym = s;
			return s->type;
		}
		yylval.lval = s->value;
		return s->type;

	tnum:
		cp = symb;
		if(c != '0')
			goto dc;
		*cp++ = c;
		c = GETC();
		c1 = 3;
		if(c == 'x' || c == 'X') {
			c1 = 4;
			c = GETC();
		} else
		if(c < '0' || c > '7')
			goto dc;
		yylval.lval = 0;
		for(;;) {
			if(c >= '0' && c <= '9') {
				if(c > '7' && c1 == 3)
					break;
				yylval.lval <<= c1;
				yylval.lval += c - '0';
				c = GETC();
				continue;
			}
			if(c1 == 3)
				break;
			if(c >= 'A' && c <= 'F')
				c += 'a' - 'A';
			if(c >= 'a' && c <= 'f') {
				yylval.lval <<= c1;
				yylval.lval += c - 'a' + 10;
				c = GETC();
				continue;
			}
			break;
		}
		goto ncu;

	dc:
		for(;;) {
			if(!isdigit(c))
				break;
			*cp++ = c;
			c = GETC();
		}
		if(c == '.')
			goto casedot;
		if(c == 'e' || c == 'E')
			goto casee;
		*cp = 0;
		if(sizeof(yylval.lval) == sizeof(vlong))
			yylval.lval = strtoll(symb, nil, 10);
		else
			yylval.lval = strtol(symb, nil, 10);

	ncu:
		while(c == 'U' || c == 'u' || c == 'l' || c == 'L')
			c = GETC();
		peekc = c;
		return LCONST;

	casedot:
		for(;;) {
			*cp++ = c;
			c = GETC();
			if(!isdigit(c))
				break;
		}
		if(c == 'e' || c == 'E')
			goto casee;
		goto caseout;

	casee:
		*cp++ = 'e';
		c = GETC();
		if(c == '+' || c == '-') {
			*cp++ = c;
			c = GETC();
		}
		while(isdigit(c)) {
			*cp++ = c;
			c = GETC();
		}

	caseout:
		*cp = 0;
		peekc = c;
		if(FPCHIP) {
			yylval.dval = atof(symb);
			return LFCONST;
		}
		yyerror("assembler cannot interpret fp constants");
		yylval.lval = 1L;
		return LCONST;

	case '"':
		memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
		cp = yylval.sval;
		c1 = 0;
		for(;;) {
			c = escchar('"');
			if(c == EOF)
				break;
			if(c1 < sizeof(yylval.sval))
				*cp++ = c;
			c1++;
		}
		if(c1 > sizeof(yylval.sval))
			yyerror("string constant too long");
		return LSCONST;

	case '\'':
		c = escchar('\'');
		if(c == EOF)
			c = '\'';
		if(escchar('\'') != EOF)
			yyerror("missing '");
		yylval.lval = c;
		return LCONST;

	case '/':
		c1 = GETC();
		if(c1 == '/') {
			for(;;) {
				c = GETC();
				if(c == '\n') {
					lineno++;
					goto l1;
				}
				if(c == EOF) {
					yyerror("eof in comment");
					errorexit();
				}
			}
		}
		if(c1 == '*') {
			for(;;) {
				c = GETC();
				while(c == '*') {
					c = GETC();
					if(c == '/')
						goto l0;
				}
				if(c == EOF) {
					yyerror("eof in comment");
					errorexit();
				}
				if(c == '\n')
					lineno++;
			}
		}
		break;

	default:
		return c;
	}
	peekc = c1;
	return c;
}

int
getc(void)
{
	int c;

	c = peekc;
	if(c != IGN) {
		peekc = IGN;
		return c;
	}
	c = GETC();
	if(c == '\n')
		lineno++;
	if(c == EOF) {
		yyerror("End of file");
		errorexit();
	}
	return c;
}

int
getnsc(void)
{
	int c;

	for(;;) {
		c = getc();
		if(!isspace(c) || c == '\n')
			return c;
	}
}

void
unget(int c)
{

	peekc = c;
	if(c == '\n')
		lineno--;
}

int
escchar(int e)
{
	int c, l;

loop:
	c = getc();
	if(c == '\n') {
		yyerror("newline in string");
		return EOF;
	}
	if(c != '\\') {
		if(c == e)
			return EOF;
		return c;
	}
	c = getc();
	if(c >= '0' && c <= '7') {
		l = c - '0';
		c = getc();
		if(c >= '0' && c <= '7') {
			l = l*8 + c-'0';
			c = getc();
			if(c >= '0' && c <= '7') {
				l = l*8 + c-'0';
				return l;
			}
		}
		peekc = c;
		return l;
	}
	switch(c)
	{
	case '\n':	goto loop;
	case 'n':	return '\n';
	case 't':	return '\t';
	case 'b':	return '\b';
	case 'r':	return '\r';
	case 'f':	return '\f';
	case 'a':	return 0x07;
	case 'v':	return 0x0b;
	case 'z':	return 0x00;
	}
	return c;
}

void
pinit(char *f)
{
	int i;
	Sym *s;

	lineno = 1;
	newio();
	newfile(f, -1);
	pc = 0;
	peekc = IGN;
	sym = 1;
	for(i=0; i<NSYM; i++) {
		h[i].type = 0;
		h[i].sym = S;
	}
	for(i=0; i<NHASH; i++)
		for(s = hash[i]; s != S; s = s->link)
			s->macro = 0;
}

int
filbuf(void)
{
	Io *i;

loop:
	i = iostack;
	if(i == I)
		return EOF;
	if(i->f < 0)
		goto pop;
	fi.c = read(i->f, i->b, BUFSIZ) - 1;
	if(fi.c < 0) {
		close(i->f);
		linehist(0, 0);
		goto pop;
	}
	fi.p = i->b + 1;
	return i->b[0];

pop:
	iostack = i->link;
	i->link = iofree;
	iofree = i;
	i = iostack;
	if(i == I)
		return EOF;
	fi.p = i->p;
	fi.c = i->c;
	if(--fi.c < 0)
		goto loop;
	return *fi.p++;
}

void
yyerror(char *a, ...)
{
	char buf[200];
	va_list arg;

	/*
	 * hack to intercept message from yaccpar
	 */
	if(strcmp(a, "syntax error") == 0) {
		yyerror("syntax error, last name: %s", symb);
		return;
	}
	prfile(lineno);
	va_start(arg, a);
	vseprint(buf, buf+sizeof(buf), a, arg);
	va_end(arg);
	print("%s\n", buf);
	nerrors++;
	if(nerrors > 10) {
		print("too many errors\n");
		errorexit();
	}
}

void
prfile(long l)
{
	int i, n;
	Hist a[HISTSZ], *h;
	long d;

	n = 0;
	for(h = hist; h != H; h = h->link) {
		if(l < h->line)
			break;
		if(h->name) {
			if(h->offset == 0) {
				if(n >= 0 && n < HISTSZ)
					a[n] = *h;
				n++;
				continue;
			}
			if(n > 0 && n < HISTSZ)
				if(a[n-1].offset == 0) {
					a[n] = *h;
					n++;
				} else
					a[n-1] = *h;
			continue;
		}
		n--;
		if(n >= 0 && n < HISTSZ) {
			d = h->line - a[n].line;
			for(i=0; i<n; i++)
				a[i].line += d;
		}
	}
	if(n > HISTSZ)
		n = HISTSZ;
	for(i=0; i<n; i++)
		print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
}

void
ieeedtod(Ieee *ieee, double native)
{
	double fr, ho, f;
	int exp;

	if(native < 0) {
		ieeedtod(ieee, -native);
		ieee->h |= 0x80000000L;
		return;
	}
	if(native == 0) {
		ieee->l = 0;
		ieee->h = 0;
		return;
	}
	fr = frexp(native, &exp);
	f = 2097152L;		/* shouldnt use fp constants here */
	fr = modf(fr*f, &ho);
	ieee->h = ho;
	ieee->h &= 0xfffffL;
	ieee->h |= (exp+1022L) << 20;
	f = 65536L;
	fr = modf(fr*f, &ho);
	ieee->l = ho;
	ieee->l <<= 16;
	ieee->l |= (long)(fr*f);
}
