summaryrefslogtreecommitdiff
path: root/sys/src/cmd/acid/dot.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/acid/dot.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/acid/dot.c')
-rwxr-xr-xsys/src/cmd/acid/dot.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/sys/src/cmd/acid/dot.c b/sys/src/cmd/acid/dot.c
new file mode 100755
index 000000000..4ff1d61e4
--- /dev/null
+++ b/sys/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;
+ uvlong addr;
+
+ s = n->sym->name;
+ if(s == 0)
+ fatal("dodot: no tag");
+
+ expr(n->left, &res);
+ if(res.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.comt, s);
+ if(t == 0)
+ error("no tag for (expr).%s", s);
+
+ /* Propagate types */
+ if(t->type)
+ r->comt = t->type->lt;
+
+ addr = res.ival+t->offset;
+ if(t->fmt == 'a') {
+ r->op = OCONST;
+ r->fmt = 'a';
+ r->type = TINT;
+ r->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->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->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->comt = type->lt;
+ v->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;
+}