shithub: mc

Download patch

ref: 0c67d98527f61a1ccef4b082d484c82b58876b80
parent: 184dbb71cbea184856fc28c94f17f19b567472fe
author: Ori Bernstein <[email protected]>
date: Tue Aug 19 12:00:07 EDT 2014

Refactor towards supporting struct compares.

    Still not supported, but it should be easier to do now.

--- a/6/simp.c
+++ b/6/simp.c
@@ -62,7 +62,7 @@
 static Node *simpcast(Simp *s, Node *val, Type *to);
 static Node *simpslice(Simp *s, Node *n, Node *dst);
 static Node *idxaddr(Simp *s, Node *seq, Node *idx);
-static void umatch(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse);
+static void matchpattern(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse);
 
 /* useful constants */
 static Type *tyintptr;
@@ -589,7 +589,7 @@
     cjmp(s, done, lmatch, lend);
     simp(s, lmatch);
     val = load(idxaddr(s, seq, idx));
-    umatch(s, n->iterstmt.elt, val, val->expr.type, lbody, lstep);
+    matchpattern(s, n->iterstmt.elt, val, val->expr.type, lbody, lstep);
     simp(s, lend);
 
     s->nloopstep--;
@@ -635,7 +635,7 @@
         return load(addk(addr(s, n, t), Wordsz));
 }
 
-static void umatch(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse)
+static void matchpattern(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse)
 {
     Node *v, *x, *y;
     Node *deeper, *next;
@@ -711,7 +711,7 @@
                 off = alignto(off, exprtype(patarg[i]));
                 next = genlbl();
                 v = load(addk(addr(s, val, exprtype(patarg[i])), off));
-                umatch(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
+                matchpattern(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
                 append(s, next);
                 off += size(patarg[i]);
             }
@@ -733,7 +733,7 @@
             if (uc->etype) {
                 pat = patval(s, pat, uc->etype);
                 val = patval(s, val, uc->etype);
-                umatch(s, pat, val, uc->etype, iftrue, iffalse);
+                matchpattern(s, pat, val, uc->etype, iftrue, iffalse);
             }
             break;
     }
@@ -757,7 +757,7 @@
         /* check pattern */
         cur = genlbl();
         next = genlbl();
-        umatch(s, m->match.pat, val, val->expr.type, cur, next);
+        matchpattern(s, m->match.pat, val, val->expr.type, cur, next);
 
         /* do the action if it matches */
         append(s, cur);
@@ -1292,6 +1292,44 @@
     return r;
 }
 
+static Node *comparecomplex(Simp *s, Node *n, Op op)
+{
+    fatal(n->line, "Complex comparisons not yet supported\n");
+}
+
+static Node *compare(Simp *s, Node *n, int fields)
+{
+    const Op cmpmap[Numops][3] = {
+        [Oeq]   = {Oeq, Oueq, Ofeq},
+        [One]   = {One, Oune, Ofne},
+        [Ogt]   = {Ogt, Ougt, Ofgt},
+        [Oge]   = {Oge, Ouge, Ofge},
+        [Olt]   = {Olt, Oult, Oflt},
+        [Ole]   = {Ole, Oule, Ofle}
+    };
+    Node *r;
+    Op newop;
+
+    newop = Obad;
+    if (istysigned(tybase(exprtype(n->expr.args[0]))))
+        newop = cmpmap[n->expr.op][0];
+    else if (istyunsigned(tybase(exprtype(n->expr.args[0]))))
+        newop = cmpmap[n->expr.op][1];
+    else if (istyfloat(tybase(exprtype(n->expr.args[0]))))
+        newop = cmpmap[n->expr.op][2];
+
+    if (newop != Obad) {
+        n->expr.op = newop;
+        r = visit(s, n);
+    } else if (fields) {
+        r = comparecomplex(s, n, exprop(n));
+    } else {
+        fatal(n->line, "unsupported comparison on values");
+    }
+    return r;
+}
+
+
 static Node *rval(Simp *s, Node *n, Node *dst)
 {
     Node *r; /* expression result */
@@ -1310,14 +1348,6 @@
         [Obsleq]        = Obsl,
         [Obsreq]        = Obsr,
     };
-    const Op cmpmap[Numops][3] = {
-        [Oeq]   = {Oeq, Ofeq, Oueq},
-        [One]   = {One, Ofne, Oune},
-        [Ogt]   = {Ogt, Ofgt, Ougt},
-        [Oge]   = {Oge, Ofge, Ouge},
-        [Olt]   = {Olt, Oflt, Oult},
-        [Ole]   = {Ole, Ofle, Oule}
-    };
 
     r = NULL;
     args = n->expr.args;
@@ -1503,15 +1533,11 @@
                 fatal(n->line, "trying to continue when not in loop");
             jmp(s, s->loopstep[s->nloopstep - 1]);
             break;
-        case Oeq: case One: case Ogt: case Oge: case Olt: case Ole:
-            if (istyfloat(tybase(exprtype(args[0]))))
-                i = 1;
-            else if (istysigned(tybase(exprtype(args[0]))))
-                i = 0;
-            else
-                i = 2;
-            n->expr.op = cmpmap[n->expr.op][i];
-            r = visit(s, n);
+        case Oeq: case One:
+            r = compare(s, n, 1);
+            break;
+        case Ogt: case Oge: case Olt: case Ole:
+            r = compare(s, n, 0);
             break;
         default:
             if (istyfloat(exprtype(n))) {
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -429,6 +429,7 @@
 Trait *mktrait(int line, Node *name, Type *param, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs, int isproto);
 Type *mktylike(int line, Ty ty); /* constrains tyvar t like it was builtin ty */
 int   istysigned(Type *t);
+int   istyunsigned(Type *t);
 int   istyfloat(Type *t);
 int   isgeneric(Type *t);
 int   hasparams(Type *t);
--- a/parse/type.c
+++ b/parse/type.c
@@ -270,6 +270,17 @@
     return t;
 }
 
+int istyunsigned(Type *t)
+{
+    switch (tybase(t)->type) {
+        case Tybyte: case Tyuint8: case Tyuint16: case Tyuint:
+        case Tychar: case Tyuint32: case Tyuint64: case Tyulong:
+            return 1;
+        default:
+            return 0;
+    }
+}
+
 int istysigned(Type *t)
 {
     switch (tybase(t)->type) {
--- a/test/tests
+++ b/test/tests
@@ -66,6 +66,7 @@
 B condiffalse	E	9
 B condifrel	E	7
 B overlappingif	E	2
+#B bigcondarg	C       ## BUGGERED
 B fib		E	21
 B basicfloat	E	84
 B sqrt		E	4