| #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; |
| u64int 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; |
| } |