397 lines · 7.3 KB · Brainfuck
RawDownload
 sbltname := array[Tend] of{	Tnone =>	byte 'n',	Tadt =>		byte 'a',	Tadtpick =>	byte 'a',	Tarray =>	byte 'A',	Tbig =>		byte 'B',	Tbyte =>	byte 'b',	Tchan =>	byte 'C',	Treal =>	byte 'f',	Tfn =>		byte 'F',	Tint =>		byte 'i',	Tlist =>	byte 'L',	Tmodule =>	byte 'm',	Tref =>		byte 'R',	Tstring =>	byte 's',	Ttuple =>	byte 't',	Texception => byte 't',	Tfix => byte 'i',	Tpoly => byte 'P', 	Tainit =>	byte '?',	Talt =>		byte '?',	Tany =>		byte 'N',	Tarrow =>	byte '?',	Tcase =>	byte '?',	Tcasel =>	byte '?',	Tcasec =>	byte '?',	Tdot =>		byte '?',	Terror =>	byte '?',	Tgoto =>	byte '?',	Tid =>		byte '?',	Tiface =>	byte '?',	Texcept => byte '?',	Tinst => byte '?',};sbltadtpick:	con byte 'p'; sfiles:		ref Sym;ftail:		ref Sym;nsfiles:	int;blockid:	int;lastf:		int;lastline:	int; MAXSBLINT:	con 12;MAXSBLSRC:	con 6*(MAXSBLINT+1); sblmod(m: ref Decl){	bsym.puts("limbo .sbl 2.1\n");	bsym.puts(m.sym.name);	bsym.putb(byte '\n'); 	blockid = 0;	nsfiles = 0;	sfiles = ftail = nil;	lastf = 0;	lastline = 0;} sblfile(name: string): int{	i := 0;	for(s := sfiles; s != nil; s = s.next){		if(s.name == name)			return i;		i++;	}	s = ref Sym;	s.name = name;	s.next = nil;	if(sfiles == nil)		sfiles = s;	else		ftail.next = s;	ftail = s;	nsfiles = i + 1;	return i;} filename(s: string): string{	(nil, file) := str->splitr(s, "/ \\");	return file;} sblfiles(){	for(i := 0; i < nfiles; i++)		files[i].sbl = sblfile(files[i].name);	bsym.puts(string nsfiles);	bsym.putb(byte '\n');	for(s := sfiles; s != nil; s = s.next){		bsym.puts(filename(s.name));		bsym.putb(byte '\n');	}} sblint(buf: array of byte, off, v: int): int{	if(v == 0){		buf[off++] = byte '0';		return off;	}	stop := off + MAXSBLINT;	if(v < 0){		buf[off++] = byte '-';		v = -v;	}	n := stop;	while(v > 0){		buf[n -= 1] = byte(v % 10 + '0');		v = v / 10;	}	while(n < stop)		buf[off++] = buf[n++];	return off;} sblsrcconvb(buf: array of byte, off: int, src: Src): int{	(startf, startl) := fline(src.start >> PosBits);	(stopf, stopl) := fline(src.stop >> PosBits);	if(lastf != startf.sbl){		off = sblint(buf, off, startf.sbl);		buf[off++] = byte ':';	}	if(lastline != startl){		off = sblint(buf, off, startl);		buf[off++] = byte '.';	}	off = sblint(buf, off, (src.start & PosMask));	buf[off++] = byte ',';	if(startf.sbl != stopf.sbl){		off = sblint(buf, off, stopf.sbl);		buf[off++] = byte ':';	}	if(startl != stopl){		off = sblint(buf, off, stopl);		buf[off++] = byte '.';	}	off = sblint(buf, off, (src.stop & PosMask));	buf[off++] = byte ' ';	lastf = stopf.sbl;	lastline = stopl;	return off;} sblsrcconv(src: Src): string{	s := "";	(startf, startl) := fline(src.start >> PosBits);	(stopf, stopl) := fline(src.stop >> PosBits);	if(lastf != startf.sbl){		s += string startf.sbl;		s[len s] = ':';	}	if(lastline != startl){		s += string startl;		s[len s] = '.';	}	s += string (src.start & PosMask);	s[len s] = ',';	if(startf.sbl != stopf.sbl){		s += string stopf.sbl;		s[len s] = ':';	}	if(startl != stopl){		s += string stopl;		s[len s] = '.';	}	s += string (src.stop & PosMask);	s[len s] = ' ';	lastf = stopf.sbl;	lastline = stopl;	return s;} isnilsrc(s: Src): int{	return s.start == 0 && s.stop == 0;} isnilstopsrc(s: Src): int{	return s.stop == 0;} sblinst(in: ref Inst, ninst: int){	src: Src; 	MAXSBL:	con 8*1024;	buf := array[MAXSBL] of byte;	n := 0;	bsym.puts(string ninst);	bsym.putb(byte '\n');	sblblocks := array[nblocks] of {* => -1};	for(; in != nil; in = in.next){		if(in.op == INOOP)			continue;		if(in.src.start < 0)			fatal("no file specified for "+instconv(in));		if(n >= (MAXSBL - MAXSBLSRC - MAXSBLINT - 1)){			bsym.write(buf, n);			n = 0;		}		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++;		}		n = sblsrcconvb(buf, n, in.src);		src = in.src;		b := sblblocks[in.block];		if(b < 0)			sblblocks[in.block] = b = blockid++;		n = sblint(buf, n, b);		buf[n++] = byte '\n';	}	if(n > 0)		bsym.write(buf, n);} sblty(tys: array of ref Decl, ntys: int){	bsym.puts(string ntys);	bsym.putb(byte '\n');	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);	}} sblfn(fns: array of ref Decl, nfns: int){	bsym.puts(string nfns);	bsym.putb(byte '\n');	for(i := 0; i < nfns; i++){		f := fns[i];		if(ispoly(f))			rmfnptrs(f);		bsym.puts(string f.pc.pc);		bsym.putb(byte ':');		if(f.dot != nil && f.dot.ty.kind == Tadt){			bsym.puts(f.dot.sym.name);			bsym.putb(byte '.');		}		bsym.puts(f.sym.name);		bsym.putb(byte '\n');		sbldecl(f.ty.ids, Darg);		sbldecl(f.locals, Dlocal);		sbltype(f.ty.tof, 0);	}} sblvar(vars: ref Decl){	sbldecl(vars, Dglobal);} isvis(id: ref Decl): int{	if(!tattr[id.ty.kind].vis	|| id.sym == nil	|| id.sym.name == ""	|| id.sym.name[0] == '.')		return 0;	if(id.ty == tstring && id.init != nil && id.init.op == Oconst)		return 0;	if(id.src.start < 0 || id.src.stop < 0)		return 0;	return 1;} sbldecl(ids: ref Decl, store: int){	n := 0;	for(id := ids; id != nil; id = id.next){		if(id.store != store || !isvis(id))			continue;		n++;	}	bsym.puts(string n);	bsym.putb(byte '\n');	for(id = ids; id != nil; id = id.next){		if(id.store != store || !isvis(id))			continue;		bsym.puts(string id.offset);		bsym.putb(byte ':');		bsym.puts(id.sym.name);		bsym.putb(byte ':');		bsym.puts(sblsrcconv(id.src));		sbltype(id.ty, 0);		bsym.putb(byte '\n');	}} sbltype(t: ref Type, force: int){	if(t.kind == Tadtpick)		t = t.decl.dot.ty; 	d := t.decl;	if(!force && d != nil && d.ty.sbl >= 0){		bsym.putb(byte '@');		bsym.puts(string d.ty.sbl);		bsym.putb(byte '\n');		return;	} 	if(t.rec != byte 0)		fatal("recursive sbl type: "+typeconv(t)); 	t.rec = byte 1;	case t.kind{	* =>		fatal("bad type in sbltype: "+typeconv(t));	Tnone or	Tany or	Tint or	Tbig or	Tbyte or	Treal or	Tstring or	Tfix or	Tpoly =>		bsym.putb(sbltname[t.kind]);	Tfn =>		bsym.putb(sbltname[t.kind]);		sbldecl(t.ids, Darg);		sbltype(t.tof, 0);	Tarray or	Tlist or	Tchan or	Tref =>		bsym.putb(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);	Ttuple or	Texception =>		bsym.putb(sbltname[t.kind]);		bsym.puts(string t.size);		bsym.putb(byte '.');		sbldecl(t.ids, Dfield);	Tadt =>		if(t.tags != nil)			bsym.putb(sbltadtpick);		else			bsym.putb(sbltname[t.kind]);		if(d.dot != nil && !isimpmod(d.dot.sym))			bsym.puts(d.dot.sym.name + "->");		bsym.puts(d.sym.name);		bsym.putb(byte ' ');		bsym.puts(sblsrcconv(d.src));		bsym.puts(string d.ty.size);		bsym.putb(byte '\n');		sbldecl(t.ids, Dfield);		if(t.tags != nil){			bsym.puts(string t.decl.tag);			bsym.putb(byte '\n');			lastt : ref Type = nil;			for(tg := t.tags; tg != nil; tg = tg.next){				bsym.puts(tg.sym.name);				bsym.putb(byte ':');				bsym.puts(sblsrcconv(tg.src));				if(lastt == tg.ty){					bsym.putb(byte '\n');				}else{					bsym.puts(string tg.ty.size);					bsym.putb(byte '\n');					sbldecl(tg.ty.ids, Dfield);				}				lastt = tg.ty;			}		}	Tmodule =>		bsym.putb(sbltname[t.kind]);		bsym.puts(d.sym.name);		bsym.putb(byte '\n');		bsym.puts(sblsrcconv(d.src));		sbldecl(t.ids, Dglobal);	}	t.rec = byte 0;}