plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

list.c (4520B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include <ctype.h>
      5 #include <mach.h>
      6 #define Extern extern
      7 #include "acid.h"
      8 
      9 static List **tail;
     10 
     11 List*
     12 construct(Node *l)
     13 {
     14 	List *lh, **save;
     15 
     16 	save = tail;
     17 	lh = 0;
     18 	tail = &lh;
     19 	build(l);
     20 	tail = save;
     21 
     22 	return lh;
     23 }
     24 
     25 int
     26 listlen(List *l)
     27 {
     28 	int len;
     29 
     30 	len = 0;
     31 	while(l) {
     32 		len++;
     33 		l = l->next;
     34 	}
     35 	return len;
     36 }
     37 
     38 void
     39 build(Node *n)
     40 {
     41 	List *l;
     42 	Node res;
     43 
     44 	if(n == 0)
     45 		return;
     46 
     47 	switch(n->op) {
     48 	case OLIST:
     49 		build(n->left);
     50 		build(n->right);
     51 		return;
     52 	default:
     53 		expr(n, &res);
     54 		l = al(res.type);
     55 		l->store = res.store;
     56 		*tail = l;
     57 		tail = &l->next;
     58 	}
     59 }
     60 
     61 List*
     62 addlist(List *l, List *r)
     63 {
     64 	List *f;
     65 
     66 	if(l == 0)
     67 		return r;
     68 
     69 	for(f = l; f->next; f = f->next)
     70 		;
     71 	f->next = r;
     72 
     73 	return l;
     74 }
     75 
     76 void
     77 append(Node *r, Node *list, Node *val)
     78 {
     79 	List *l, *f;
     80 
     81 	l = al(val->type);
     82 	l->store = val->store;
     83 	l->next = 0;
     84 
     85 	r->op = OCONST;
     86 	r->type = TLIST;
     87 
     88 	if(list->store.u.l == 0) {
     89 		list->store.u.l = l;
     90 		r->store.u.l = l;
     91 		return;
     92 	}
     93 	for(f = list->store.u.l; f->next; f = f->next)
     94 		;
     95 	f->next = l;
     96 	r->store.u.l = list->store.u.l;
     97 }
     98 
     99 int
    100 listcmp(List *l, List *r)
    101 {
    102 	if(l == r)
    103 		return 1;
    104 
    105 	while(l) {
    106 		if(r == 0)
    107 			return 0;
    108 		if(l->type != r->type)
    109 			return 0;
    110 		switch(l->type) {
    111 		case TINT:
    112 			if(l->store.u.ival != r->store.u.ival)
    113 				return 0;
    114 			break;
    115 		case TFLOAT:
    116 			if(l->store.u.fval != r->store.u.fval)
    117 				return 0;
    118 			break;
    119 		case TSTRING:
    120 			if(scmp(l->store.u.string, r->store.u.string) == 0)
    121 				return 0;
    122 			break;
    123 		case TLIST:
    124 			if(listcmp(l->store.u.l, r->store.u.l) == 0)
    125 				return 0;
    126 			break;
    127 		}
    128 		l = l->next;
    129 		r = r->next;
    130 	}
    131 	if(l != r)
    132 		return 0;
    133 	return 1;
    134 }
    135 
    136 void
    137 nthelem(List *l, int n, Node *res)
    138 {
    139 	if(n < 0)
    140 		error("negative index in []");
    141 
    142 	while(l && n--)
    143 		l = l->next;
    144 
    145 	res->op = OCONST;
    146 	if(l == 0) {
    147 		res->type = TLIST;
    148 		res->store.u.l = 0;
    149 		return;
    150 	}
    151 	res->type = l->type;
    152 	res->store = l->store;
    153 }
    154 
    155 void
    156 delete(List *l, int n, Node *res)
    157 {
    158 	List **tl;
    159 
    160 	if(n < 0)
    161 		error("negative index in delete");
    162 
    163 	res->op = OCONST;
    164 	res->type = TLIST;
    165 	res->store.u.l = l;
    166 
    167 	for(tl = &res->store.u.l; l && n--; l = l->next)
    168 		tl = &l->next;
    169 
    170 	if(l == 0)
    171 		error("element beyond end of list");
    172 	*tl = l->next;
    173 }
    174 
    175 List*
    176 listvar(char *s, long v)
    177 {
    178 	List *l, *tl;
    179 
    180 	tl = al(TLIST);
    181 
    182 	l = al(TSTRING);
    183 	tl->store.u.l = l;
    184 	l->store.fmt = 's';
    185 	l->store.u.string = strnode(s);
    186 	l->next = al(TINT);
    187 	l = l->next;
    188 	l->store.fmt = 'X';
    189 	l->store.u.ival = v;
    190 
    191 	return tl;
    192 }
    193 
    194 static List*
    195 listregisters(Map *map, Regs *regs)
    196 {
    197 	List **tail, *l2, *l;
    198 	Regdesc *rp;
    199 	u64int v;
    200 
    201 	l2 = 0;
    202 	tail = &l2;
    203 	for(rp=mach->reglist; rp->name; rp++){
    204 		if(rget(regs, rp->name, &v) < 0)
    205 			continue;
    206 		l = al(TSTRING);
    207 		l->store.fmt = 's';
    208 		l->store.u.string = strnode(rp->name);
    209 		*tail = l;
    210 		tail = &l->next;
    211 		l = al(TINT);
    212 		l->store.fmt = 'X';
    213 		l->store.u.ival = v;
    214 		*tail = l;
    215 		tail = &l->next;
    216 	}
    217 	return l2;
    218 }
    219 
    220 static List*
    221 listlocals(Map *map, Regs *regs, Symbol *fn, int class)
    222 {
    223 	int i;
    224 	u32int val;
    225 	Symbol s;
    226 	List **tail, *l2;
    227 
    228 	l2 = 0;
    229 	tail = &l2;
    230 	if(fn == nil)
    231 		return l2;
    232 	for(i = 0; indexlsym(fn, i, &s)>=0; i++) {
    233 		if(s.class != class)
    234 			continue;
    235 		if(class == CAUTO && (s.name==0 || s.name[0] == '.'))
    236 			continue;
    237 		if(lget4(map, regs, s.loc, &val) < 0)
    238 			continue;
    239 		*tail = listvar(s.name, val);
    240 		tail = &(*tail)->next;
    241 	}
    242 	return l2;
    243 }
    244 
    245 static List*
    246 listparams(Map *map, Regs *regs, Symbol *fn)
    247 {
    248 	return listlocals(map, regs, fn, CPARAM);
    249 }
    250 
    251 static List*
    252 listautos(Map *map, Regs *regs, Symbol *fn)
    253 {
    254 	return listlocals(map, regs, fn, CAUTO);
    255 }
    256 
    257 int
    258 trlist(Map *map, Regs *regs, u64int pc, u64int callerpc, Symbol *sym, int depth)
    259 {
    260 	List *q, *l;
    261 	static List **tail;
    262 
    263 	if (tracelist == 0)		/* first time */
    264 		tail = &tracelist;
    265 
    266 	q = al(TLIST);
    267 	*tail = q;
    268 	tail = &q->next;
    269 
    270 	l = al(TINT);			/* Function address */
    271 	q->store.u.l = l;
    272 	l->store.u.ival = sym ? sym->loc.addr : pc;
    273 	l->store.fmt = 'X';
    274 
    275 	l->next = al(TINT);		/* actual pc address */
    276 	l = l->next;
    277 	l->store.u.ival = pc;
    278 	l->store.fmt = 'X';
    279 
    280 	l->next = al(TINT);		/* called from address */
    281 	l = l->next;
    282 	l->store.u.ival = callerpc;
    283 	l->store.fmt = 'X';
    284 
    285 	l->next = al(TLIST);		/* make list of params */
    286 	l = l->next;
    287 	if(sym)
    288 		l->store.u.l = listparams(map, regs, sym);
    289 
    290 	l->next = al(TLIST);		/* make list of locals */
    291 	l = l->next;
    292 	if(sym)
    293 		l->store.u.l = listautos(map, regs, sym);
    294 
    295 	l->next = al(TLIST);		/* make list of registers */
    296 	l = l->next;
    297 	l->store.u.l = listregisters(map, regs);
    298 
    299 	return depth<40;
    300 }