示例#1
0
文件: main.c 项目: a8m/c
int
main(int argc, char *argv[])
{
	int   i;
	Vec  *includedirs;
	char *cfile;
	
	cfile = 0;
	includedirs = vec();
	for(i = 1; i < argc; i++) {
		if(strcmp(argv[i], "-I") == 0) {
			i++;
			if(i >= argc)
				errorf("-I requires an include path\n");
			vecappend(includedirs, argv[i]);
		} else if(strncmp(argv[i], "-I", 2) == 0) {
			vecappend(includedirs, argv[i]+2);
		} else {
			if(argv[i][0] == '-')
				errorf("unknown flag %s\n", argv[i]);
			if(cfile)
				errorf("please specify a single c file\n");
			cfile = argv[i];
		}
	}
	if(!cfile)
		usage();
	cppinit(cfile, includedirs);
	emitinit(stdout);
	parse();
	emitend();
	return 0;
}
示例#2
0
文件: main.c 项目: 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;
}
示例#3
0
文件: parse.c 项目: xtao/c
static void
fbody(void)
{
	Node   *gotofixup;
	int     i;
	char   *l;
	NameTy *nt;
	Sym    *sym;

	pushscope();
	labels = map();
	gotos = vec();
	for(i = 0; i < curfunc->type->Func.params->len; i++) {
		nt = vecget(curfunc->type->Func.params, i);
		if(nt->name) {
			sym = definesym(&curfunc->pos, SCAUTO, nt->name, nt->type, 0);
			vecappend(curfunc->Func.params, sym);
		}
	}
	curfunc->Func.body = block();
	popscope();
	for(i = 0 ; i < gotos->len ; i++) {
		gotofixup = vecget(gotos, i);
		l = mapget(labels, gotofixup->Goto.name);
		if(!l)
			errorposf(&gotofixup->pos, "goto target does not exist");
		gotofixup->Goto.l = l;
	}
}
示例#4
0
文件: parse.c 项目: xtao/c
static void
params(CTy *fty)
{
	int     sclass;
	CTy    *t;
	char   *name;
	SrcPos *pos;

	fty->Func.isvararg = 0;
	if(tok->k == ')')
		return;
	for(;;) {
		pos = &tok->pos;
		t = declspecs(&sclass);
		t = declarator(t, &name, 0);
		if(sclass != SCNONE)
			errorposf(pos, "storage class not allowed in parameter decl");
		vecappend(fty->Func.params, newnamety(name, t));
		if(tok->k != ',')
			break;
		next();
	}
	if(tok->k == TOKELLIPSIS) {
		fty->Func.isvararg = 1;
		next();
	}
}
示例#5
0
文件: parse.c 项目: xtao/c
static Node *
decl()
{
	Node   *n, *init;
	char   *name;
	CTy    *type, *basety;
	SrcPos *pos;
	Sym    *sym;
	Vec    *syms;
	int     sclass;

	pos = &tok->pos;
	syms  = vec();
	basety = declspecs(&sclass);
	while(tok->k != ';' && tok->k != TOKEOF) {
		type = declarator(basety, &name, &init);
		switch(sclass){
		case SCNONE:
			if(isglobal()) {
				sclass = SCGLOBAL;
			} else {
				sclass = SCAUTO;
			}
			break;
		case SCTYPEDEF:
			if(init)
				errorposf(pos, "typedef cannot have an initializer");
			break;
		}
		if(!name)
			errorposf(pos, "decl needs to specify a name");
		sym = definesym(pos, sclass, name, type, init);
		vecappend(syms, sym);
		if(isglobal() && tok->k == '{') {
			if(init)
				errorposf(pos, "function declaration has an initializer");
			if(type->t != CFUNC)
				errorposf(pos, "expected a function");
			curfunc = mknode(NFUNC, pos);
			curfunc->type = type;
			curfunc->Func.name = name;
			curfunc->Func.params = vec();
			curfunc->Func.stkslots = vec();
			fbody();
			definesym(pos, sclass, name, type, curfunc);
			curfunc = 0;
			goto done;
		}
		if(tok->k == ',')
			next();
		else
			break;
	}
	expect(';');
  done:
	n = mknode(NDECL, pos);
	n->Decl.syms = syms;
	return n;
}
示例#6
0
文件: emit.c 项目: a8m/c
void
penddata(char *label, CTy *ty, Node *init, int isglobal)
{
	Data *d;

	d = xmalloc(sizeof(Data));
	d->label = label;
	d->type = ty;
	d->init = init;
	d->isglobal = isglobal;
	vecappend(pendingdata, d);
}
示例#7
0
文件: parse.c 项目: xtao/c
static void
addtentativesym(Sym *sym)
{
	int i;
	Sym *s;

	for(i = 0; i < tentativesyms->len; i++) {
		s = vecget(tentativesyms, i);
		if(s == sym)
			return;
	}
	vecappend(tentativesyms, sym);
}
示例#8
0
文件: main.c 项目: 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;
}
示例#9
0
文件: parse.c 项目: xtao/c
/* TODO: proper efficient set for tentative syms */
static void
removetentativesym(Sym *sym)
{
	int i;
	Vec *newv;
	Sym *s;

	newv = vec();
	for(i = 0; i < tentativesyms->len; i++) {
		s = vecget(tentativesyms, i);
		if(s == sym)
			continue;
		vecappend(newv, s);
	}
	tentativesyms = newv;
}
示例#10
0
文件: types.c 项目: 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);
}
示例#11
0
文件: parse.c 项目: 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;
}