ref: 8c2fb645b95fa69e53e910102c601f3a80007251
parent: bc18d36c3cf2e2ceea1e78a21242423d6878ed12
author: Ori Bernstein <[email protected]>
date: Tue Jun 18 08:59:26 EDT 2013
Move away from literal types that aren't actual compile time constants.
--- a/6/isel.c
+++ b/6/isel.c
@@ -34,7 +34,9 @@
/* forward decls */
Loc *selexpr(Isel *s, Node *n);
+static void writeblob(FILE *fd, Node *blob);
+
/* used to decide which operator is appropriate
* for implementing various conditional operators */
struct {
@@ -84,16 +86,16 @@
switch (exprop(n)) {
case Ovar:
- if (hthas(s->stkoff, n)) {
- stkoff = (ssize_t)htget(s->stkoff, n);
- l = locmem(-stkoff, locphysreg(Rrbp), NULL, mode(n));
- } else if (hthas(s->globls, n)) {
+ if (hthas(s->globls, n)) {
if (tybase(exprtype(n))->type == Tyfunc)
rip = NULL;
else
rip = locphysreg(Rrip);
l = locmeml(htget(s->globls, n), rip, NULL, mode(n));
- } else {
+ } else if (hthas(s->stkoff, n)) {
+ stkoff = (ssize_t)htget(s->stkoff, n);
+ l = locmem(-stkoff, locphysreg(Rrbp), NULL, mode(n));
+ } else {
if (!hthas(s->reglocs, n))
htput(s->reglocs, n, locreg(mode(n)));
return htget(s->reglocs, n);
@@ -614,7 +616,7 @@
case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
case Oslice: case Oidx: case Osize: case Numops:
- case Oucon: case Ouget: case Otup: case Oarr:
+ case Oucon: case Ouget: case Otup: case Oarr: case Ostruct:
case Oslbase: case Osllen: case Ocast:
dump(n, stdout);
die("Should not see %s in isel", opstr(exprop(n)));
@@ -854,7 +856,7 @@
return as;
}
-static void writeblob(FILE *fd, char *p, size_t sz)
+static void writebytes(FILE *fd, char *p, size_t sz)
{
size_t i;
@@ -861,8 +863,8 @@
for (i = 0; i < sz; i++) {
if (i % 60 == 0)
fprintf(fd, "\t.ascii \"");
- if (p[i] == '"')
- fprintf(fd, "\\");
+ if (p[i] == '"')
+ fprintf(fd, "\\");
if (isprint(p[i]))
fprintf(fd, "%c", p[i]);
else
@@ -876,8 +878,6 @@
static void writelit(FILE *fd, Node *v, size_t sz)
{
char lbl[128];
- size_t i;
- Node *val;
char *intsz[] = {
[1] = ".byte",
[2] = ".short",
@@ -887,27 +887,15 @@
assert(v->type == Nlit);
switch (v->lit.littype) {
+ case Lint: fprintf(fd, "\t%s %lld\n", intsz[sz], v->lit.intval); break;
case Lbool: fprintf(fd, "\t.byte %d\n", v->lit.boolval); break;
case Lchr: fprintf(fd, "\t.long %d\n", v->lit.chrval); break;
- case Lint: fprintf(fd, "\t%s %lld\n", intsz[sz], v->lit.intval); break;
case Lflt: fprintf(fd, "\t.double %f\n", v->lit.fltval); break;
case Lstr: fprintf(fd, "\t.quad %s\n", genlblstr(lbl, 128));
fprintf(fd, "\t.quad %zd\n", strlen(v->lit.strval));
fprintf(fd, "%s:\n", lbl);
- writeblob(fd, v->lit.strval, strlen(v->lit.strval));
+ writebytes(fd, v->lit.strval, strlen(v->lit.strval));
break;
- case Larray:
- for (i = 0; i < v->lit.nelt; i++) {
- val = v->lit.seqval[i]->idxinit.init;
- writelit(fd, val->expr.args[0], size(val));
- }
- break;
- case Lstruct:
- for (i = 0; i < v->lit.nelt; i++) {
- val = v->lit.seqval[i]->idxinit.init;
- writelit(fd, val->expr.args[0], size(val));
- }
- break;
case Lfunc:
die("Generating this shit ain't ready yet ");
break;
@@ -917,9 +905,56 @@
}
}
-void genblob(FILE *fd, Node *blob, Htab *globls)
+static void writepad(FILE *fd, size_t sz)
{
size_t i;
+
+ for (i = 0; i < sz; i++)
+ fprintf(fd, "\t.byte 0\n");
+}
+
+static void writetup(FILE *fd, Node *n)
+{
+ size_t i;
+
+ for (i = 0; i < n->expr.nargs; i++) {
+ writeblob(fd, n->expr.args[i]);
+ }
+}
+
+static void writearr(FILE *fd, Node *n)
+{
+ size_t i;
+
+ for (i = 0; i < n->expr.nargs; i++) {
+ writeblob(fd, n->expr.args[i]);
+ }
+}
+
+static void writestruct(FILE *fd, Node *n)
+{
+ size_t i;
+
+ for (i = 0; i < n->expr.nargs; i++) {
+ writeblob(fd, n->expr.args[i]);
+ }
+}
+
+static void writeblob(FILE *fd, Node *n)
+{
+ switch(exprop(n)) {
+ case Otup: writetup(fd, n); break;
+ case Oarr: writearr(fd, n); break;
+ case Ostruct: writestruct(fd, n); break;
+ case Olit: writelit(fd, n->expr.args[0], size(n)); break;
+ default:
+ die("Nonliteral initializer for global");
+ break;
+ }
+}
+
+void genblob(FILE *fd, Node *blob, Htab *globls)
+{
char *lbl;
/* lits and such also get wrapped in decls */
@@ -929,14 +964,10 @@
if (blob->decl.isexport)
fprintf(fd, ".globl %s\n", lbl);
fprintf(fd, "%s:\n", lbl);
- if (blob->decl.init) {
- if (exprop(blob->decl.init) != Olit)
- die("Nonliteral initializer for global");
- writelit(fd, blob->decl.init->expr.args[0], size(blob));
- } else {
- for (i = 0; i < size(blob); i++)
- fprintf(fd, "\t.byte 0\n");
- }
+ if (blob->decl.init)
+ writeblob(fd, blob->decl.init);
+ else
+ writepad(fd, size(blob));
}
/* genasm requires all nodes in 'nl' to map cleanly to operations that are
--- a/6/simp.c
+++ b/6/simp.c
@@ -54,6 +54,7 @@
static Node *assign(Simp *s, Node *lhs, Node *rhs);
static void declarelocal(Simp *s, Node *n);
static void simpcond(Simp *s, Node *n, Node *ltrue, Node *lfalse);
+static void simpconstinit(Simp *s, Node *dcl);
/* useful constants */
static Type *tyintptr;
@@ -932,6 +933,7 @@
off = 0;
for (i = 0; i < n->expr.nargs; i++) {
+ off = align(off, size(args[i]));
val = rval(s, args[i], NULL);
pdst = add(r, disp(n->line, off));
@@ -1157,7 +1159,7 @@
case Lchr: case Lbool: case Lint: case Llbl:
r = n;
break;
- case Lstr: case Lstruct: case Larray: case Lflt:
+ case Lstr: case Lflt:
r = simplit(s, n, &s->blobs, &s->nblobs);
break;
case Lfunc:
@@ -1203,6 +1205,20 @@
else
r = t->expr.args[0];
break;
+ case Oarr:
+ if (dst)
+ r = dst;
+ else
+ r = temp(s, n);
+ die("No initialization done yet");
+ break;
+ case Ostruct:
+ if (dst)
+ r = dst;
+ else
+ r = temp(s, n);
+ die("No initialization done yet");
+ break;
default:
r = visit(s, n);
}
@@ -1270,14 +1286,14 @@
case Ndecl:
declarelocal(s, n);
- if (n->decl.init) {
- t = mkexpr(n->line, Ovar, n->decl.name, NULL);
- u = mkexpr(n->line, Oasn, t, n->decl.init, NULL);
- u->expr.type = n->decl.type;
- t->expr.type = n->decl.type;
- t->expr.did = n->decl.did;
- simp(s, u);
- }
+ if (!n->decl.init)
+ break;
+ t = mkexpr(n->line, Ovar, n->decl.name, NULL);
+ u = mkexpr(n->line, Oasn, t, n->decl.init, NULL);
+ u->expr.type = n->decl.type;
+ t->expr.type = n->decl.type;
+ t->expr.did = n->decl.did;
+ simp(s, u);
break;
default:
die("Bad node passsed to simp()");
@@ -1331,8 +1347,6 @@
if(debugopt['i'])
printf("\n\nfunction %s\n", name);
- if (!n->decl.init)
- return NULL;
/* set up the simp context */
/* unwrap to the function body */
n = n->expr.args[0];
@@ -1395,8 +1409,31 @@
free(k);
}
-static void simpdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
+static void simpconstinit(Simp *s, Node *dcl)
{
+ Node *e;
+
+ dcl->decl.init = fold(dcl->decl.init);;
+ e = dcl->decl.init;
+ if (e && exprop(e) == Olit) {
+ if (e->expr.args[0]->lit.littype == Lfunc)
+ simplit(s, e->expr.args[0], &file->file.stmts, &file->file.nstmts);
+ else
+ lappend(&s->blobs, &s->nblobs, dcl);
+ } else if (dcl->decl.isconst && exprop(e) == Oarr) {
+ lappend(&s->blobs, &s->nblobs, dcl);
+ } else if (dcl->decl.isconst && exprop(e) == Ostruct) {
+ lappend(&s->blobs, &s->nblobs, dcl);
+ /* uninitialized global vars get zero-initialized decls */
+ } else if (!dcl->decl.isconst && !e) {
+ lappend(&s->blobs, &s->nblobs, dcl);
+ } else {
+ fatal(dcl->line, "Declaration %s initialized with nonconstant value", declname(dcl));
+ }
+}
+
+static void simpglobl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
+{
Simp s = {0,};
char *name;
Func *f;
@@ -1413,14 +1450,7 @@
lappend(fn, nfn, f);
}
} else {
- dcl->decl.init = fold(dcl->decl.init);
- if (dcl->decl.init && exprop(dcl->decl.init) == Olit)
- lappend(&s.blobs, &s.nblobs, dcl);
- /* uninitialized global vars get zero-initialized decls */
- else if (!dcl->decl.isconst && !dcl->decl.init)
- lappend(&s.blobs, &s.nblobs, dcl);
- else
- die("We don't simp globls with nonlit inits yet...");
+ simpconstinit(&s, dcl);
}
*blob = s.blobs;
*nblob = s.nblobs;
@@ -1457,7 +1487,7 @@
case Nuse: /* nothing to do */
break;
case Ndecl:
- simpdcl(n, globls, &fn, &nfn, &blob, &nblob);
+ simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
break;
default:
die("Bad node %s in toplevel", nodestr(n->type));
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -154,7 +154,7 @@
}
const intfmt = {buf, val, base
- var digits = [
+ const digits = [
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
]
var isneg
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -61,6 +61,7 @@
size_t i, n;
void **k;
char *ty;
+ Type *t;
indent(fd, depth);
fprintf(fd, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, namestr(st->name));
@@ -74,8 +75,9 @@
fprintf(fd, "T ");
/* already indented */
outname(k[i], fd);
- ty = tystr(gettype(st, k[i]));
- fprintf(fd, " = %s\n", ty);
+ t = gettype(st, k[i]);
+ ty = tystr(t);
+ fprintf(fd, " = %s [tid=%d]\n", ty, t->tid);
free(ty);
}
free(k);
@@ -172,9 +174,10 @@
break;
case Nexpr:
ty = tystr(n->expr.type);
- fprintf(fd, " (type = %s, op = %s, isconst = %d, did=%zd)\n",
- ty, opstr(n->expr.op), n->expr.isconst, n->expr.did);
+ fprintf(fd, " (type = %s [tid %d], op = %s, isconst = %d, did=%zd)\n",
+ ty, n->expr.type->tid, opstr(n->expr.op), n->expr.isconst, n->expr.did);
free(ty);
+ outnode(n->expr.idx, fd, depth + 1);
for (i = 0; i < n->expr.nargs; i++)
outnode(n->expr.args[i], fd, depth+1);
break;
@@ -190,16 +193,6 @@
fprintf(fd, " Lfunc\n");
outnode(n->lit.fnval, fd, depth+1);
break;
- case Larray:
- fprintf(fd, " Larray\n");
- for (i = 0; i < n->lit.nelt; i++)
- outnode(n->lit.seqval[i], fd, depth+1);
- break;
- case Lstruct:
- fprintf(fd, " Lstruct\n");
- for (i = 0; i < n->lit.nelt; i++)
- outnode(n->lit.seqval[i], fd, depth+1);
- break;
}
break;
case Nfunc:
@@ -221,11 +214,6 @@
case Nnone:
fprintf(stderr, "Nnone not a real node type!");
fprintf(fd, "Nnone\n");
- break;
- case Nidxinit:
- fprintf(fd, "\n");
- outnode(n->idxinit.idx, fd, depth + 1);
- outnode(n->idxinit.init, fd, depth + 1);
break;
}
}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -561,7 +561,7 @@
atomicexpr
: Tident
{$$ = mkexpr($1->line, Ovar, mkname($1->line, $1->str), NULL);}
- | literal {$$ = mkexpr($1->line, Olit, $1, NULL);}
+ | literal
| Toparen expr Tcparen
{$$ = $2;}
| Toparen tupbody Tcparen
@@ -586,9 +586,9 @@
{lappend(&$$.nl, &$$.nn, $3);}
;
-literal : funclit {$$ = $1;}
+literal : funclit {$$ = mkexpr($1->line, Olit, $1, NULL);}
+ | littok {$$ = mkexpr($1->line, Olit, $1, NULL);}
| seqlit {$$ = $1;}
- | littok {$$ = $1;}
;
littok : Tstrlit {$$ = mkstr($1->line, $1->str);}
@@ -613,9 +613,9 @@
;
seqlit : Tosqbrac arrayelts Tcsqbrac
- {$$ = mkarray($1->line, $2.nl, $2.nn);}
+ {$$ = mkexprl($1->line, Oarr, $2.nl, $2.nn);}
| Tosqbrac structelts Tcsqbrac
- {$$ = mkstruct($1->line, $2.nl, $2.nn);}
+ {$$ = mkexprl($1->line, Ostruct, $2.nl, $2.nn);}
;
arrayelts
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -58,8 +58,10 @@
char *s;
char *t;
char *u;
+ char *idx;
char buf[512];
+ idx = NULL;
switch (n->type) {
default:
s = nodestr(n->type);
@@ -75,6 +77,8 @@
s = namestr(n);
break;
case Nexpr:
+ if (n->expr.idx)
+ idx = ctxstr(st, n->expr.idx);
if (exprop(n) == Ovar)
u = namestr(n->expr.args[0]);
else
@@ -83,17 +87,13 @@
t = tystr(tf(st, exprtype(n)));
else
t = strdup("unknown");
- snprintf(buf, sizeof buf, "%s:%s", u, t);
- s = strdup(buf);
+ if (idx)
+ snprintf(buf, sizeof buf, ".%s=%s:%s", idx, u, t);
+ else
+ snprintf(buf, sizeof buf, "%s:%s", u, t);
+ free(idx);
free(t);
- break;
- case Nidxinit:
- t = ctxstr(st, n->idxinit.idx);
- u = ctxstr(st, n->idxinit.init);
- snprintf(buf, sizeof buf, "%s=%s", t, u);
s = strdup(buf);
- free(t);
- free(u);
break;
}
return s;
@@ -313,8 +313,6 @@
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 Lstruct: return NULL; break;
- case Larray: return NULL; break;
};
die("Bad lit type %d", n->lit.littype);
return NULL;
@@ -339,7 +337,6 @@
case Nexpr: t = n->expr.type; break;
case Ndecl: t = decltype(n); break;
case Nfunc: t = n->func.type; break;
- case Nidxinit: t = type(st, n->idxinit.init); break;
default:
t = NULL;
die("untypeable node %s", nodestr(n->type));
@@ -747,9 +744,9 @@
size_t i;
*isconst = 1;
- for (i = 0; i < n->lit.nelt; i++) {
- infernode(st, n->lit.seqval[i], NULL, NULL);
- if (!n->lit.seqval[i]->idxinit.init->expr.isconst)
+ for (i = 0; i < n->expr.nargs; i++) {
+ infernode(st, n->expr.args[i], NULL, NULL);
+ if (!n->expr.args[i]->expr.isconst)
*isconst = 0;
}
settype(st, n, mktyvar(n->line));
@@ -764,16 +761,28 @@
len = mkintlit(n->line, n->lit.nelt);
t = mktyarray(n->line, mktyvar(n->line), len);
- *isconst = 1;
- for (i = 0; i < n->lit.nelt; i++) {
- infernode(st, n->lit.seqval[i], NULL, NULL);
- unify(st, n, t->sub[0], type(st, n->lit.seqval[i]));
- if (!n->lit.seqval[i]->idxinit.init->expr.isconst)
+ for (i = 0; i < n->expr.nargs; i++) {
+ infernode(st, n->expr.args[i], NULL, NULL);
+ unify(st, n, t->sub[0], type(st, n->expr.args[i]));
+ if (!n->expr.args[i]->expr.isconst)
*isconst = 0;
}
settype(st, n, t);
}
+static void infertuple(Inferstate *st, Node *n, int *isconst)
+{
+ Type **types;
+ size_t i;
+
+ types = xalloc(sizeof(Type *)*n->expr.nargs);
+ for (i = 0; i < n->expr.nargs; i++) {
+ n->expr.isconst = n->expr.isconst && n->expr.args[i]->expr.isconst;
+ types[i] = type(st, n->expr.args[i]);
+ }
+ settype(st, n, mktytuple(n->line, types, n->expr.nargs));
+}
+
static void inferpat(Inferstate *st, Node *n, Node *val, Node ***bind, size_t *nbind)
{
size_t i;
@@ -839,7 +848,6 @@
static void inferexpr(Inferstate *st, Node *n, Type *ret, int *sawret)
{
Node **args;
- Type **types;
size_t i, nargs;
Ucon *uc;
Node *s;
@@ -858,6 +866,7 @@
inferexpr(st, args[i], ret, sawret);
}
}
+ infernode(st, n->expr.idx, NULL, NULL);
switch (exprop(n)) {
/* all operands are same type */
case Oadd: /* @a + @a -> @a */
@@ -988,15 +997,13 @@
settype(st, n, delayed(st, uc->utype));
break;
case Otup:
- types = xalloc(sizeof(Type *)*n->expr.nargs);
- for (i = 0; i < n->expr.nargs; i++)
- types[i] = type(st, n->expr.args[i]);
- settype(st, n, mktytuple(n->line, types, n->expr.nargs));
+ infertuple(st, n, &n->expr.isconst);
break;
+ case Ostruct:
+ inferstruct(st, n, &n->expr.isconst);
+ break;
case Oarr:
- for (i = 0; i < n->expr.nargs; i++)
- unify(st, n, type(st, n->expr.args[0]), type(st, n->expr.args[i]));
- settype(st, n, mktyarray(n->line, type(st, n->expr.args[0]), mkintlit(n->line, n->expr.nargs)));
+ inferarray(st, n, &n->expr.isconst);
break;
case Olit: /* <lit>:@a::tyclass -> @a */
switch (args[0]->lit.littype) {
@@ -1004,12 +1011,6 @@
infernode(st, args[0]->lit.fnval, NULL, NULL); break;
/* FIXME: env capture means this is non-const */
n->expr.isconst = 1;
- case Larray:
- inferarray(st, args[0], &n->expr.isconst);
- break;
- case Lstruct:
- inferstruct(st, args[0], &n->expr.isconst);
- break;
default:
n->expr.isconst = 1;
break;
@@ -1163,10 +1164,6 @@
inferfunc(st, n);
popstab();
break;
- case Nidxinit:
- infernode(st, n->idxinit.idx, NULL, NULL);
- infernode(st, n->idxinit.init, NULL, NULL);
- break;
case Nname:
case Nlit:
case Nuse:
@@ -1276,7 +1273,7 @@
static void checkstruct(Inferstate *st, Node *n)
{
Type *t, *et;
- Node *elt, *name, *val;
+ Node *val, *name;
size_t i, j;
t = tybase(tf(st, n->lit.type));
@@ -1283,10 +1280,9 @@
if (t->type != Tystruct)
fatal(n->line, "Type %s for struct literal is not struct near %s", tystr(t), ctxstr(st, n));
- for (i = 0; i < n->lit.nelt; i++) {
- elt = n->lit.seqval[i];
- name = elt->idxinit.idx;
- val = elt->idxinit.init;
+ for (i = 0; i < n->expr.nargs; i++) {
+ val = n->expr.args[i];
+ name = val->expr.idx;
et = NULL;
for (j = 0; j < t->nmemb; j++) {
@@ -1300,7 +1296,7 @@
fatal(n->line, "Could not find member %s in struct %s, near %s",
namestr(name), tystr(t), ctxstr(st, n));
- unify(st, elt, et, type(st, val));
+ unify(st, val, et, type(st, val));
}
}
@@ -1315,7 +1311,7 @@
infercompn(st, n);
else if (n->type == Nexpr && exprop(n) == Ocast)
checkcast(st, n);
- else if (n->type == Nlit && n->lit.littype == Lstruct)
+ else if (n->type == Nexpr && exprop(n) == Ostruct)
checkstruct(st, n);
else
die("Thing we shouldn't be checking in postcheck\n");
@@ -1398,6 +1394,7 @@
break;
case Nexpr:
settype(st, n, tyfix(st, n, type(st, n)));
+ typesub(st, n->expr.idx);
for (i = 0; i < n->expr.nargs; i++)
typesub(st, n->expr.args[i]);
break;
@@ -1414,20 +1411,8 @@
switch (n->lit.littype) {
case Lfunc:
typesub(st, n->lit.fnval); break;
- case Larray:
- for (i = 0; i < n->lit.nelt; i++)
- typesub(st, n->lit.seqval[i]);
- break;
- case Lstruct:
- for (i = 0; i < n->lit.nelt; i++)
- typesub(st, n->lit.seqval[i]);
- break;
default: break;
}
- break;
- case Nidxinit:
- typesub(st, n->idxinit.idx);
- typesub(st, n->idxinit.init);
break;
case Nname:
case Nuse:
--- a/parse/lits.def
+++ b/parse/lits.def
@@ -4,6 +4,4 @@
L(Lflt)
L(Lstr)
L(Lfunc)
-L(Lstruct)
-L(Larray)
L(Llbl)
--- a/parse/node.c
+++ b/parse/node.c
@@ -232,39 +232,10 @@
return n;
}
-Node *mkarray(int line, Node **vals, size_t nvals)
-{
- Node *n;
-
- n = mknode(line, Nlit);
- n->lit.littype = Larray;
- n->lit.nelt = nvals;
- n->lit.seqval = vals;
-
- return n;
-}
-
-Node *mkstruct(int line, Node **vals, size_t nvals)
-{
- Node *n;
-
- n = mknode(line, Nlit);
- n->lit.littype = Lstruct;
- n->lit.nelt = nvals;
- n->lit.seqval = vals;
-
- return n;
-}
-
Node *mkidxinit(int line, Node *idx, Node *init)
{
- Node *n;
-
- n = mknode(line, Nidxinit);
- n->idxinit.idx = idx;
- n->idxinit.init = init;
-
- return n;
+ init->expr.idx = idx;
+ return init;
}
Node *mkname(int line, char *name)
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -11,4 +11,3 @@
N(Nname)
N(Ndecl)
N(Nfunc)
-N(Nidxinit)
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -52,6 +52,7 @@
O(Oucon, 1)
O(Ouget, 1)
O(Otup, 1)
+O(Ostruct, 1)
O(Oarr, 1)
/* backend-only */
O(Ocjmp, 1) /* conditional jump */
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -168,6 +168,7 @@
int isconst;
size_t did; /* for Ovar, we want a mapping to the decl id */
size_t nargs;
+ Node *idx; /* used when this is in an indexed initializer */
Node **args;
} expr;
@@ -222,11 +223,6 @@
} match;
struct {
- Node *idx;
- Node *init;
- } idxinit;
-
- struct {
Stab *scope;
size_t nstmts;
Node **stmts;
@@ -400,9 +396,6 @@
Node *mkstr(int line, char *s);
Node *mkfloat(int line, double flt);
Node *mkfunc(int line, Node **args, size_t nargs, Type *ret, Node *body);
-Node *mkstruct(int line, Node **vals, size_t nvals);
-Node *mkarray(int line, Node **vals, size_t nvals);
-Node *mktuple(int line, Node **vals, size_t nvals);
Node *mkname(int line, char *name);
Node *mknsname(int line, char *ns, char *name);
Node *mkdecl(int line, Node *name, Type *ty);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -131,6 +131,7 @@
die("Node %s not allowed here\n", nodestr(n->type));
break;
case Nexpr:
+ fixup(n->expr.idx);
for (i = 0; i < n->expr.nargs; i++)
fixup(n->expr.args[i]);
if (n->expr.op == Ovar) {
@@ -145,14 +146,6 @@
case Nlit:
switch (n->lit.littype) {
case Lfunc: fixup(n->lit.fnval); break;
- case Larray:
- for (i = 0; i < n->lit.nelt; i++)
- fixup(n->lit.seqval[i]);
- break;
- case Lstruct:
- for (i = 0; i < n->lit.nelt; i++)
- fixup(n->lit.seqval[i]);
- break;
case Lchr: case Lint: case Lflt:
case Lstr: case Llbl: case Lbool:
break;
@@ -192,9 +185,6 @@
fixup(n->func.body);
popstab();
break;
- case Nidxinit:
- fixup(n->idxinit.idx);
- fixup(n->idxinit.init);
case Nnone: case Nname:
break;
}
@@ -224,6 +214,7 @@
r->expr.type = tysubst(n->expr.type, tsmap);
r->expr.isconst = n->expr.isconst;
r->expr.nargs = n->expr.nargs;
+ r->expr.idx = specializenode(n->expr.idx, tsmap);
r->expr.args = xalloc(n->expr.nargs * sizeof(Node*));
for (i = 0; i < n->expr.nargs; i++)
r->expr.args[i] = specializenode(n->expr.args[i], tsmap);
@@ -244,16 +235,6 @@
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 Larray:
- r->lit.seqval = xalloc(n->lit.nelt * sizeof(Node*));
- for (i = 0; i < n->lit.nelt; i++)
- r->lit.seqval[i] = specializenode(n->lit.seqval[i], tsmap);
- break;
- case Lstruct:
- r->lit.seqval = xalloc(n->lit.nelt * sizeof(Node*));
- for (i = 0; i < n->lit.nelt; i++)
- r->lit.seqval[i] = specializenode(n->lit.seqval[i], tsmap);
- break;
}
break;
case Nifstmt:
@@ -314,10 +295,6 @@
r->func.args[i] = specializenode(n->func.args[i], tsmap);
r->func.body = specializenode(n->func.body, tsmap);
popstab();
- break;
- case Nidxinit:
- r->idxinit.idx = specializenode(n->idxinit.idx, tsmap);
- r->idxinit.init = specializenode(n->idxinit.init, tsmap);
break;
case Nnone:
die("Nnone should not be seen as node type!");
--- a/parse/use.c
+++ b/parse/use.c
@@ -328,6 +328,7 @@
wrbyte(fd, n->expr.op);
wrtype(fd, n->expr.type);
wrbool(fd, n->expr.isconst);
+ pickle(n->expr.idx, fd);
wrint(fd, n->expr.nargs);
for (i = 0; i < n->expr.nargs; i++)
pickle(n->expr.args[i], fd);
@@ -355,14 +356,6 @@
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 Larray:
- for (i = 0; i < n->lit.nelt; i++)
- pickle(n->lit.seqval[i], fd);
- break;
- case Lstruct:
- for (i = 0; i < n->lit.nelt; i++)
- pickle(n->lit.seqval[i], fd);
- break;
}
break;
case Nloopstmt:
@@ -413,10 +406,6 @@
pickle(n->func.args[i], fd);
pickle(n->func.body, fd);
break;
- case Nidxinit:
- pickle(n->idxinit.idx, fd);
- pickle(n->idxinit.init, fd);
- break;
case Nnone:
die("Nnone should not be seen as node type!");
break;
@@ -456,6 +445,7 @@
n->expr.op = rdbyte(fd);
rdtype(fd, &n->expr.type);
n->expr.isconst = rdbool(fd);
+ n->expr.idx = unpickle(fd);
n->expr.nargs = rdint(fd);
n->expr.args = xalloc(sizeof(Node *)*n->expr.nargs);
for (i = 0; i < n->expr.nargs; i++)
@@ -482,14 +472,6 @@
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 Larray:
- for (i = 0; i < n->lit.nelt; i++)
- n->lit.seqval[i] = unpickle(fd);
- break;
- case Lstruct:
- for (i = 0; i < n->lit.nelt; i++)
- n->lit.seqval[i] = unpickle(fd);
- break;
}
break;
case Nloopstmt:
@@ -550,10 +532,6 @@
n->func.body = unpickle(fd);
popstab();
break;
- case Nidxinit:
- n->idxinit.idx = unpickle(fd);
- n->idxinit.init = unpickle(fd);
- break;
case Nnone:
die("Nnone should not be seen as node type!");
break;
@@ -745,6 +723,7 @@
nodetag(n->match.block);
break;
case Nexpr:
+ nodetag(n->expr.idx);
taghidden(n->expr.type);
for (i = 0; i < n->expr.nargs; i++)
nodetag(n->expr.args[i]);
@@ -751,19 +730,8 @@
break;
case Nlit:
taghidden(n->lit.type);
- switch (n->lit.littype) {
- case Lfunc: nodetag(n->lit.fnval); break;
- case Larray:
- for (i = 0; i < n->lit.nelt; i++)
- nodetag(n->lit.seqval[i]);
- break;
- case Lstruct:
- for (i = 0; i < n->lit.nelt; i++)
- nodetag(n->lit.seqval[i]);
- break;
- default:
- break;
- }
+ if (n->lit.littype == Lfunc)
+ nodetag(n->lit.fnval);
break;
case Ndecl:
taghidden(n->decl.type);
@@ -776,10 +744,6 @@
for (i = 0; i < n->func.nargs; i++)
nodetag(n->func.args[i]);
nodetag(n->func.body);
- break;
- case Nidxinit:
- nodetag(n->idxinit.idx);
- nodetag(n->idxinit.init);
break;
case Nuse: case Nname:
--- a/test/tests
+++ b/test/tests
@@ -71,6 +71,7 @@
B matchunion_sl P foo
B matchbind E 8
B arraylit-ni E 2
+B livearraylit E 21
# B arraylit E 3 ## BUGGERED
B structlit E 42
B livestructlit E 21