sbl.c 6.6 KB

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