shithub: mc

Download patch

ref: 945c62edc1fc6dd17e1883dab8b7bc11d16276ba
parent: c4b85bb8c16c1a80775985774aabda635b43d694
author: Ori Bernstein <[email protected]>
date: Tue Jan 7 08:27:05 EST 2014

Start work on global const slices.

--- a/6/isel.c
+++ b/6/isel.c
@@ -35,7 +35,7 @@
 
 /* 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 @@
     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 @@
         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));
 }
--- a/6/simp.c
+++ b/6/simp.c
@@ -1613,11 +1613,16 @@
             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 {
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -115,7 +115,7 @@
 	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 @@
 	lines = strsplit(h, "\n")
 	for l in lines
 		match strfind(l, "#")
-		| `Some idx: l = l[:idx]
+		| `Some _idx: l = l[:_idx]
 		| `None:
 		;;
 
--- a/mi/fold.c
+++ b/mi/fold.c
@@ -45,6 +45,11 @@
     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 @@
         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:
--- a/test/constslice.myr
+++ b/test/constslice.myr
@@ -6,7 +6,7 @@
 const main = {
 	/* expected output 23 */
 	for x in sl
-		std.put("%i\n", x)
+		std.put("%i", x)
 	;;
 	std.put("\n")
 }