summaryrefslogtreecommitdiff
path: root/limbo/sbl.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /limbo/sbl.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'limbo/sbl.c')
-rw-r--r--limbo/sbl.c351
1 files changed, 351 insertions, 0 deletions
diff --git a/limbo/sbl.c b/limbo/sbl.c
new file mode 100644
index 00000000..fff80392
--- /dev/null
+++ b/limbo/sbl.c
@@ -0,0 +1,351 @@
+#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);
+
+void
+sblmod(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 int
+sblfile(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;
+}
+
+void
+sblfiles(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)
+
+void
+sblinst(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;
+ 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);
+}
+
+void
+sblty(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);
+ }
+}
+
+void
+sblfn(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);
+ }
+}
+
+void
+sblvar(Decl *vars)
+{
+ sbldecl(vars, Dglobal);
+}
+
+static int
+isvis(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 void
+sbldecl(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 void
+sbltype(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;
+ }
+}