acid
This commit is contained in:
parent
22a7368ef2
commit
564ca709d0
14 changed files with 6578 additions and 0 deletions
270
src/cmd/acid/list.c
Normal file
270
src/cmd/acid/list.c
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
#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*
|
||||
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] == '.')
|
||||
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);
|
||||
|
||||
return depth<40;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue