diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /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-x | sys/src/cmd/acid/dot.c | 153 |
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; +} |