shithub: mc

Download patch

ref: 79dbe0f5f75ea9da8f5b33b2c96842223ade42c7
parent: a7951ace877710b07cdf88cd7f5fcfe8c28b449e
author: Ori Bernstein <[email protected]>
date: Sun Jul 15 22:17:44 EDT 2012

We now make a valiant attempt at destructuring tuples.

--- a/8/isel.c
+++ b/8/isel.c
@@ -157,9 +157,10 @@
 static void load(Isel *s, Loc *a, Loc *b)
 {
     Loc *l;
+
     assert(b->type == Locreg);
     if (a->type == Locreg)
-        locmem(0, b, Rnone, a->mode);
+        l = locmem(0, b, Rnone, a->mode);
     else
         l = a;
     g(s, Imov, l, b, NULL);
@@ -171,7 +172,7 @@
 
     assert(a->type == Locreg || a->type == Loclit);
     if (b->type == Locreg)
-        locmem(0, b, Rnone, b->mode);
+        l = locmem(0, b, Rnone, b->mode);
     else
         l = b;
     g(s, Imov, a, l, NULL);
--- a/8/ra.c
+++ b/8/ra.c
@@ -661,6 +661,7 @@
     Loc *m;
 
     /* FIXME: pick a better heuristic for spilling */
+    m = NULL;
     for (i = 0; i < s->nwlspill; i++) {
         if (!bshas(s->spilled, s->wlspill[i]->reg.id)) {
             m = s->wlspill[i];
--- a/8/simp.c
+++ b/8/simp.c
@@ -700,14 +700,37 @@
     return r;
 }
 
+Node *destructure(Simp *s, Node *lhs, Node *rhs)
+{
+    Node *plv, *prv, *lv, *sz, *stor, **args;
+    size_t off, i;
+
+    args = lhs->expr.args;
+    rhs = rval(s, rhs, NULL);
+    off = 0;
+    for (i = 0; i < lhs->expr.nargs; i++) {
+        lv = lval(s, args[i]);
+        prv = add(addr(rhs, exprtype(args[i])), word(rhs->line, off));
+        if (size(args[i]) > Wordsz) {
+            sz = word(lhs->line, size(lv));
+            plv = addr(lv, exprtype(lv));
+            stor = mkexpr(lhs->line, Oblit, plv, prv, sz, NULL);
+        } else {
+            stor = store(lv, load(prv));
+        }
+        append(s, stor);
+        off += size(args[i]);
+    }
+
+    return NULL;
+}
+
 Node *assign(Simp *s, Node *lhs, Node *rhs)
 {
     Node *t, *u, *v, *r;
 
     if (exprop(lhs) == Otup) {
-        /* destructuring bind */
-        die("No destructuring binds implemented yet");
-        r = NULL;
+        r = destructure(s, lhs, rhs);
     } else {
         t = lval(s, lhs);
         u = rval(s, rhs, t);
@@ -766,6 +789,7 @@
 
     /* find the ucon we're constructing here */
     ty = tybase(n->expr.type);
+    uc = NULL;
     for (i = 0; i < ty->nmemb; i++) {
         if (!strcmp(namestr(n->expr.args[0]), namestr(ty->udecls[i]->name))) {
             uc = ty->udecls[i];
@@ -772,6 +796,8 @@
             break;
         }
     }
+    if (!uc)
+        die("Couldn't find union constructor");
 
     if (dst)
         tmp = dst;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -544,7 +544,7 @@
             types = xalloc(sizeof(Type *)*n->expr.nargs);
             for (i = 0; i < n->expr.nargs; i++)
                 types[i] = type(n->expr.args[i]);
-            settype(n, mktytuple(n->line, types, n->lit.nelt));
+            settype(n, mktytuple(n->line, types, n->expr.nargs));
             break;
         case Oarr:
             for (i = 0; i < n->expr.nargs; i++)
--- a/parse/type.c
+++ b/parse/type.c
@@ -182,7 +182,7 @@
     Type *t;
     size_t i;
 
-    t = mkty(line, Tyfunc);
+    t = mkty(line, Tytuple);
     t->nsub = nsub;
     t->sub = xalloc(nsub*sizeof(Type));
     for (i = 0; i < nsub; i++)
@@ -392,7 +392,7 @@
             break;
         case Tytuple:
             p += snprintf(p, end - p, "[");
-            for (i = 1; i < t->nsub; i++) {
+            for (i = 0; i < t->nsub; i++) {
                 p += snprintf(p, end - p, "%s", sep);
                 p += tybfmt(p, end - p, t->sub[i]);
                 sep = ", ";