summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-01-07 13:27:05 -0500
committerOri Bernstein <ori@eigenstate.org>2014-01-07 13:27:05 -0500
commit945c62edc1fc6dd17e1883dab8b7bc11d16276ba (patch)
tree23c8e4ba8c9e905f4545eaab538a1c4ff0c5060b
parentc4b85bb8c16c1a80775985774aabda635b43d694 (diff)
downloadmc-945c62edc1fc6dd17e1883dab8b7bc11d16276ba.tar.gz
Start work on global const slices.
-rw-r--r--6/isel.c62
-rw-r--r--6/simp.c15
-rw-r--r--libstd/resolve.myr4
-rw-r--r--mi/fold.c7
-rw-r--r--test/constslice.myr2
5 files changed, 60 insertions, 30 deletions
diff --git a/6/isel.c b/6/isel.c
index 9c5e5fc..a06b8bf 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -35,7 +35,7 @@ char* modenames[] = {
/* forward decls */
Loc *selexpr(Isel *s, Node *n);
-static void writeblob(FILE *fd, Htab *strtab, Node *blob);
+static void writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *blob);
/* used to decide which operator is appropriate
* for implementing various conditional operators */
@@ -1042,40 +1042,60 @@ static void writepad(FILE *fd, size_t sz)
fprintf(fd, "\t.fill %zd,1,0\n", sz);
}
-static void writetup(FILE *fd, Htab *strtab, Node *n)
+static void writeexprs(FILE *fd, Htab *globls, Htab *strtab, Node **e, size_t n)
{
size_t i;
- for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, strtab, n->expr.args[i]);
+ for (i = 0; i < n; i++) {
+ writeblob(fd, globls, strtab, e[i]);
}
}
-static void writearr(FILE *fd, Htab *strtab, Node *n)
+static size_t getintlit(Node *n, char *failmsg)
{
- size_t i;
-
- for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, strtab, n->expr.args[i]);
- }
+ if (exprop(n) != Olit)
+ fatal(n->line, "%s");
+ n = n->expr.args[0];
+ if (n->lit.littype != Lint)
+ fatal(n->line, "%s");
+ return n->lit.intval;
}
-static void writestruct(FILE *fd, Htab *strtab, Node *n)
+static void writeslice(FILE *fd, Htab *globls, Htab *strtab, Node *n)
{
- size_t i;
+ Node *base, *lo, *hi;
+ ssize_t loval, hival, sz;
+ char *lbl;
- for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, strtab, n->expr.args[i]);
- }
+ base = n->expr.args[0];
+ lo = n->expr.args[1];
+ hi = n->expr.args[2];
+
+ if (exprop(base) != Ovar || !base->expr.isconst)
+ fatal(base->line, "slice base is not a constant value");
+ loval = getintlit(lo, "lower bound in slice is not constant literal");
+ hival = getintlit(hi, "upper bound in slice is not constant literal");
+ sz = tysize(tybase(exprtype(base))->sub[0]);
+
+ lbl = htget(globls, base);
+ fprintf(fd, "\t.quad %s + (%zd*%zd)\n", lbl, loval, sz);
+ fprintf(fd, "\t.quad %zd\n", (hival - loval));
}
-static void writeblob(FILE *fd, Htab *strtab, Node *n)
+static void writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *n)
{
switch(exprop(n)) {
- case Otup: writetup(fd, strtab, n); break;
- case Oarr: writearr(fd, strtab, n); break;
- case Ostruct: writestruct(fd, strtab, n); break;
- case Olit: writelit(fd, strtab, n->expr.args[0], size(n)); break;
+ case Otup:
+ case Oarr:
+ case Ostruct:
+ writeexprs(fd, globls, strtab, n->expr.args, n->expr.nargs);
+ break;
+ case Olit:
+ writelit(fd, strtab, n->expr.args[0], size(n));
+ break;
+ case Oslice:
+ writeslice(fd, globls, strtab, n);
+ break;
default:
die("Nonliteral initializer for global");
break;
@@ -1094,7 +1114,7 @@ void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
fprintf(fd, ".globl %s\n", lbl);
fprintf(fd, "%s:\n", lbl);
if (blob->decl.init)
- writeblob(fd, strtab, blob->decl.init);
+ writeblob(fd, globls, strtab, blob->decl.init);
else
writepad(fd, size(blob));
}
diff --git a/6/simp.c b/6/simp.c
index 82a1b62..420c95f 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -1613,11 +1613,16 @@ static void simpconstinit(Simp *s, Node *dcl)
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) {
+ switch (exprop(e)) {
+ case Oarr:
+ case Ostruct:
+ case Oslice:
+ lappend(&s->blobs, &s->nblobs, dcl);
+ break;
+ default:
+ break;
+ }
} else if (!dcl->decl.isconst && !e) {
lappend(&s->blobs, &s->nblobs, dcl);
} else {
diff --git a/libstd/resolve.myr b/libstd/resolve.myr
index 5bea130..db7286c 100644
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -115,7 +115,7 @@ const loadhosts = {
for l in lines
/* trim comment */
match strfind(l, "#")
- | `Some idx: l = l[:idx]
+ | `Some _idx: l = l[:_idx]
;;
match word(l)
@@ -169,7 +169,7 @@ const loadresolv = {
lines = strsplit(h, "\n")
for l in lines
match strfind(l, "#")
- | `Some idx: l = l[:idx]
+ | `Some _idx: l = l[:_idx]
| `None:
;;
diff --git a/mi/fold.c b/mi/fold.c
index 5e16f18..e8d93eb 100644
--- a/mi/fold.c
+++ b/mi/fold.c
@@ -45,6 +45,11 @@ static Node *val(int line, vlong val, Type *t)
return n;
}
+static int issmallconst(Node *dcl)
+{
+ return dcl->decl.isconst && exprop(dcl->decl.init) == Olit;
+}
+
Node *fold(Node *n, int foldvar)
{
Node **args, *r;
@@ -62,7 +67,7 @@ Node *fold(Node *n, int foldvar)
args[i] = fold(args[i], foldvar);
switch (exprop(n)) {
case Ovar:
- if (foldvar && decls[n->expr.did]->decl.isconst)
+ if (foldvar && issmallconst(decls[n->expr.did]))
r = fold(decls[n->expr.did]->decl.init, foldvar);
break;
case Oadd:
diff --git a/test/constslice.myr b/test/constslice.myr
index c14fd09..4b43a37 100644
--- a/test/constslice.myr
+++ b/test/constslice.myr
@@ -6,7 +6,7 @@ const array = [1,2,3,4,5]
const main = {
/* expected output 23 */
for x in sl
- std.put("%i\n", x)
+ std.put("%i", x)
;;
std.put("\n")
}