aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acid/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/acid/list.c')
-rw-r--r--src/cmd/acid/list.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/cmd/acid/list.c b/src/cmd/acid/list.c
new file mode 100644
index 00000000..76214b2d
--- /dev/null
+++ b/src/cmd/acid/list.c
@@ -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;
+}