text: #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;
  	ulong 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, ulong pc, ulong 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;
  }
  