16acf605e2
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.
278 lines
3.6 KiB
C
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);
|
|
}
|