Esempio n. 1
0
File: parse.c Progetto: xtao/c
static CTy *
directdeclarator(CTy *basety, char **name) 
{
	CTy *ty, *stub;

	*name = 0;
	switch(tok->k) {
	case '(':
		expect('(');
		stub = gcmalloc(sizeof(CTy));
		*stub = *basety;
		ty = declarator(stub, name, 0);
		expect(')');
		*stub = *declaratortail(basety);
		return ty;
	case TOKIDENT:
		if(name)
			*name = tok->v;
		next();
		return declaratortail(basety);
	default:
		if(!name)
			errorposf(&tok->pos, "expected ident or ( but got %s", tokktostr(tok->k));
		return declaratortail(basety);
	}
	errorf("unreachable");
	return 0;
}
Esempio n. 2
0
File: main.c Progetto: xtao/c
static Val *
randstruct(int depth)
{
	Val *r, *p;
	int i, n; 
	char buff[1024];

	r = gcmalloc(sizeof(Val));
	r->t = STRUCT;
	r->Cstruct.members = vec();
	n = rand() % MAXSTRUCTM;
	for(i = 0; i < n; i++)
		vecappend(r->Cstruct.members, randval(depth + 1));
	snprintf(buff, sizeof buff, "s%d", structcount++);
	r->Cstruct.name = gcstrdup(buff);
	printf("struct %s {\n", r->Cstruct.name);
	for(i = 0; i < r->Cstruct.members->len; i++) {
		p = vecget(r->Cstruct.members, i);
		printf("\t");
		printvaltype(p);
		printf(" m%d;\n", i);
	}
	printf("};\n");
	return r;
}
Esempio n. 3
0
List *
list()
{
    List *l;

    l = gcmalloc(sizeof(List));
    return l;
}
Esempio n. 4
0
File: parse.c Progetto: xtao/c
static CTy *
newtype(int type)
{
	CTy *t;

	t = gcmalloc(sizeof(CTy));
	t->t = type;
	return t;
}
Esempio n. 5
0
File: parse.c Progetto: xtao/c
static Node *
mknode(int type, SrcPos *p)
{
	Node *n;

	n = gcmalloc(sizeof(Node));
	n->pos = *p;
	n->t = type;
	return n;
}
Esempio n. 6
0
File: parse.c Progetto: xtao/c
static NameTy *
newnamety(char *n, CTy *t)
{
	NameTy *nt;
	
	nt = gcmalloc(sizeof(NameTy));
	nt->name = n;
	nt->type = t;
	return nt;
}
Esempio n. 7
0
void
listprepend(List *l, void *v)
{
    ListEnt *e;

    e = gcmalloc(sizeof(ListEnt));
    e->v = v;
    e->next = l->head;
    l->head = e;
}
Esempio n. 8
0
File: main.c Progetto: xtao/c
static Testcase *
randtestcase()
{
	Testcase *t;
	int n, i;
	
	t = gcmalloc(sizeof(Testcase));
	t->vals = vec();
	t->ret = randval(0);
	n = rand() % MAXPARAMS;
	for(i = 0; i < n; i++)
		vecappend(t->vals, randval(0));
	return t;
}
Esempio n. 9
0
File: main.c Progetto: xtao/c
static Val *
randval(int depth)
{
	Val *r;

	again:
	switch(rand() % TEND) {
	case CHAR:
		r = gcmalloc(sizeof(Val));
		r->t = CHAR;
		r->Cchar.v = rand();
		break;
	case SHORT:
		r = gcmalloc(sizeof(Val));
		r->t = SHORT;
		r->Cshort.v = rand();
		break;
	case INT:
		r = gcmalloc(sizeof(Val));
		r->t = INT;
		r->Cint.v = rand();
		break;
	case LONG:
		r = gcmalloc(sizeof(Val));
		r->t = LONG;
		r->Clong.v = rand();
		break;
	case LLONG:
		r = gcmalloc(sizeof(Val));
		r->t = LLONG;
		r->Cllong.v = rand();
		break;
	case FLOAT:
		r = gcmalloc(sizeof(Val));
		r->t = FLOAT;
		r->Cfloat.v = (float)rand();
		break;
	case DOUBLE:
		r = gcmalloc(sizeof(Val));
		r->t = DOUBLE;
		r->Cdouble.v = (double)rand();
		break;
	case STRUCT:
		if(depth > MAXNEST)
			goto again;
		r = randstruct(depth);
		break;
	default:
		panic("internal error randval");
	}
	return r;
}
Esempio n. 10
0
File: parse.c Progetto: xtao/c
static Sym *
defineenum(SrcPos *p, char *name, CTy *type, int64 v)
{
	Sym *sym;

	sym = gcmalloc(sizeof(Sym));
	sym->pos = p;
	sym->name = name;
	sym->type = type;
	sym->k = SYMENUM;
	sym->Enum.v = v;
	if(!define(syms, name, sym))
		errorposf(p, "redefinition of %s", name);
	return sym;
}
Esempio n. 11
0
File: parse.c Progetto: xtao/c
char *
newlabel(void)
{
	char *s;
	int   n;

	n = snprintf(0, 0, "L%d", labelcount);
	if(n < 0)
		panic("internal error");
	n += 1;
	s = gcmalloc(n);
	if(snprintf(s, n, "L%d", labelcount) < 0)
		panic("internal error");
	labelcount++;
	return s;
}
Esempio n. 12
0
void
listappend(List *l, void *v)
{
    ListEnt *e, *ne;

    ne = gcmalloc(sizeof(ListEnt));
    ne->v = v;
    if(l->head == 0) {
        l->head = ne;
        return;
    }
    e = l->head;
    while(e->next)
        e = e->next;
    e->next = ne;
}
Esempio n. 13
0
static void
pushlex(char *path)
{
	Lexer *l;

	if(nlexers == MAXINCLUDE)
		panic("include depth limit reached!");
	l = gcmalloc(sizeof(Lexer));
	l->pos.file = path;
	l->prevpos.file = path;
	l->markpos.file = path;
	l->pos.line = 1;
	l->pos.col = 1;
	l->f = fopen(path, "r");
	if (!l->f)
		errorf("error opening file %s\n", path);
	lexers[nlexers] = l;
	nlexers += 1;
}
Esempio n. 14
0
File: parse.c Progetto: xtao/c
static CTy *
usualarithconv(Node **a, Node **b)
{   
	Node **large, **small;
	CTy   *t;

	if(!isarithtype((*a)->type) || !isarithtype((*b)->type))
		panic("internal error\n");
	if(convrank((*a)->type) < convrank((*b)->type)) {
		large = a;
		small = b;
	} else {
		large = b;
		small = a;
	}
	if(isftype((*large)->type)) {
		*small = mkcast(&(*small)->pos, *small, (*large)->type);
		return (*large)->type;
	}
	*large = ipromote(*large);
	*small = ipromote(*small);
	if(sametype((*large)->type, (*small)->type))
		return (*large)->type;
	if((*large)->type->Prim.issigned == (*small)->type->Prim.issigned ) {
		*small = mkcast(&(*small)->pos, *small, (*large)->type);
		return (*large)->type;
	}
	if(!(*large)->type->Prim.issigned) {
		*small = mkcast(&(*small)->pos, *small, (*large)->type);
		return (*large)->type;
	}
	if((*large)->type->Prim.issigned && canrepresent((*large)->type, (*small)->type)) {
		*small = mkcast(&(*small)->pos, *small, (*large)->type);
		return (*large)->type;
	}
	t = gcmalloc(sizeof(CTy));
	*t = *((*large)->type);
	t->Prim.issigned = 0;
	*large = mkcast(&(*large)->pos, *large, t);
	*small = mkcast(&(*small)->pos, *small, t);
	return t;
}
Esempio n. 15
0
File: types.c Progetto: xtao/c
void
addstructmember(SrcPos *pos, CTy *t, char *name, CTy *membt)
{
	StructMember *sm, *subsm;
	int i, align, sz;

	sm = gcmalloc(sizeof(StructMember));
	sm->name = name;
	sm->type = membt;
	if(!isstruct(t))
		panic("internal error");
	if(sm->name == 0 && isstruct(sm->type)) {
		for(i = 0; i < sm->type->Struct.members->len; i++) {
			subsm = vecget(sm->type->Struct.members, i);
			addstructmember(pos, t, subsm->name, subsm->type);
		}
		return;
	}
	if(sm->name) {
		for(i = 0; i < t->Struct.members->len; i++) {
			subsm = vecget(t->Struct.members, i);
			if(subsm->name)
			if(strcmp(sm->name, subsm->name) == 0)
				errorposf(pos ,"struct already has a member named %s", sm->name);
		}
	}
	if(membt->align < t->align)
		t->align = membt->align;
	sz = t->size;
	align = membt->align;
	if(sz % align)
		sz = sz + align - (sz % align);
	sm->offset = sz;
	sz += sm->type->size;
	t->size = sz;
	vecappend(t->Struct.members, sm);
}
Esempio n. 16
0
File: parse.c Progetto: xtao/c
static Sym *
definesym(SrcPos *p, int sclass, char *name, CTy *type, Node *n)
{
	Sym *sym;

	if(sclass == SCAUTO || n != 0)
		if(type->incomplete)
			errorposf(p, "cannot use incomplete type in this context");
	if(sclass == SCAUTO && isglobal())
		errorposf(p, "defining local symbol in global scope");
	sym = mapget(syms[nscopes - 1], name);
	if(sym) {
		switch(sym->k) {
		case SYMTYPE:
			if(sclass != SCTYPEDEF || !sametype(sym->type, type))
				errorposf(p, "incompatible redefinition of typedef %s", name);
			break;
		case SYMGLOBAL:
			if(sym->Global.sclass != sclass)
				errorposf(p, "redefinition of %s with differing storage class", name);
			if(sym->init && n)
				errorposf(p, "%s already initialized", name);
			if(!sym->init && n) {
				sym->init = n;
				emitsym(sym);
				removetentativesym(sym);
			}
			break;
		default:
			errorposf(p, "redefinition of %s", name);
		}
		return sym;
	}
	sym = gcmalloc(sizeof(Sym));
	sym->name = name;
	sym->type = type;
	sym->init = n;
	switch(sclass) {
	case SCAUTO:
		sym->k = SYMLOCAL;
		sym->Local.slot = gcmalloc(sizeof(StkSlot));
		sym->Local.slot->size = sym->type->size;
		sym->Local.slot->align = sym->type->align;
		vecappend(curfunc->Func.stkslots, sym->Local.slot);
		break;
	case SCTYPEDEF:
		sym->k = SYMTYPE;
		break;
	case SCGLOBAL:
		sym->k = SYMGLOBAL;
		sym->Global.label = name;
		sym->Global.sclass = SCGLOBAL;
		break;
	case SCSTATIC:
		sym->k = SYMGLOBAL;
		sym->Global.label = newlabel();
		sym->Global.sclass = SCSTATIC;
		break;
	}
	if(sym->k == SYMGLOBAL) {
		if(sym->init)
			emitsym(sym);
		else
			if(!isfunc(sym->type))
				addtentativesym(sym);
	}
	if(!define(syms, name, sym))
		panic("internal error");
	return sym;
}