Charles.Forsyth20061220965a0ca19 years agoHistory
352 lines · 6.6 KB · C
RawDownload
#include "limbo.h" static char sbltname[Tend] ={	/* Tnone */	'n',	/* Tadt */	'a',	/* Tadtpick */	'a',	/* Tarray */	'A',	/* Tbig */	'B',	/* Tbyte */	'b',	/* Tchan */	'C',	/* Treal */	'f',	/* Tfn */	'F',	/* Tint */	'i',	/* Tlist */	'L',	/* Tmodule */	'm',	/* Tref */	'R',	/* Tstring */	's',	/* Ttuple */	't',	/* Texception */	't',	/* Tfix */	'i',	/* Tpoly */	'P', 	/* Tainit */	'?',	/* Talt */	'?',	/* Tany */	'N',	/* Tarrow */	'?',	/* Tcase */	'?',	/* Tcasel */	'?',	/* Tcasec */	'?',	/* Tdot */	'?',	/* Terror */	'?',	/* Tgoto */	'?',	/* Tid */	'?',	/* Tiface */	'?',	/* Texcept */	'?',	/* Tinst */	'?',};int	sbltadtpick = 'p'; static	Sym	*sfiles;static	Sym	*ftail;static	int	nsfiles;static	int	blockid;static	int	lastf;static	int	lastline; static	void	sbltype(Type*, int);static	void	sbldecl(Decl*, int);static	void	sblftype(Type*);static	void	sblfdecl(Decl*, int); voidsblmod(Decl *m){	Bprint(bsym, "limbo .sbl 2.1\n");	Bprint(bsym, "%s\n", m->sym->name); 	blockid = 0;	nsfiles = 0;	sfiles = ftail = nil;	lastf = 0;	lastline = 0;} static intsblfile(char *name){	Sym *s;	int i; 	i = 0;	for(s = sfiles; s != nil; s = s->next){		if(strcmp(s->name, name) == 0)			return i;		i++;	}	s = allocmem(sizeof(Sym));	s->name = name;	s->next = nil;	if(sfiles == nil)		sfiles = s;	else		ftail->next = s;	ftail = s;	nsfiles = i + 1;	return i;} static char *filename(char *s){	char *t; 	t = strrchr(s, '/');	if(t != nil)		s = t + 1;	t = strrchr(s, '\\');	if(t != nil)		s = t+1;	t = strrchr(s, ' ');	if(t != nil)		s = t + 1;	return s;} voidsblfiles(void){	Sym *s;	int i; 	for(i = 0; i < nfiles; i++)		files[i]->sbl = sblfile(files[i]->name);	Bprint(bsym, "%d\n", nsfiles);	for(s = sfiles; s != nil; s = s->next)		Bprint(bsym, "%s\n", filename(s->name));} static char*sblsrcconv(char *buf, char *end, Src *src){	Fline fl;	File *startf, *stopf;	char *s;	int startl, stopl; 	s = buf; 	fl = fline(src->start.line);	startf = fl.file;	startl = fl.line;	fl = fline(src->stop.line);	stopf = fl.file;	stopl = fl.line;	if(lastf != startf->sbl)		s = seprint(s, end, "%d:", startf->sbl);	if(lastline != startl)		s = seprint(s, end, "%d.", startl);	s = seprint(s, end, "%d,", src->start.pos);	if(startf->sbl != stopf->sbl)		s = seprint(s, end, "%d:", stopf->sbl);	if(startl != stopl)		s = seprint(s, end, "%d.", stopl);	seprint(s, end, "%d ", src->stop.pos);	lastf = stopf->sbl;	lastline = stopl;	return buf;} #define isnilsrc(s)	((s)->start.line == 0 && (s)->stop.line == 0 && (s)->start.pos == 0 && (s)->stop.pos == 0)#define isnilstopsrc(s)	((s)->stop.line == 0 && (s)->stop.pos == 0) voidsblinst(Inst *inst, long ninst){	Inst *in;	char buf[StrSize];	int *sblblocks, i, b;	Src src; 	Bprint(bsym, "%ld\n", ninst);	sblblocks = allocmem(nblocks * sizeof *sblblocks);	for(i = 0; i < nblocks; i++)		sblblocks[i] = -1;	src = nosrc;	for(in = inst; in != nil; in = in->next){		if(in->op == INOOP)			continue;		if(in->src.start.line < 0)			fatal("no file specified for %I", in);		b = sblblocks[in->block];		if(b < 0)			sblblocks[in->block] = b = blockid++;		if(isnilsrc(&in->src))			in->src = src;		else if(isnilstopsrc(&in->src)){	/* how does this happen ? */			in->src.stop = in->src.start;			in->src.stop.pos++;		}		Bprint(bsym, "%s%d\n", sblsrcconv(buf, buf+sizeof(buf), &in->src), b);		src = in->src;	}	free(sblblocks);} voidsblty(Decl **tys, int ntys){	Decl *d;	int i; 	Bprint(bsym, "%d\n", ntys);	for(i = 0; i < ntys; i++){		d = tys[i];		d->ty->sbl = i;	}	for(i = 0; i < ntys; i++){		d = tys[i];		sbltype(d->ty, 1);	}} voidsblfn(Decl **fns, int nfns){	Decl *f;	int i; 	Bprint(bsym, "%d\n", nfns);	for(i = 0; i < nfns; i++){		f = fns[i];		if(ispoly(f))			rmfnptrs(f);		if(f->dot != nil && f->dot->ty->kind == Tadt)			Bprint(bsym, "%ld:%s.%s\n", f->pc->pc, f->dot->sym->name, f->sym->name);		else			Bprint(bsym, "%ld:%s\n", f->pc->pc, f->sym->name);		sbldecl(f->ty->ids, Darg);		sbldecl(f->locals, Dlocal);		sbltype(f->ty->tof, 0);	}} voidsblvar(Decl *vars){	sbldecl(vars, Dglobal);} static intisvis(Decl *id){	if(!tattr[id->ty->kind].vis	|| id->sym == nil	|| id->sym->name == nil		/*????*/	|| id->sym->name[0] == '.')		return 0;	if(id->ty == tstring && id->init != nil && id->init->op == Oconst)		return 0;	if(id->src.start.line < 0 || id->src.stop.line < 0)		return 0;	return 1;} static voidsbldecl(Decl *ids, int store){	Decl *id;	char buf[StrSize];	int n; 	n = 0;	for(id = ids; id != nil; id = id->next){		if(id->store != store || !isvis(id))			continue;		n++;	}	Bprint(bsym, "%d\n", n);	for(id = ids; id != nil; id = id->next){		if(id->store != store || !isvis(id))			continue;		Bprint(bsym, "%ld:%s:%s", id->offset, id->sym->name, sblsrcconv(buf, buf+sizeof(buf), &id->src));		sbltype(id->ty, 0);		Bprint(bsym, "\n");	}} static voidsbltype(Type *t, int force){	Type *lastt;	Decl *tg, *d;	char buf[StrSize]; 	if(t->kind == Tadtpick)		t = t->decl->dot->ty; 	d = t->decl;	if(!force && d != nil && d->ty->sbl >= 0){		Bprint(bsym, "@%d\n", d->ty->sbl);		return;	} 	switch(t->kind){	default:		fatal("bad type %T in sbltype", t);		break;	case Tnone:	case Tany:	case Tint:	case Tbig:	case Tbyte:	case Treal:	case Tstring:	case Tfix:	case Tpoly:		Bprint(bsym, "%c", sbltname[t->kind]);		break;	case Tfn:		Bprint(bsym, "%c", sbltname[t->kind]);		sbldecl(t->ids, Darg);		sbltype(t->tof, 0);		break;	case Tarray:	case Tlist:	case Tchan:	case Tref:		Bprint(bsym, "%c", sbltname[t->kind]);		if(t->kind == Tref && t->tof->kind == Tfn){			tattr[Tany].vis = 1;			sbltype(tfnptr, 0);			tattr[Tany].vis = 0;		}		else			sbltype(t->tof, 0);		break;	case Ttuple:	case Texception:		Bprint(bsym, "%c%d.", sbltname[t->kind], t->size);		sbldecl(t->ids, Dfield);		break;	case Tadt:		if(t->tags != nil)			Bputc(bsym, sbltadtpick);		else			Bputc(bsym, sbltname[t->kind]);		if(d->dot != nil && !isimpmod(d->dot->sym))			Bprint(bsym, "%s->", d->dot->sym->name);		Bprint(bsym, "%s %s%d\n", d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src), d->ty->size);		sbldecl(t->ids, Dfield);		if(t->tags != nil){			Bprint(bsym, "%d\n", t->decl->tag);			lastt = nil;			for(tg = t->tags; tg != nil; tg = tg->next){				Bprint(bsym, "%s:%s", tg->sym->name, sblsrcconv(buf, buf+sizeof(buf), &tg->src));				if(lastt == tg->ty){					Bputc(bsym, '\n');				}else{					Bprint(bsym, "%d\n", tg->ty->size);					sbldecl(tg->ty->ids, Dfield);				}				lastt = tg->ty;			}		}		break;	case Tmodule:		Bprint(bsym, "%c%s\n%s", sbltname[t->kind], d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src));		sbldecl(t->ids, Dglobal);		break;	}}