#include #include #include #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.nstore.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.nstore.comt, s); if(t == 0) error("no tag for (expr).%s", s); /* Propagate types */ if(t->type) r->nstore.comt = t->type->lt; addr = res.nstore.u0.sival+t->offset; if(t->fmt == 'a') { r->op = OCONST; r->nstore.fmt = 'a'; r->type = TINT; r->nstore.u0.sival = 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 = gmalloc(sizeof(Type)); t->next = 0; t->depth = d; t->tag = m->sym; t->base = base; t->offset = m->nstore.u0.sival; 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->nstore.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->vstore.comt = type->lt; v->vstore.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 = gmalloc(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; }