xref: /inferno-os/limbo/sbl.c (revision 2b69dba5038ffd0b59cf30a4c44bce549e5097f8)
1 #include "limbo.h"
2 
3 static char sbltname[Tend] =
4 {
5 	/* Tnone */	'n',
6 	/* Tadt */	'a',
7 	/* Tadtpick */	'a',
8 	/* Tarray */	'A',
9 	/* Tbig */	'B',
10 	/* Tbyte */	'b',
11 	/* Tchan */	'C',
12 	/* Treal */	'f',
13 	/* Tfn */	'F',
14 	/* Tint */	'i',
15 	/* Tlist */	'L',
16 	/* Tmodule */	'm',
17 	/* Tref */	'R',
18 	/* Tstring */	's',
19 	/* Ttuple */	't',
20 	/* Texception */	't',
21 	/* Tfix */	'i',
22 	/* Tpoly */	'P',
23 
24 	/* Tainit */	'?',
25 	/* Talt */	'?',
26 	/* Tany */	'N',
27 	/* Tarrow */	'?',
28 	/* Tcase */	'?',
29 	/* Tcasel */	'?',
30 	/* Tcasec */	'?',
31 	/* Tdot */	'?',
32 	/* Terror */	'?',
33 	/* Tgoto */	'?',
34 	/* Tid */	'?',
35 	/* Tiface */	'?',
36 	/* Texcept */	'?',
37 	/* Tinst */	'?',
38 };
39 int	sbltadtpick = 'p';
40 
41 static	Sym	*sfiles;
42 static	Sym	*ftail;
43 static	int	nsfiles;
44 static	int	blockid;
45 static	int	lastf;
46 static	int	lastline;
47 
48 static	void	sbltype(Type*, int);
49 static	void	sbldecl(Decl*, int);
50 static	void	sblftype(Type*);
51 static	void	sblfdecl(Decl*, int);
52 
53 void
54 sblmod(Decl *m)
55 {
56 	Bprint(bsym, "limbo .sbl 2.1\n");
57 	Bprint(bsym, "%s\n", m->sym->name);
58 
59 	blockid = 0;
60 	nsfiles = 0;
61 	sfiles = ftail = nil;
62 	lastf = 0;
63 	lastline = 0;
64 }
65 
66 static int
67 sblfile(char *name)
68 {
69 	Sym *s;
70 	int i;
71 
72 	i = 0;
73 	for(s = sfiles; s != nil; s = s->next){
74 		if(strcmp(s->name, name) == 0)
75 			return i;
76 		i++;
77 	}
78 	s = allocmem(sizeof(Sym));
79 	s->name = name;
80 	s->next = nil;
81 	if(sfiles == nil)
82 		sfiles = s;
83 	else
84 		ftail->next = s;
85 	ftail = s;
86 	nsfiles = i + 1;
87 	return i;
88 }
89 
90 static char *
91 filename(char *s)
92 {
93 	char *t;
94 
95 	t = strrchr(s, '/');
96 	if(t != nil)
97 		s = t + 1;
98 	t = strrchr(s, '\\');
99 	if(t != nil)
100 		s = t+1;
101 	t = strrchr(s, ' ');
102 	if(t != nil)
103 		s = t + 1;
104 	return s;
105 }
106 
107 void
108 sblfiles(void)
109 {
110 	Sym *s;
111 	int i;
112 
113 	for(i = 0; i < nfiles; i++)
114 		files[i]->sbl = sblfile(files[i]->name);
115 	Bprint(bsym, "%d\n", nsfiles);
116 	for(s = sfiles; s != nil; s = s->next)
117 		Bprint(bsym, "%s\n", filename(s->name));
118 }
119 
120 static char*
121 sblsrcconv(char *buf, char *end, Src *src)
122 {
123 	Fline fl;
124 	File *startf, *stopf;
125 	char *s;
126 	int startl, stopl;
127 
128 	s = buf;
129 
130 	fl = fline(src->start.line);
131 	startf = fl.file;
132 	startl = fl.line;
133 	fl = fline(src->stop.line);
134 	stopf = fl.file;
135 	stopl = fl.line;
136 	if(lastf != startf->sbl)
137 		s = seprint(s, end, "%d:", startf->sbl);
138 	if(lastline != startl)
139 		s = seprint(s, end, "%d.", startl);
140 	s = seprint(s, end, "%d,", src->start.pos);
141 	if(startf->sbl != stopf->sbl)
142 		s = seprint(s, end, "%d:", stopf->sbl);
143 	if(startl != stopl)
144 		s = seprint(s, end, "%d.", stopl);
145 	seprint(s, end, "%d ", src->stop.pos);
146 	lastf = stopf->sbl;
147 	lastline = stopl;
148 	return buf;
149 }
150 
151 #define isnilsrc(s)	((s)->start.line == 0 && (s)->stop.line == 0 && (s)->start.pos == 0 && (s)->stop.pos == 0)
152 #define isnilstopsrc(s)	((s)->stop.line == 0 && (s)->stop.pos == 0)
153 
154 void
155 sblinst(Inst *inst, long ninst)
156 {
157 	Inst *in;
158 	char buf[StrSize];
159 	int *sblblocks, i, b;
160 	Src src;
161 
162 	Bprint(bsym, "%ld\n", ninst);
163 	sblblocks = allocmem(nblocks * sizeof *sblblocks);
164 	for(i = 0; i < nblocks; i++)
165 		sblblocks[i] = -1;
166 	src = nosrc;
167 	for(in = inst; in != nil; in = in->next){
168 		if(in->op == INOOP)
169 			continue;
170 		if(in->src.start.line < 0)
171 			fatal("no file specified for %I", in);
172 		b = sblblocks[in->block];
173 		if(b < 0)
174 			sblblocks[in->block] = b = blockid++;
175 		if(isnilsrc(&in->src))
176 			in->src = src;
177 		else if(isnilstopsrc(&in->src)){	/* how does this happen ? */
178 			in->src.stop = in->src.start;
179 			in->src.stop.pos++;
180 		}
181 		Bprint(bsym, "%s%d\n", sblsrcconv(buf, buf+sizeof(buf), &in->src), b);
182 		src = in->src;
183 	}
184 	free(sblblocks);
185 }
186 
187 void
188 sblty(Decl **tys, int ntys)
189 {
190 	Decl *d;
191 	int i;
192 
193 	Bprint(bsym, "%d\n", ntys);
194 	for(i = 0; i < ntys; i++){
195 		d = tys[i];
196 		d->ty->sbl = i;
197 	}
198 	for(i = 0; i < ntys; i++){
199 		d = tys[i];
200 		sbltype(d->ty, 1);
201 	}
202 }
203 
204 void
205 sblfn(Decl **fns, int nfns)
206 {
207 	Decl *f;
208 	int i;
209 
210 	Bprint(bsym, "%d\n", nfns);
211 	for(i = 0; i < nfns; i++){
212 		f = fns[i];
213 		if(ispoly(f))
214 			rmfnptrs(f);
215 		if(f->dot != nil && f->dot->ty->kind == Tadt)
216 			Bprint(bsym, "%ld:%s.%s\n", f->pc->pc, f->dot->sym->name, f->sym->name);
217 		else
218 			Bprint(bsym, "%ld:%s\n", f->pc->pc, f->sym->name);
219 		sbldecl(f->ty->ids, Darg);
220 		sbldecl(f->locals, Dlocal);
221 		sbltype(f->ty->tof, 0);
222 	}
223 }
224 
225 void
226 sblvar(Decl *vars)
227 {
228 	sbldecl(vars, Dglobal);
229 }
230 
231 static int
232 isvis(Decl *id)
233 {
234 	if(!tattr[id->ty->kind].vis
235 	|| id->sym == nil
236 	|| id->sym->name == nil		/*????*/
237 	|| id->sym->name[0] == '.')
238 		return 0;
239 	if(id->ty == tstring && id->init != nil && id->init->op == Oconst)
240 		return 0;
241 	if(id->src.start.line < 0 || id->src.stop.line < 0)
242 		return 0;
243 	return 1;
244 }
245 
246 static void
247 sbldecl(Decl *ids, int store)
248 {
249 	Decl *id;
250 	char buf[StrSize];
251 	int n;
252 
253 	n = 0;
254 	for(id = ids; id != nil; id = id->next){
255 		if(id->store != store || !isvis(id))
256 			continue;
257 		n++;
258 	}
259 	Bprint(bsym, "%d\n", n);
260 	for(id = ids; id != nil; id = id->next){
261 		if(id->store != store || !isvis(id))
262 			continue;
263 		Bprint(bsym, "%ld:%s:%s", id->offset, id->sym->name, sblsrcconv(buf, buf+sizeof(buf), &id->src));
264 		sbltype(id->ty, 0);
265 		Bprint(bsym, "\n");
266 	}
267 }
268 
269 static void
270 sbltype(Type *t, int force)
271 {
272 	Type *lastt;
273 	Decl *tg, *d;
274 	char buf[StrSize];
275 
276 	if(t->kind == Tadtpick)
277 		t = t->decl->dot->ty;
278 
279 	d = t->decl;
280 	if(!force && d != nil && d->ty->sbl >= 0){
281 		Bprint(bsym, "@%d\n", d->ty->sbl);
282 		return;
283 	}
284 
285 	switch(t->kind){
286 	default:
287 		fatal("bad type %T in sbltype", t);
288 		break;
289 	case Tnone:
290 	case Tany:
291 	case Tint:
292 	case Tbig:
293 	case Tbyte:
294 	case Treal:
295 	case Tstring:
296 	case Tfix:
297 	case Tpoly:
298 		Bprint(bsym, "%c", sbltname[t->kind]);
299 		break;
300 	case Tfn:
301 		Bprint(bsym, "%c", sbltname[t->kind]);
302 		sbldecl(t->ids, Darg);
303 		sbltype(t->tof, 0);
304 		break;
305 	case Tarray:
306 	case Tlist:
307 	case Tchan:
308 	case Tref:
309 		Bprint(bsym, "%c", sbltname[t->kind]);
310 		if(t->kind == Tref && t->tof->kind == Tfn){
311 			tattr[Tany].vis = 1;
312 			sbltype(tfnptr, 0);
313 			tattr[Tany].vis = 0;
314 		}
315 		else
316 			sbltype(t->tof, 0);
317 		break;
318 	case Ttuple:
319 	case Texception:
320 		Bprint(bsym, "%c%ld.", sbltname[t->kind], t->size);
321 		sbldecl(t->ids, Dfield);
322 		break;
323 	case Tadt:
324 		if(t->tags != nil)
325 			Bputc(bsym, sbltadtpick);
326 		else
327 			Bputc(bsym, sbltname[t->kind]);
328 		if(d->dot != nil && !isimpmod(d->dot->sym))
329 			Bprint(bsym, "%s->", d->dot->sym->name);
330 		Bprint(bsym, "%s %s%ld\n", d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src), d->ty->size);
331 		sbldecl(t->ids, Dfield);
332 		if(t->tags != nil){
333 			Bprint(bsym, "%d\n", t->decl->tag);
334 			lastt = nil;
335 			for(tg = t->tags; tg != nil; tg = tg->next){
336 				Bprint(bsym, "%s:%s", tg->sym->name, sblsrcconv(buf, buf+sizeof(buf), &tg->src));
337 				if(lastt == tg->ty){
338 					Bputc(bsym, '\n');
339 				}else{
340 					Bprint(bsym, "%ld\n", tg->ty->size);
341 					sbldecl(tg->ty->ids, Dfield);
342 				}
343 				lastt = tg->ty;
344 			}
345 		}
346 		break;
347 	case Tmodule:
348 		Bprint(bsym, "%c%s\n%s", sbltname[t->kind], d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src));
349 		sbldecl(t->ids, Dglobal);
350 		break;
351 	}
352 }
353