ref: 1ad08d5fdee3b975722f692e9222da1a0126d632
parent: 62f7dc8a82a51b9b043587ee0ca52c62c7420999
author: Ori Bernstein <[email protected]>
date: Wed Oct 17 14:05:26 EDT 2012
Labels are now Lit values, not their own toplev nodes.
--- a/6/isel.c
+++ b/6/isel.c
@@ -737,12 +737,7 @@
static void isel(Isel *s, Node *n)
{
- Loc *lbl;
-
switch (n->type) {
- case Nlbl:
- g(s, Ilbl, lbl = loclbl(n), NULL);
- break;
case Nexpr:
selexpr(s, n);
break;
@@ -857,7 +852,11 @@
writelit(fd, v->lit.seqval[i]->expr.args[0], size(v->lit.seqval[i]));
break;
case Lfunc:
- die("Generating this shit ain't ready yet ");
+ die("Generating this shit ain't ready yet ");
+ break;
+ case Llbl:
+ die("Can't generate literal labels, ffs. They're not data.");
+ break;
}
}
--- a/6/locs.c
+++ b/6/locs.c
@@ -90,10 +90,14 @@
return l;
}
-Loc *loclbl(Node *lbl)
+Loc *loclbl(Node *e)
{
- assert(lbl->type = Nlbl);
- return locstrlbl(lbl->lbl.name);
+ Node *lbl;
+ assert(e->type == Nexpr);
+ lbl = e->expr.args[0];
+ assert(lbl->type == Nlit);
+ assert(lbl->lit.littype = Llbl);
+ return locstrlbl(lbl->lit.lblval);
}
Loc **locmap = NULL;
--- a/6/main.c
+++ b/6/main.c
@@ -30,11 +30,12 @@
printf("\t-I path\tAdd 'path' to use search path\n");
printf("\t-d\tPrint debug dumps. Recognized options: f r p i\n");
printf("\t\t\tno options: print most common debug information\n");
- printf("\t\t\tf: additionally log folded trees\n");
- printf("\t\t\tl: additionally log lowered pre-cfg trees\n");
- printf("\t\t\tT: additionally log tree immediately\n");
- printf("\t\t\tr: additionally log register allocation activity\n");
- printf("\t\t\ti: additionally log instruction selection activity\n");
+ printf("\t\t\tf: log folded trees\n");
+ printf("\t\t\tl: log lowered pre-cfg trees\n");
+ printf("\t\t\tT: log tree immediately\n");
+ printf("\t\t\tr: log register allocation activity\n");
+ printf("\t\t\ti: log instruction selection activity\n");
+ printf("\t\t\tu: log type unifications\n");
printf("\t-o\tOutput to outfile\n");
printf("\t-S\tGenerate assembly instead of object code\n");
}
--- a/6/simp.c
+++ b/6/simp.c
@@ -1117,6 +1117,9 @@
case Lfunc:
r = simplit(s, n, &file->file.stmts, &file->file.nstmts);
break;
+ case Llbl:
+ die("Don't support labels in expressions yet");
+ break;
}
break;
case Ovar:
@@ -1183,6 +1186,15 @@
s->argsz += size(n);
}
+static int islbl(Node *n)
+{
+ Node *l;
+ if (exprop(n) != Olit)
+ return 0;
+ l = n->expr.args[0];
+ return l->type == Nlit && l->lit.littype == Llbl;
+}
+
static Node *simp(Simp *s, Node *n)
{
Node *r, *t, *u;
@@ -1192,14 +1204,15 @@
return NULL;
r = NULL;
switch (n->type) {
- case Nlit: r = n; break;
- case Nlbl: append(s, n); break;
case Nblock: simpblk(s, n); break;
case Nifstmt: simpif(s, n, NULL); break;
case Nloopstmt: simploop(s, n); break;
case Nmatchstmt: simpmatch(s, n); break;
case Nexpr:
- r = rval(s, n, NULL);
+ if (islbl(n))
+ append(s, n);
+ else
+ r = rval(s, n, NULL);
if (r)
append(s, r);
/* drain the increment queue for this expr */
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,7 +4,6 @@
chartype.myr \
die.myr \
fmt.myr \
- option.myr \
rand.myr \
sys.myr \
types.myr \
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -26,10 +26,18 @@
return bb;
}
+static char *lblstr(Node *n)
+{
+ assert(exprop(n) == Olit);
+ assert(n->expr.args[0]->type == Nlit);
+ assert(n->expr.args[0]->lit.littype == Llbl);
+ return n->expr.args[0]->lit.lblval;
+}
+
static void label(Cfg *cfg, Node *lbl, Bb *bb)
{
- htput(cfg->lblmap, lbl->lbl.name, bb);
- lappend(&bb->lbls, &bb->nlbls, lbl->lbl.name);
+ htput(cfg->lblmap, lblstr(lbl), bb);
+ lappend(&bb->lbls, &bb->nlbls, lblstr(lbl));
}
static int addnode(Cfg *cfg, Bb *bb, Node *n)
@@ -49,6 +57,34 @@
return 0;
}
+static int islabel(Node *n)
+{
+ Node *l;
+ if (n->type != Nexpr)
+ return 0;
+ if (exprop(n) != Olit)
+ return 0;
+ l = n->expr.args[0];
+ if (l->type != Nlit)
+ return 0;
+ if (l->lit.littype != Llbl)
+ return 0;
+ return 1;
+}
+
+static Bb *addlabel(Cfg *cfg, Bb *bb, Node **nl, size_t i)
+{
+ /* if the current block assumes fall-through, insert an explicit jump */
+ if (i > 0 && nl[i - 1]->type == Nexpr) {
+ if (exprop(nl[i - 1]) != Ocjmp && exprop(nl[i - 1]) != Ojmp)
+ addnode(cfg, bb, mkexpr(-1, Ojmp, mklbl(-1, lblstr(nl[i])), NULL));
+ }
+ if (bb->nnl)
+ bb = mkbb(cfg);
+ label(cfg, nl[i], bb);
+ return bb;
+}
+
Cfg *mkcfg(Node **nl, size_t nn)
{
Cfg *cfg;
@@ -63,20 +99,13 @@
bb = mkbb(cfg);
for (i = 0; i < nn; i++) {
switch (nl[i]->type) {
- case Nlbl:
- /* if the current block assumes fall-through, insert an explicit jump */
- if (i > 0 && nl[i - 1]->type == Nexpr) {
- if (exprop(nl[i - 1]) != Ocjmp && exprop(nl[i - 1]) != Ojmp)
- addnode(cfg, bb, mkexpr(-1, Ojmp, mklbl(-1, nl[i]->lbl.name), NULL));
- }
- if (bb->nnl)
- bb = mkbb(cfg);
- label(cfg, nl[i], bb);
- break;
case Nexpr:
- if (addnode(cfg, bb, nl[i]))
+ if (islabel(nl[i]))
+ bb = addlabel(cfg, bb, nl, i);
+ else if (addnode(cfg, bb, nl[i]))
bb = mkbb(cfg);
break;
+ break;
case Ndecl:
break;
default:
@@ -104,16 +133,16 @@
break;
}
if (a) {
- targ = htget(cfg->lblmap, a->lbl.name);
+ targ = htget(cfg->lblmap, lblstr(a));
if (!targ)
- die("No bb with label %s", a->lbl.name);
+ die("No bb with label %s", lblstr(a));
bsput(bb->succ, targ->id);
bsput(targ->pred, bb->id);
}
if (b) {
- targ = htget(cfg->lblmap, b->lbl.name);
+ targ = htget(cfg->lblmap, lblstr(b));
if (!targ)
- die("No bb with label %s", b->lbl.name);
+ die("No bb with label %s", lblstr(b));
bsput(bb->succ, targ->id);
bsput(targ->pred, bb->id);
}
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -185,6 +185,7 @@
case Lint: fprintf(fd, " Lint %llu\n", n->lit.intval); break;
case Lflt: fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
case Lstr: fprintf(fd, " Lstr %s\n", n->lit.strval); break;
+ case Llbl: fprintf(fd, " Llbl %s\n", n->lit.lblval); break;
case Lfunc:
fprintf(fd, " Lfunc\n");
outnode(n->lit.fnval, fd, depth+1);
@@ -204,9 +205,6 @@
indent(fd, depth);
fprintf(fd, ")\n");
outnode(n->func.body, fd, depth+1);
- break;
- case Nlbl:
- fprintf(fd, "(lbl = %s)\n", n->lbl.name);
break;
case Nname:
fprintf(fd, "(");
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -319,6 +319,7 @@
case Lint: return mktylike(n->line, Tyint); break;
case Lflt: return mktylike(n->line, Tyfloat32); break;
case Lstr: return mktyslice(n->line, mktype(n->line, Tybyte)); break;
+ case Llbl: return mktyptr(n->line, mktype(n->line, Tyvoid)); break;
case Lfunc: return n->lit.fnval->func.type; break;
case Lseq: return NULL; break;
};
@@ -528,8 +529,8 @@
/* Unifies two types, or errors if the types are not unifiable. */
static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b)
{
- Type *t;
- Type *r;
+ Type *t, *r;
+ char *from, *to;
size_t i;
/* a ==> b */
@@ -537,6 +538,8 @@
b = tf(st, b);
if (a == b)
return a;
+
+ /* we unify from lower to higher ranked types */
if (tyrank(b) < tyrank(a)) {
t = a;
a = b;
@@ -543,6 +546,14 @@
b = t;
}
+ if (debugopt['u']) {
+ from = tystr(a);
+ to = tystr(b);
+ printf("Unify %s => %s", from, to);
+ free(from);
+ free(to);
+ }
+
r = NULL;
if (a->type == Tyvar) {
tytab[a->tid] = b;
@@ -1131,7 +1142,6 @@
case Nname:
case Nlit:
case Nuse:
- case Nlbl:
break;
case Nnone:
die("Nnone should not be seen as node type!");
@@ -1332,7 +1342,6 @@
break;
case Nname:
case Nuse:
- case Nlbl:
break;
case Nnone:
die("Nnone should not be seen as node type!");
--- a/parse/lits.def
+++ b/parse/lits.def
@@ -5,3 +5,4 @@
L(Lstr)
L(Lfunc)
L(Lseq)
+L(Llbl)
--- a/parse/node.c
+++ b/parse/node.c
@@ -181,9 +181,11 @@
{
Node *n;
- n = mknode(line, Nlbl);
- n->lbl.name = strdup(lbl);
- return n;
+ assert(lbl != NULL);
+ n = mknode(line, Nlit);
+ n->lit.littype = Llbl;
+ n->lit.lblval = strdup(lbl);
+ return mkexpr(line, Olit, n, NULL);
}
Node *mkstr(int line, char *val)
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -11,4 +11,3 @@
N(Nname)
N(Ndecl)
N(Nfunc)
-N(Nlbl)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -182,6 +182,7 @@
double fltval;
unichar chrval;
char *strval;
+ char *lblval;
int boolval;
Node *fnval;
Node **seqval;
@@ -217,10 +218,6 @@
size_t nstmts;
Node **stmts;
} block;
-
- struct {
- char *name;
- } lbl;
struct {
size_t did;
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -339,6 +339,7 @@
case Lint: wrint(fd, n->lit.intval); break;
case Lflt: wrflt(fd, n->lit.fltval); break;
case Lstr: wrstr(fd, n->lit.strval); break;
+ case Llbl: wrstr(fd, n->lit.lblval); break;
case Lbool: wrbool(fd, n->lit.boolval); break;
case Lfunc: pickle(n->lit.fnval, fd); break;
case Lseq:
@@ -374,9 +375,6 @@
for (i = 0; i < n->block.nstmts; i++)
pickle(n->block.stmts[i], fd);
break;
- case Nlbl:
- wrstr(fd, n->lbl.name);
- break;
case Ndecl:
/* sym */
pickle(n->decl.name, fd);
@@ -460,6 +458,7 @@
case Lint: n->lit.intval = rdint(fd); break;
case Lflt: n->lit.fltval = rdflt(fd); break;
case Lstr: n->lit.strval = rdstr(fd); break;
+ case Llbl: n->lit.lblval = rdstr(fd); break;
case Lbool: n->lit.boolval = rdbool(fd); break;
case Lfunc: n->lit.fnval = unpickle(fd); break;
case Lseq:
@@ -498,9 +497,6 @@
for (i = 0; i < n->block.nstmts; i++)
n->block.stmts[i] = unpickle(fd);
popstab();
- break;
- case Nlbl:
- n->lbl.name = rdstr(fd);
break;
case Ndecl:
n->decl.did = maxdid++; /* unique within file */
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -129,7 +129,8 @@
for (i = 0; i < n->lit.nelt; i++)
fixup(n->lit.seqval[i]);
break;
- case Lchr: case Lint: case Lflt: case Lstr: case Lbool:
+ case Lchr: case Lint: case Lflt:
+ case Lstr: case Llbl: case Lbool:
break;
}
break;
@@ -166,7 +167,7 @@
fixup(n->func.body);
popstab();
break;
- case Nnone: case Nlbl: case Nname:
+ case Nnone: case Nname:
break;
}
}
@@ -212,6 +213,7 @@
case Lint: r->lit.intval = n->lit.intval; break;
case Lflt: r->lit.fltval = n->lit.fltval; break;
case Lstr: r->lit.strval = n->lit.strval; break;
+ case Llbl: r->lit.lblval = n->lit.lblval; break;
case Lbool: r->lit.boolval = n->lit.boolval; break;
case Lfunc: r->lit.fnval = specializenode(n->lit.fnval, tsmap); break;
case Lseq:
@@ -251,9 +253,6 @@
for (i = 0; i < n->block.nstmts; i++)
r->block.stmts[i] = specializenode(n->block.stmts[i], tsmap);
popstab();
- break;
- case Nlbl:
- r->lbl.name = strdup(n->lbl.name);
break;
case Ndecl:
r->decl.did = maxdid++;