plan9fox/sys/src/cmd/acid/list.c
cinap_lenrek 16acf605e2 acid: make 'a' and 'A' format to have the same size as mach->szaddr
to make it easier to write portable acid code, we
introduce 'A' format in the same meaning as in db(1):

A    Print the value of dot in hexadecimal.  Dot is
     unaffected.

both 'a' (symbolic) and 'A' will both have 64 or 32 bit
size depending on the mach, so pointer array indexing
works the same.
2014-02-09 22:43:09 +01:00

278 lines
3.6 KiB
C

#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->l == 0) {
list->l = l;
r->l = l;
return;
}
for(f = list->l; f->next; f = f->next)
;
f->next = l;
r->l = list->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->ival != r->ival)
return 0;
break;
case TFLOAT:
if(l->fval != r->fval)
return 0;
break;
case TSTRING:
if(scmp(l->string, r->string) == 0)
return 0;
break;
case TLIST:
if(listcmp(l->l, r->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->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->l = l;
for(tl = &res->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, vlong v)
{
List *l, *tl;
tl = al(TLIST);
l = al(TSTRING);
tl->l = l;
l->fmt = 's';
l->string = strnode(s);
l->next = al(TINT);
l = l->next;
l->fmt = 'A';
l->ival = v;
return tl;
}
static List*
listlocals(Map *map, Symbol *fn, uvlong fp)
{
int i;
uvlong val;
Symbol s;
List **tail, *l2;
l2 = 0;
tail = &l2;
s = *fn;
for(i = 0; localsym(&s, i); i++) {
if(s.class != CAUTO)
continue;
if(s.name[0] == '.')
continue;
if(geta(map, fp-s.value, &val) > 0) {
*tail = listvar(s.name, val);
tail = &(*tail)->next;
}
}
return l2;
}
static List*
listparams(Map *map, Symbol *fn, uvlong fp)
{
int i;
Symbol s;
uvlong v;
List **tail, *l2;
l2 = 0;
tail = &l2;
fp += mach->szaddr; /* skip saved pc */
s = *fn;
for(i = 0; localsym(&s, i); i++) {
if (s.class != CPARAM)
continue;
if(geta(map, fp+s.value, &v) > 0) {
*tail = listvar(s.name, v);
tail = &(*tail)->next;
}
}
return l2;
}
void
trlist(Map *map, uvlong pc, uvlong sp, Symbol *sym)
{
List *q, *l;
static List **tail;
if (tracelist == 0) { /* first time */
tracelist = al(TLIST);
tail = &tracelist;
}
q = al(TLIST);
*tail = q;
tail = &q->next;
l = al(TINT); /* Function address */
q->l = l;
l->ival = sym->value;
l->fmt = 'A';
l->next = al(TINT); /* called from address */
l = l->next;
l->ival = pc;
l->fmt = 'Y';
l->next = al(TLIST); /* make list of params */
l = l->next;
l->l = listparams(map, sym, sp);
l->next = al(TLIST); /* make list of locals */
l = l->next;
l->l = listlocals(map, sym, sp);
}