// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include	"go.h"
#include	"y.tab.h"

void
dodclvar(Node *n, Node *t)
{

loop:
	if(n == N)
		return;

	if(n->op == OLIST) {
		dodclvar(n->left, t);
		n = n->right;
		goto loop;
	}

	addvar(n, t, dclcontext);
}

void
dodcltype(Node *n, Node *t)
{

loop:
	if(n == N)
		return;

	if(n->op == OLIST) {
		dodcltype(n->left, t);
		n = n->right;
		goto loop;
	}

	addtyp(n, t, dclcontext);
}

void
dodclconst(Node *n, Node *e)
{
	Sym *s;
	Dcl *r, *d;

loop:
	if(n == N)
		return;
	if(n->op == OLIST) {
		dodclconst(n->left, e);
		n = n->right;
		goto loop;
	}

	if(n->op != ONAME)
		fatal("dodclconst: not a name");

	if(e->op != OLITERAL) {
		yyerror("expression must be a constant");
		goto loop;
	}
	s = n->sym;

	s->oconst = e;
	s->lexical = LACONST;

	r = autodcl;
	if(dclcontext == PEXTERN)
		r = externdcl;

	d = dcl();
	d->dsym = s;
	d->dnode = e;
	d->op = OCONST;

	r->back->forw = d;
	r->back = d;

	if(debug['d'])
		print("const-dcl %S %N\n", n->sym, n->sym->oconst);
}

/*
 * return nelem of list
 */
int
listcount(Node *n)
{
	int v;

	v = 0;
	while(n != N) {
		v++;
		if(n->op != OLIST)
			break;
		n = n->right;
	}
	return v;
}

/*
 * turn a parsed function declaration
 * into a type
 */
Node*
functype(Node *this, Node *in, Node *out)
{
	Node *t;

	t = nod(OTYPE, N, N);
	t->etype = TFUNC;

	t->type = dostruct(this, TSTRUCT);
	t->type->down = dostruct(out, TSTRUCT);
	t->type->down->down = dostruct(in, TSTRUCT);

	t->thistuple = listcount(this);
	t->outtuple = listcount(out);
	t->intuple = listcount(in);

	return t;
}

void
funcnam(Node *t, char *nam)
{
	Node *n;
	Sym *s;
	char buf[100];

	if(nam == nil) {
		vargen++;
		snprint(buf, sizeof(buf), "_f%.3ld", vargen);
		nam = buf;
	}

	if(t->etype != TFUNC)
		fatal("funcnam: not func %T\n", t);

	if(t->thistuple > 0) {
		vargen++;
		snprint(namebuf, sizeof(namebuf), "_t%.3ld", vargen);
		s = lookup(namebuf);
		addtyp(newtype(s), t->type, PEXTERN);
		n = newname(s);
		n->vargen = vargen;
		t->type->nname = n;
	}
	if(t->outtuple > 0) {
		vargen++;
		snprint(namebuf, sizeof(namebuf), "_o%.3ld", vargen);
		s = lookup(namebuf);
		addtyp(newtype(s), t->type->down, PEXTERN);
		n = newname(s);
		n->vargen = vargen;
		t->type->down->nname = n;
	}
	if(t->intuple > 0) {
		vargen++;
		snprint(namebuf, sizeof(namebuf), "_i%.3ld", vargen);
		s = lookup(namebuf);
		addtyp(newtype(s), t->type->down->down, PEXTERN);
		n = newname(s);
		n->vargen = vargen;
		t->type->down->down->nname = n;
	}
}

int
methcmp(Node *t1, Node *t2)
{
	if(t1->etype != TFUNC)
		return 0;
	if(t2->etype != TFUNC)
		return 0;

	t1 = t1->type->down;	// skip this arg
	t2 = t2->type->down;	// skip this arg
	for(;;) {
		if(t1 == t2)
			break;
		if(t1 == N || t2 == N)
			return 0;
		if(t1->etype != TSTRUCT || t2->etype != TSTRUCT)
			return 0;

		if(!eqtype(t1->type, t2->type, 0))
			return 0;

		t1 = t1->down;
		t2 = t2->down;
	}
	return 1;
}

/*
 * add a method, declared as a function,
 * into the structure
 */
void
addmethod(Node *n, Node *pa, Node *t)
{
	Node *p, *f, *d;
	Sym *s;

	if(n->op != ONAME)
		goto bad;
	s = n->sym;
	if(s == S)
		goto bad;
	if(pa == N)
		goto bad;
	if(pa->etype != TPTR)
		goto bad;
	p = pa->type;
	if(p == N)
		goto bad;
	if(p->etype != TSTRUCT)
		goto bad;
	if(p->sym == S)
		goto bad;

	if(p->type == N) {
		n = nod(ODCLFIELD, newname(s), N);
		n->type = t;

		stotype(n, &p->type, p);
		return;
	}

	d = N;	// last found
	for(f=p->type; f!=N; f=f->down) {
		if(f->etype != TFIELD)
			fatal("addmethod: not TFIELD: %N", f);

		if(strcmp(s->name, f->sym->name) != 0) {
			d = f;
			continue;
		}

		// if a field matches a non-this function
		// then delete it and let it be redeclared
		if(methcmp(t, f->type)) {
			if(d == N) {
				p->type = f->down;
				continue;
			}
			d->down = f->down;
			continue;
		}
		if(!eqtype(t, f->type, 0))
			yyerror("field redeclared as method: %S", s);
		return;
	}

	n = nod(ODCLFIELD, newname(s), N);
	n->type = t;

	if(d == N)
		stotype(n, &p->type, p);
	else
		stotype(n, &d->down, p);
	return;

bad:
	yyerror("unknown method pointer: %T", pa);
}

/*
 * declare the function proper.
 * and declare the arguments
 * called in extern-declaration context
 * returns in auto-declaration context.
 */
void
funchdr(Node *n)
{
	Node *on;
	Sym *s;

	s = n->nname->sym;
	on = s->oname;

	// check for foreward declaration
	if(on == N || !eqtype(n->type, on->type, 0)) {
		// initial declaration or redeclaration
		// declare fun name, argument types and argument names
		funcnam(n->type, s->name);
		n->nname->type = n->type;
		if(n->type->thistuple == 0)
			addvar(n->nname, n->type, PEXTERN);
	} else {
		// identical redeclaration
		// steal previous names
		n->nname = on;
		n->type = on->type;
		n->sym = s;
		s->oname = n;
		if(debug['d'])
			print("forew  var-dcl %S %T\n", n->sym, n->type);
	}

	// change the declaration context from extern to auto
	autodcl = dcl();
	autodcl->back = autodcl;

	if(dclcontext != PEXTERN)
		fatal("funchdr: dclcontext");
	dclcontext = PAUTO;

	funcargs(n->type);
	if(n->type->thistuple > 0) {
		Node *n1;
		n1 = *getthis(n->type);
		addmethod(n->nname, n1->type->type, n->type);
	}
}

void
funcargs(Node *t)
{
	Node *n1;
	Iter save;

	// declare the this argument
	n1 = structfirst(&save, getthis(t));
	if(n1 != N) {
		if(n1->nname != N)
			addvar(n1->nname, n1->type, PAUTO);
	}

	// declare the incoming arguments
	n1 = structfirst(&save, getinarg(t));
	while(n1 != N) {
		if(n1->nname != N)
			addvar(n1->nname, n1->type, PAUTO);
		n1 = structnext(&save);
	}

	// declare the outgoing arguments
//	n1 = structfirst(&save, getoutarg(t));
//	while(n1 != N) {
//		n1->left = newname(n1->sym);
//		if(n1->nname != N)
//			addvar(n1->nname, n1->type, PAUTO);
//		n1 = structnext(&save);
//	}
}

/*
 * compile the function.
 * called in auto-declaration context.
 * returns in extern-declaration context.
 */
void
funcbody(Node *n)
{

	compile(n);

	// change the declaration context from auto to extern
	if(dclcontext != PAUTO)
		fatal("funcbody: dclcontext");
	dclcontext = PEXTERN;
}

/*
 * turn a parsed struct into a type
 */
Node**
stotype(Node *n, Node **t, Node *uber)
{
	Node *f;
	Iter save;

	n = listfirst(&save, &n);

loop:
	if(n == N) {
		*t = N;
		return t;
	}

	if(n->op == OLIST) {
		// recursive because it can be lists of lists
		t = stotype(n, t, uber);
		goto next;
	}

	if(n->op != ODCLFIELD || n->type == N)
		fatal("stotype: oops %N\n", n);

	if(n->type->etype == TDARRAY)
		yyerror("type of a structure field cannot be an open array");

	f = nod(OTYPE, N, N);
	f->etype = TFIELD;
	f->type = n->type;
	f->uberstruct = uber;

	if(n->left != N && n->left->op == ONAME) {
		f->nname = n->left;
	} else {
		vargen++;
		snprint(namebuf, sizeof(namebuf), "_e%.3ld", vargen);
		f->nname = newname(lookup(namebuf));
	}
	f->sym = f->nname->sym;
	f->nname->uberstruct = uber;	// can reach parent from element

	*t = f;
	t = &f->down;

next:
	n = listnext(&save);
	goto loop;
}

Node*
dostruct(Node *n, int et)
{
	Node *t;

	/*
	 * convert a parsed id/type list into
	 * a type for struct/interface/arglist
	 */

	t = nod(OTYPE, N, N);
	stotype(n, &t->type, t);
	t->etype = et;
	return t;
}

Node*
sortinter(Node *n)
{
	return n;
}

void
dcopy(Sym *a, Sym *b)
{
	a->name = b->name;
	a->oname = b->oname;
	a->otype = b->otype;
	a->oconst = b->oconst;
	a->package = b->package;
	a->opackage = b->opackage;
	a->forwtype = b->forwtype;
	a->lexical = b->lexical;
	a->undef = b->undef;
	a->vargen = b->vargen;
}

Sym*
push(void)
{
	Sym *d;

	d = mal(sizeof(*d));
	d->link = dclstack;
	dclstack = d;
	return d;
}

Sym*
pushdcl(Sym *s)
{
	Sym *d;

	d = push();
	dcopy(d, s);
	return d;
}

void
popdcl(void)
{
	Sym *d, *s;

//	if(debug['d'])
//		print("revert\n");
	for(d=dclstack; d!=S; d=d->link) {
		if(d->name == nil)
			break;
		s = pkglookup(d->name, d->package);
		dcopy(s, d);
		if(debug['d'])
			print("\t%ld pop %S\n", curio.lineno, s);
	}
	if(d != S)
		d = d->link;
	dclstack = d;
}

void
markdcl(void)
{
	Sym *d;

	d = push();
	d->name = nil;		// used as a mark in fifo
//	if(debug['d'])
//		print("markdcl\n");
}

void
markdclstack(void)
{
	Sym *d, *s;

	markdcl();

	// copy the entire pop of the stack
	// all the way back to block0.
	// after this the symbol table is at
	// block0 and popdcl will restore it.
	for(d=dclstack; d!=S; d=d->link) {
		if(d == b0stack)
			break;
		if(d->name != nil) {
			s = pkglookup(d->name, d->package);
			pushdcl(s);
			dcopy(s, d);
		}
	}
}

void
addvar(Node *n, Node *t, int ctxt)
{
	Dcl *r, *d;
	Sym *s;
	Node *on;
	int gen;

	if(n==N || n->sym == S || n->op != ONAME || t == N)
		fatal("addvar: n=%N t=%N nil", n, t);

	on = t;
	if(on->etype == TPTR)
		on = on->type;
	if(on->etype == TSTRUCT && on->vargen == 0) {
		vargen++;
		snprint(namebuf, sizeof(namebuf), "_s%.3ld", vargen);
		addtyp(newtype(lookup(namebuf)), on, PEXTERN);
	}

	s = n->sym;
	vargen++;
	gen = vargen;

	r = autodcl;
	if(ctxt == PEXTERN) {
		on = s->oname;
		if(on != N) {
			if(eqtype(t, on->type, 0)) {
				warn("%S redeclared", s);
				return;
			}
			yyerror("%S redeclared (%T %T)", s,
				on->type, t);
		}
		r = externdcl;
		gen = 0;
	}

	pushdcl(s);
	s->vargen = gen;
	s->oname = n;

	n->type = t;
	n->vargen = gen;

	d = dcl();
	d->dsym = s;
	d->dnode = n;
	d->op = ONAME;

	r->back->forw = d;
	r->back = d;

	if(debug['d']) {
		if(ctxt == PEXTERN)
			print("extern var-dcl %S G%ld %T\n", s, s->vargen, t);
		else
			print("auto   var-dcl %S G%ld %T\n", s, s->vargen, t);
	}
}

void
addtyp(Node *n, Node *t, int ctxt)
{
	Dcl *r, *d;
	Sym *s;
	Node *f, *ot;

	if(n==N || n->sym == S || n->op != OTYPE || t == N)
		fatal("addtyp: n=%N t=%N nil", n, t);

	s = n->sym;

	r = autodcl;
	if(ctxt == PEXTERN) {
		ot = s->otype;
		if(ot != N) {
			// allow nil interface to be
			// redeclared as an interface
			if(ot->etype == TINTER && ot->type == N && t->etype == TINTER) {
				if(debug['d'])
					print("forew  typ-dcl %S G%ld %T\n", s, s->vargen, t);
				s->otype = t;
				return;
			}
			if(eqtype(t, ot, 0)) {
				warn("%S redeclared", s);
				return;
			}
			yyerror("%S redeclared (%T %T)", s,
				ot, t);
		}
		r = externdcl;
	}

	pushdcl(s);
	vargen++;
	s->vargen = vargen;
	s->otype = t;
	s->lexical = LATYPE;

	if(t->sym != S)
		warn("addtyp: renaming %S to %S", t->sym, s);

	t->sym = s;
	t->vargen = vargen;

	for(f=s->forwtype; f!=N; f=f->nforw) {
		if(f->op != OTYPE && f->etype != TPTR)
			fatal("addtyp: foreward");
		f->type = t;
	}
	s->forwtype = N;

	d = dcl();
	d->dsym = s;
	d->dnode = t;
	d->op = OTYPE;

	r->back->forw = d;
	r->back = d;

	if(debug['d']) {
		if(ctxt == PEXTERN)
			print("extern typ-dcl %S G%ld %T\n", s, s->vargen, t);
		else
			print("auto   typ-dcl %S G%ld %T\n", s, s->vargen, t);
	}
}

/*
 * make a new variable
 */
Node*
tempname(Node *t)
{
	Sym *s;
	Node *n;

	if(t == N) {
		yyerror("tempname called with nil type");
		t = types[TINT32];
	}

	s = lookup("!tmpname!");
	n = newname(s);
	dodclvar(n, t);
	return n;
}

/*
 * this generates a new name that is
 * pushed down on the declaration list.
 * no diagnostics are produced as this
 * name will soon be declared.
 */
Node*
newname(Sym *s)
{
	Node *n;

	n = nod(ONAME, N, N);
	n->sym = s;
	n->type = N;
	n->addable = 1;
	n->ullman = 0;
	return n;
}

/*
 * this will return an old name
 * that has already been pushed on the
 * declaration list. a diagnostic is
 * generated if no name has been defined.
 */
Node*
oldname(Sym *s)
{
	Node *n;

	n = s->oname;
	if(n == N) {
		yyerror("%S undefined", s);
		n = newname(s);
		dodclvar(n, types[TINT32]);
	}
	return n;
}

/*
 * same for types
 */
Node*
newtype(Sym *s)
{
	Node *n;

	n = nod(OTYPE, N, N);
	n->etype = TFORW;
	n->sym = s;
	n->type = N;
	return n;
}

Node*
oldtype(Sym *s)
{
	Node *n;

	n = s->otype;
	if(n == N)
		fatal("%S not a type", s); // cant happen
	return n;
}

Node*
forwdcl(Sym *s)
{
	Node *n;

	// this type has no meaning and
	// will cause an error if referenced.
	// it will be patched when/if the
	// type is ever assigned.
	n = nod(OTYPE, N, N);
	n->etype = TFORW;
	n = ptrto(n);

	n->nforw = s->forwtype;
	s->forwtype = n;
	return n;
}
