aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acid/dot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/acid/dot.c')
-rw-r--r--src/cmd/acid/dot.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/cmd/acid/dot.c b/src/cmd/acid/dot.c
new file mode 100644
index 00000000..07b8c194
--- /dev/null
+++ b/src/cmd/acid/dot.c
@@ -0,0 +1,153 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+#include <mach.h>
+#define Extern extern
+#include "acid.h"
+
+Type*
+srch(Type *t, char *s)
+{
+ Type *f;
+
+ f = 0;
+ while(t) {
+ if(strcmp(t->tag->name, s) == 0) {
+ if(f == 0 || t->depth < f->depth)
+ f = t;
+ }
+ t = t->next;
+ }
+ return f;
+}
+
+void
+odot(Node *n, Node *r)
+{
+ char *s;
+ Type *t;
+ Node res;
+ ulong addr;
+
+ s = n->sym->name;
+ if(s == 0)
+ fatal("dodot: no tag");
+
+ expr(n->left, &res);
+ if(res.store.comt == 0)
+ error("no type specified for (expr).%s", s);
+
+ if(res.type != TINT)
+ error("pointer must be integer for (expr).%s", s);
+
+ t = srch(res.store.comt, s);
+ if(t == 0)
+ error("no tag for (expr).%s", s);
+
+ /* Propagate types */
+ if(t->type)
+ r->store.comt = t->type->lt;
+
+ addr = res.store.u.ival+t->offset;
+ if(t->fmt == 'a') {
+ r->op = OCONST;
+ r->store.fmt = 'a';
+ r->type = TINT;
+ r->store.u.ival = addr;
+ }
+ else
+ indir(cormap, addr, t->fmt, r);
+
+}
+
+static Type **tail;
+static Lsym *base;
+
+void
+buildtype(Node *m, int d)
+{
+ Type *t;
+
+ if(m == ZN)
+ return;
+
+ switch(m->op) {
+ case OLIST:
+ buildtype(m->left, d);
+ buildtype(m->right, d);
+ break;
+
+ case OCTRUCT:
+ buildtype(m->left, d+1);
+ break;
+ default:
+ t = malloc(sizeof(Type));
+ t->next = 0;
+ t->depth = d;
+ t->tag = m->sym;
+ t->base = base;
+ t->offset = m->store.u.ival;
+ if(m->left) {
+ t->type = m->left->sym;
+ t->fmt = 'a';
+ }
+ else {
+ t->type = 0;
+ if(m->right)
+ t->type = m->right->sym;
+ t->fmt = m->store.fmt;
+ }
+
+ *tail = t;
+ tail = &t->next;
+ }
+}
+
+void
+defcomplex(Node *tn, Node *m)
+{
+ tail = &tn->sym->lt;
+ base = tn->sym;
+ buildtype(m, 0);
+}
+
+void
+decl(Node *n)
+{
+ Node *l;
+ Value *v;
+ Frtype *f;
+ Lsym *type;
+
+ type = n->sym;
+ if(type->lt == 0)
+ error("%s is not a complex type", type->name);
+
+ l = n->left;
+ if(l->op == ONAME) {
+ v = l->sym->v;
+ v->store.comt = type->lt;
+ v->store.fmt = 'a';
+ return;
+ }
+
+ /*
+ * Frame declaration
+ */
+ for(f = l->sym->local; f; f = f->next) {
+ if(f->var == l->left->sym) {
+ f->type = n->sym->lt;
+ return;
+ }
+ }
+ f = malloc(sizeof(Frtype));
+ if(f == 0)
+ fatal("out of memory");
+
+ f->type = type->lt;
+
+ f->var = l->left->sym;
+ f->next = l->sym->local;
+ l->sym->local = f;
+}