#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <mach.h>
#define Extern extern
#include "acid.h"

static List **tail;

List*
construct(Node *l)
{
	List *lh, **save;

	save = tail;
	lh = 0;
	tail = &lh;
	build(l);
	tail = save;

	return lh;
}

int
listlen(List *l)
{
	int len;

	len = 0;
	while(l) {
		len++;
		l = l->next;
	}
	return len;
}

void
build(Node *n)
{
	List *l;
	Node res;

	if(n == 0)
		return;

	switch(n->op) {
	case OLIST:
		build(n->left);
		build(n->right);
		return;
	default:
		expr(n, &res);
		l = al(res.type);
		l->store = res.store;
		*tail = l;
		tail = &l->next;	
	}
}

List*
addlist(List *l, List *r)
{
	List *f;

	if(l == 0)
		return r;

	for(f = l; f->next; f = f->next)
		;
	f->next = r;

	return l;
}

void
append(Node *r, Node *list, Node *val)
{
	List *l, *f;

	l = al(val->type);
	l->store = val->store;
	l->next = 0;

	r->op = OCONST;
	r->type = TLIST;

	if(list->store.u.l == 0) {
		list->store.u.l = l;
		r->store.u.l = l;
		return;
	}
	for(f = list->store.u.l; f->next; f = f->next)
		;
	f->next = l;
	r->store.u.l = list->store.u.l;
}

int
listcmp(List *l, List *r)
{
	if(l == r)
		return 1;

	while(l) {
		if(r == 0)
			return 0;
		if(l->type != r->type)
			return 0;
		switch(l->type) {
		case TINT:
			if(l->store.u.ival != r->store.u.ival)
				return 0;
			break;
		case TFLOAT:
			if(l->store.u.fval != r->store.u.fval)
				return 0;
			break;
		case TSTRING:
			if(scmp(l->store.u.string, r->store.u.string) == 0)
				return 0;
			break;
		case TLIST:
			if(listcmp(l->store.u.l, r->store.u.l) == 0)
				return 0;
			break;
		}
		l = l->next;
		r = r->next;
	}
	if(l != r)
		return 0;
	return 1;
}

void
nthelem(List *l, int n, Node *res)
{
	if(n < 0)
		error("negative index in []");

	while(l && n--)
		l = l->next;

	res->op = OCONST;
	if(l == 0) {
		res->type = TLIST;
		res->store.u.l = 0;
		return;
	}
	res->type = l->type;
	res->store = l->store;
}

void
delete(List *l, int n, Node *res)
{
	List **tl;

	if(n < 0)
		error("negative index in delete");

	res->op = OCONST;
	res->type = TLIST;
	res->store.u.l = l;

	for(tl = &res->store.u.l; l && n--; l = l->next)
		tl = &l->next;

	if(l == 0)
		error("element beyond end of list");
	*tl = l->next;
}

List*
listvar(char *s, long v)
{
	List *l, *tl;

	tl = al(TLIST);

	l = al(TSTRING);
	tl->store.u.l = l;
	l->store.fmt = 's';
	l->store.u.string = strnode(s);
	l->next = al(TINT);
	l = l->next;
	l->store.fmt = 'X';
	l->store.u.ival = v;

	return tl;
}

static List*
listregisters(Map *map, Regs *regs)
{
	List **tail, *l2, *l;
	Regdesc *rp;
	u64int v;

	l2 = 0;
	tail = &l2;
	for(rp=mach->reglist; rp->name; rp++){
		if(rget(regs, rp->name, &v) < 0)
			continue;
		l = al(TSTRING);
		l->store.fmt = 's';
		l->store.u.string = strnode(rp->name);
		*tail = l;
		tail = &l->next;
		l = al(TINT);
		l->store.fmt = 'X';
		l->store.u.ival = v;
		*tail = l;
		tail = &l->next;
	}
	return l2;
}

static List*
listlocals(Map *map, Regs *regs, Symbol *fn, int class)
{
	int i;
	u32int val;
	Symbol s;
	List **tail, *l2;

	l2 = 0;
	tail = &l2;
	if(fn == nil)
		return l2;
	for(i = 0; indexlsym(fn, i, &s)>=0; i++) {
		if(s.class != class)
			continue;
		if(class == CAUTO && (s.name==0 || s.name[0] == '.'))
			continue;
		if(lget4(map, regs, s.loc, &val) < 0)
			continue;
		*tail = listvar(s.name, val);
		tail = &(*tail)->next;
	}
	return l2;
}

static List*
listparams(Map *map, Regs *regs, Symbol *fn)
{
	return listlocals(map, regs, fn, CPARAM);
}

static List*
listautos(Map *map, Regs *regs, Symbol *fn)
{
	return listlocals(map, regs, fn, CAUTO);
}

int
trlist(Map *map, Regs *regs, u64int pc, u64int callerpc, Symbol *sym, int depth)
{
	List *q, *l;
	static List **tail;

	if (tracelist == 0)		/* first time */
		tail = &tracelist;

	q = al(TLIST);
	*tail = q;
	tail = &q->next;

	l = al(TINT);			/* Function address */
	q->store.u.l = l;
	l->store.u.ival = sym ? sym->loc.addr : pc;
	l->store.fmt = 'X';

	l->next = al(TINT);		/* actual pc address */
	l = l->next;
	l->store.u.ival = pc;
	l->store.fmt = 'X';

	l->next = al(TINT);		/* called from address */
	l = l->next;
	l->store.u.ival = callerpc;
	l->store.fmt = 'X';

	l->next = al(TLIST);		/* make list of params */
	l = l->next;
	if(sym)
		l->store.u.l = listparams(map, regs, sym);

	l->next = al(TLIST);		/* make list of locals */
	l = l->next;
	if(sym)
		l->store.u.l = listautos(map, regs, sym);

	l->next = al(TLIST);		/* make list of registers */
	l = l->next;
	l->store.u.l = listregisters(map, regs);

	return depth<40;
}
