blob: fd4464925fe97f71580cad20c6ec2af881a8ab4e [file] [log] [blame]
#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;
}