shithub: mc

Download patch

ref: c96b770a0aa93c1e7b99e5874808af85ddacc6a7
parent: 468265b7b2719d783afc46ea5aa7c9ffa3142970
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jan 6 08:29:51 EST 2015

Improve error messages.

    This involved lots of table changes.

--- a/6/gengas.c
+++ b/6/gengas.c
@@ -514,7 +514,7 @@
                 simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
                 break;
             default:
-                die("Bad node %s in toplevel", nodestr(n->type));
+                die("Bad node %s in toplevel", nodestr[n->type]);
                 break;
         }
     }
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -533,7 +533,7 @@
                 simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
                 break;
             default:
-                die("Bad node %s in toplevel", nodestr(n->type));
+                die("Bad node %s in toplevel", nodestr[n->type]);
                 break;
         }
     }
--- a/6/isel.c
+++ b/6/isel.c
@@ -102,11 +102,11 @@
                 case Lbool:     l = loclit(v->lit.boolval, mode(n)); break;
                 case Lint:      l = loclit(v->lit.intval, mode(n)); break;
                 default:
-                                die("Literal type %s should be blob", litstr(v->lit.littype));
+                                die("Literal type %s should be blob", litstr[v->lit.littype]);
             }
             break;
         default:
-            die("Node %s not leaf in loc()", opstr(exprop(n)));
+            die("Node %s not leaf in loc()", opstr[exprop(n)]);
             break;
     }
     return l;
@@ -648,7 +648,7 @@
             return r;
 
         case Oasn:  /* relabel */
-            die("Unimplemented op %s", opstr(exprop(n)));
+            die("Unimplemented op %s", opstr[exprop(n)]);
             break;
         case Oset:
             assert(exprop(args[0]) == Ovar || exprop(args[0]) == Oderef);
@@ -756,7 +756,7 @@
 		case Obreak: case Ocontinue:
 		case Numops:
             dump(n, stdout);
-            die("Should not see %s in isel", opstr(exprop(n)));
+            die("Should not see %s in isel", opstr[exprop(n)]);
             break;
     }
     return r;
--- a/6/simp.c
+++ b/6/simp.c
@@ -277,7 +277,7 @@
 
 static int ispure(Node *n)
 {
-    return ispureop[exprop(n)];
+    return opispure[exprop(n)];
 }
 
 static int isconstfn(Node *s)
@@ -822,7 +822,7 @@
         case Oderef:    r = deref(rval(s, args[0], NULL), NULL); break;
         case Omemb:     r = deref(membaddr(s, n), NULL); break;
         default:
-            fatal(n, "%s cannot be an lvalue", opstr(exprop(n)));
+            fatal(n, "%s cannot be an lvalue", opstr[exprop(n)]);
             break;
     }
     return r;
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -211,7 +211,7 @@
             case Ndecl:
                 break;
             default:
-                die("Invalid node type %s in mkcfg", nodestr(nl[i]->type));
+                die("Invalid node type %s in mkcfg", nodestr[nl[i]->type]);
         }
     }
     post = mkbb(cfg);
--- a/mi/match.c
+++ b/mi/match.c
@@ -224,7 +224,7 @@
             break;
         default:
             ret = NULL;
-            fatal(pat, "unsupported pattern %s of type %s", opstr(exprop(pat)), tystr(exprtype(pat)));
+            fatal(pat, "unsupported pattern %s of type %s", opstr[exprop(pat)], tystr(exprtype(pat)));
             break;
     }
     return ret;
@@ -332,7 +332,7 @@
         case Ovar:
             return namestr(n->expr.args[0]);
         case Olit:
-            return litstr(n->expr.args[0]->lit.littype);
+            return litstr[n->expr.args[0]->lit.littype];
         case Oucon:
             return namestr(n->expr.args[0]);
         case Otup:
@@ -354,7 +354,7 @@
     size_t i;
     if (dt->patexpr) {
         e = dt->patexpr;
-        indentf(depth, "%s%s %s : %s\n", iswild ? "WILDCARD " : "", opstr(exprop(e)), dtnodestr(e), tystr(exprtype(e)));
+        indentf(depth, "%s%s %s : %s\n", iswild ? "WILDCARD " : "", opstr[exprop(e)], dtnodestr(e), tystr(exprtype(e)));
     } 
     if (dt->cap)
         for (i = 0; i < dt->ncap; i++)
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -113,7 +113,7 @@
         findentf(fd, depth, "Nil\n");
         return;
     }
-    findentf(fd, depth, "%s.%zd@%i", nodestr(n->type), n->nid, lnum(n->loc));
+    findentf(fd, depth, "%s.%zd@%i", nodestr[n->type], n->nid, lnum(n->loc));
     switch(n->type) {
         case Nfile:
             fprintf(fd, "(name = %s)\n", n->file.files[0]);
@@ -191,7 +191,7 @@
             else
                 tid = -1;
             fprintf(fd, " (type = %s [tid %d], op = %s, isconst = %d, did=%zd)\n",
-                    ty, tid, opstr(n->expr.op), n->expr.isconst, n->expr.did);
+                    ty, 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++)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -56,6 +56,42 @@
 static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b);
 static Type *tf(Inferstate *st, Type *t);
 
+static void ctxstrcall(char *buf, size_t sz, Inferstate *st, Node *n)
+{
+    char *p, *end, *sep, *t;
+    size_t nargs, i;
+    Node **args;
+    Type *et;
+
+    args = n->expr.args;
+    nargs = n->expr.nargs;
+    p = buf;
+    end = buf + sz;
+    sep = "";
+
+    if (exprop(args[0]) == Ovar)
+        p += snprintf(p, end - p, "%s(", namestr(args[0]->expr.args[0]));
+    else
+        p += snprintf(p, end - p, "<e>(");
+    for (i = 1; i < nargs; i++) {
+        et = exprtype(args[i]);
+        if (et != NULL)
+            t = tystr(et);
+        else
+            t = "?";
+
+        if (exprop(args[i]) == Ovar)
+            p += snprintf(p, end - p, "%s%s:%s", sep, namestr(args[0]->expr.args[0]), t);
+        else
+            p += snprintf(p, end - p, "%s<e%zd>:%s", sep, i, t);
+        sep = ", ";
+        free(t);
+    }
+    t = tystr(exprtype(args[0])->sub[0]);
+    p += snprintf(p, end - p, "): %s", t);
+    free(t);
+}
+
 /* Tries to give a good string describing the context
  * for the sake of error messages. */
 static char *ctxstr(Inferstate *st, Node *n)
@@ -69,7 +105,7 @@
     idx = NULL;
     switch (n->type) {
         default:
-            s = strdup(nodestr(n->type));
+            s = strdup(nodestr[n->type]);
             break;
         case Ndecl:
             u = declname(n);
@@ -82,21 +118,34 @@
             s = strdup(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
-                u = opstr(exprop(n));
+                u = opstr[exprop(n)];
             if (exprtype(n))
                 t = tystr(tf(st, exprtype(n)));
             else
-                t = strdup("unknown");
-            if (idx)
-                snprintf(buf, sizeof buf, ".%s=%s:%s", idx, u, t);
-            else
-                snprintf(buf, sizeof buf, "%s:%s", u, t);
-            free(idx);
+                t = strdup("unknown type");
+            switch (opclass[exprop(n)]) {
+                case OTbin:
+                    snprintf(buf, sizeof buf, "<e1> %s <e2>", oppretty[exprop(n)]);
+                    break;
+                case OTpre:
+                    snprintf(buf, sizeof buf, "%s<e>", oppretty[exprop(n)]);
+                    break;
+                case OTpost:
+                    snprintf(buf, sizeof buf, "<e>%s", oppretty[exprop(n)]);
+                    break;
+                case OTzarg:
+                    snprintf(buf, sizeof buf, "%s", oppretty[exprop(n)]);
+                case OTmisc:
+                    if (exprop(n) == Ovar)
+                        snprintf(buf, sizeof buf, "%s:%s", namestr(n->expr.args[0]), t);
+                    else if (exprop(n) == Ocall)
+                        ctxstrcall(buf, sizeof buf, st, n);
+                    else
+                        snprintf(buf, sizeof buf, "%s:%s", u, t);
+            }
             free(t);
             s = strdup(buf);
             break;
@@ -368,7 +417,7 @@
         case Nlit:      n->lit.type = t;        break;
         case Nfunc:     n->func.type = t;       break;
         default:
-            die("untypable node %s", nodestr(n->type));
+            die("untypable node %s", nodestr[n->type]);
             break;
     }
 }
@@ -422,7 +471,7 @@
       case Nfunc:       t = n->func.type;       break;
       default:
         t = NULL;
-        die("untypeable node %s", nodestr(n->type));
+        die("untypeable node %s", nodestr[n->type]);
         break;
     };
     return tf(st, t);
@@ -1073,7 +1122,7 @@
     }
     if (exprop(n) == Ovar)
         n->expr.isconst = decls[n->expr.did]->decl.isconst;
-    else if (ispureop[exprop(n)])
+    else if (opispure[exprop(n)])
         n->expr.isconst = isconst;
     *exprconst = n->expr.isconst;
 }
@@ -1288,7 +1337,7 @@
         case Ofeq: case Ofne: case Ofgt: case Ofge: case Oflt: case Ofle:
         case Oueq: case Oune: case Ougt: case Ouge: case Oult: case Oule:
         case Oudata:
-            die("Should not see %s in fe", opstr(exprop(n)));
+            die("Should not see %s in fe", opstr[exprop(n)]);
             break;
     }
 }
--- a/parse/names.c
+++ b/parse/names.c
@@ -11,52 +11,45 @@
 
 #include "parse.h"
 
-static char *optab[] =  {
-#define O(op, pure) #op,
+char *opstr[] =  {
+#define O(op, pure, class, pretty) #op,
 #include "ops.def"
 #undef O
 };
 
-int ispureop[] = {
-#define O(op, pure) pure,
+char * oppretty[] = {
+#define O(op, pure, class, pretty) pretty,
 #include "ops.def"
 #undef O
 };
 
-static char *nodetab[] =  {
+
+int opispure[] = {
+#define O(op, pure, class, pretty) pure,
+#include "ops.def"
+#undef O
+};
+
+int opclass[] = {
+#define O(op, pure, class, pretty) class,
+#include "ops.def"
+#undef O
+};
+
+char *nodestr[] =  {
 #define N(nt) #nt,
 #include "nodes.def"
 #undef N
 };
 
-static char *littab[] =  {
+char *litstr[] =  {
 #define L(lt) #lt,
 #include "lits.def"
 #undef L
 };
 
-static char *tidtab[] =  {
+char *tidstr[] =  {
 #define Ty(t, n) n,
 #include "types.def"
 #undef Ty
 };
-
-char *opstr(Op o)
-{
-    return optab[o];
-}
-
-char *nodestr(Ntype nt)
-{
-    return nodetab[nt];
-}
-
-char *litstr(Littype lt)
-{
-    return littab[lt];
-}
-
-char *tidstr(Ty tid)
-{
-    return tidtab[tid];
-}
--- a/parse/node.c
+++ b/parse/node.c
@@ -374,7 +374,7 @@
         case Ndecl:     return n->decl.type;            break;
         case Nexpr:     return n->expr.type;            break;
         case Nlit:      return n->lit.type;             break;
-        default:        die("Node %s has no type", nodestr(n->type)); break;
+        default:        die("Node %s has no type", nodestr[n->type]); break;
     }
     return NULL;
 }
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -1,99 +1,100 @@
-/* operator name, is it pure */
-O(Obad, 1)
-O(Oadd, 1)
-O(Osub, 1)
-O(Omul, 1)
-O(Odiv, 1)
-O(Omod, 1)
-O(Oneg, 1)
-O(Obor, 1)
-O(Oband, 1)
-O(Obxor, 1)
-O(Obsl, 1)
-O(Obsr, 1)
-O(Obnot, 1)
-O(Opreinc, 1)
-O(Opostinc, 1)
-O(Opredec, 1)
-O(Opostdec, 1)
-O(Oaddr, 1)
-O(Oderef, 1)
-O(Olor, 1)
-O(Oland, 1)
-O(Olnot, 1)
-O(Oeq, 1)
-O(One, 1)
-O(Ogt, 1)
-O(Oge, 1)
-O(Olt, 1)
-O(Ole, 1)
-O(Oasn, 1)
-O(Oaddeq, 1)
-O(Osubeq, 1)
-O(Omuleq, 1)
-O(Odiveq, 1)
-O(Omodeq, 1)
-O(Oboreq, 1)
-O(Obandeq, 1)
-O(Obxoreq, 1)
-O(Obsleq, 1)
-O(Obsreq, 1)
-O(Oidx, 1)
-O(Oslice, 1)
-O(Omemb, 1)
-O(Osize, 1)
-O(Ocall, 0)
-O(Ocast, 1)
-O(Oret, 1)
-O(Ojmp, 0)
-O(Obreak, 0)
-O(Ocontinue, 0)
-O(Ovar, 1)
-O(Olit, 1)
-O(Oucon, 1)
-O(Otup, 1)
-O(Ostruct, 1)
-O(Oarr, 1)
+/* operator name, is it pure, pretty name */
+O(Obad,         1,	OTmisc,	"BAD")
+O(Oadd,	        1,	OTbin,	"+")
+O(Osub,	        1,	OTbin,	"-")
+O(Omul,	        1,	OTbin,	"*")
+O(Odiv,	        1,	OTbin,	"/")
+O(Omod,	        1,	OTbin,	"%")
+O(Oneg,	        1,	OTpre,	"-")
+O(Obor,	        1,	OTbin,	"|")
+O(Oband,	1,	OTbin,  "&")
+O(Obxor,	1,	OTbin,  "^")
+O(Obsl,	        1,	OTbin,  "<<")
+O(Obsr,	        1,	OTbin,  ">>")
+O(Obnot,	1,	OTpre,  "~")
+O(Opreinc,	1,	OTpre,  "++")
+O(Opostinc,	1,	OTpost, "++")
+O(Opredec,	1,	OTpre,  "--")
+O(Opostdec,	1,	OTpost, "--")
+O(Oaddr,	1,	OTpre,  "&")
+O(Oderef,	1,	OTpost, "#")
+O(Olor,	        1,	OTbin,  "||")
+O(Oland,	1,	OTbin,  "&&")
+O(Olnot,	1,	OTpre,  "!")
+O(Oeq,	        1,	OTbin,  "==")
+O(One,	        1,	OTbin,  "!=")
+O(Ogt,	        1,	OTbin,  ">")
+O(Oge,	        1,	OTbin,  ">=")
+O(Olt,	        1,	OTbin,  "<")
+O(Ole,	        1,	OTbin,  "<=")
+O(Oasn,	        1,	OTbin,  "==")
+O(Oaddeq,	1,	OTbin,  "+=")
+O(Osubeq,	1,	OTbin,  "-=")
+O(Omuleq,	1,	OTbin,  "*=")
+O(Odiveq,	1,	OTbin,  "/=")
+O(Omodeq,	1,	OTbin,  "%=")
+O(Oboreq,	1,	OTbin,  "|=")
+O(Obandeq,	1,	OTbin,  "&=")
+O(Obxoreq,	1,	OTbin,  "^=")
+O(Obsleq,	1,	OTbin,  "<<=")
+O(Obsreq,	1,	OTbin,  ">>=")
+O(Oidx,	        1,	OTmisc,  NULL)
+O(Oslice,	1,	OTmisc,  NULL)
+O(Omemb,	1,	OTmisc,  NULL)
+O(Osize,	1,	OTmisc,  NULL)
+O(Ocall,	0,	OTmisc,  NULL)
+O(Ocast,	1,	OTmisc,  NULL)
+O(Oret,	        1,	OTpre,  "->")
+O(Ojmp,	        0,	OTpre,  "goto")
+O(Obreak,	0,	OTzarg, "break")
+O(Ocontinue,	0,	OTzarg, "continue")
+O(Ovar,	        1,	OTmisc, NULL)
+O(Olit,	        1,	OTmisc, NULL)
+O(Oucon,	1,	OTmisc, "`")
+O(Otup,	        1,	OTmisc, NULL)
+O(Ostruct,	1,	OTmisc, NULL)
+O(Oarr,	        1,	OTmisc, NULL)
 
 /* all below this point are backend-only */
-O(Ocjmp, 1)        /* conditional jump */
-O(Ojtab, 1)		   /* jump table */
-O(Oset, 1)         /* store to var */
-O(Osllen, 1)       /* size of slice */
-O(Oslbase, 1)      /* base of sice */
-O(Outag, 1)		   /* tag of union */
-O(Oudata, 1)       /* pointer to contents of union */
-O(Oblit, 1)        /* blit memory */
+O(Ocjmp,	1,	OTmisc, NULL)        /* conditional jump */
+O(Ojtab,	1,	OTmisc, NULL)		   /* jump table */
+O(Oset,	        1,	OTbin,  "=")         /* store to var */
+O(Osllen,	1,	OTpre,  "SLLEN")       /* size of slice */
+O(Oslbase,	1,	OTpre,  "SLBASE")      /* base of sice */
+O(Outag,	1,	OTpre,  "UTAG")		   /* tag of union */
+O(Oudata,	1,	OTpre,  "UDATA")       /* pointer to contents of union */
+O(Oblit,	1,	OTbin,  "BLIT")        /* blit memory */
 
 /* integer conversions */
-O(Otrunc, 1)       /* truncating cast */
-O(Ozwiden, 1)      /* zero-extending widening cast */
-O(Oswiden, 1)      /* sign-extending widening cast */
+O(Otrunc,	1,	OTmisc, NULL)       /* truncating cast */
+O(Ozwiden,	1,	OTmisc, NULL)      /* zero-extending widening cast */
+O(Oswiden,	1,	OTmisc, NULL)      /* sign-extending widening cast */
 
 /* float conversions */
-O(Oflt2int, 1)     /* float to int conversion */
-O(Oint2flt, 1)     /* int to float conversion */
-O(Oflt2flt, 1)     /* flt32<->flt64 conversion */
+O(Oflt2int,	1,	OTmisc, NULL)     /* float to int conversion */
+O(Oint2flt,	1,	OTmisc, NULL)     /* int to float conversion */
+O(Oflt2flt,	1,	OTmisc, NULL)     /* flt32<->flt64 conversion */
 
 /* floating arithmetic */
-O(Ofadd, 1)
-O(Ofsub, 1)
-O(Ofmul, 1)
-O(Ofdiv, 1)
-O(Ofneg, 1)
+O(Ofadd,	1,	OTmisc, NULL)
+O(Ofsub,	1,	OTmisc, NULL)
+O(Ofmul,	1,	OTmisc, NULL)
+O(Ofdiv,	1,	OTmisc, NULL)
+O(Ofneg,	1,	OTmisc, NULL)
 
 /* floating point comparisons */
-O(Ofeq, 1)
-O(Ofne, 1)
-O(Ofgt, 1)
-O(Ofge, 1)
-O(Oflt, 1)
-O(Ofle, 1)
+O(Ofeq,	        1,	OTmisc, NULL)
+O(Ofne,	        1,	OTmisc, NULL)
+O(Ofgt,	        1,	OTmisc, NULL)
+O(Ofge,	        1,	OTmisc, NULL)
+O(Oflt,	        1,	OTmisc, NULL)
+O(Ofle,	        1,	OTmisc, NULL)
 
 /* unsigned comparisons */
-O(Oueq, 1)
-O(Oune, 1)
-O(Ougt, 1)
-O(Ouge, 1)
-O(Oult, 1)
-O(Oule, 1)
+O(Oueq,	        1,	OTmisc, NULL)
+O(Oune,	        1,	OTmisc, NULL)
+O(Ougt,	        1,	OTmisc, NULL)
+O(Ouge,	        1,	OTmisc, NULL)
+O(Oult,	        1,	OTmisc, NULL)
+O(Oule,	        1,	OTmisc, NULL)
+
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -26,7 +26,15 @@
 typedef struct Trait Trait;
 
 typedef enum {
-#define O(op, pure) op,
+    OTmisc,
+    OTpre,
+    OTpost,
+    OTbin,
+    OTzarg,
+} Optype;
+
+typedef enum {
+#define O(op, pure, type, pretty) op,
 #include "ops.def"
     Numops,
 #undef O
@@ -367,7 +375,14 @@
 extern size_t nexportimpls;
 extern size_t maxnid;      /* the maximum node id generated so far */
 
-extern int ispureop[];
+/* property tables */
+extern int opispure[];
+extern char *opstr[];
+extern char *oppretty[];
+extern int opclass[];
+extern char *nodestr[];
+extern char *litstr[];
+extern char *tidstr[];
 
 /* data structures */
 Bitset *mkbs(void);
@@ -563,10 +578,6 @@
 void dump(Node *t, FILE *fd);
 void dumpsym(Node *s, FILE *fd);
 void dumpstab(Stab *st, FILE *fd);
-char *opstr(Op o);
-char *nodestr(Ntype nt);
-char *litstr(Littype lt);
-char *tidstr(Ty tid);
 
 /* option parsing */
 void optinit(Optctx *ctx, char *optstr, char **optargs, size_t noptargs);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -158,7 +158,7 @@
     switch (n->type) {
         case Nfile:
         case Nuse:
-            die("Node %s not allowed here\n", nodestr(n->type));
+            die("Node %s not allowed here\n", nodestr[n->type]);
             break;
         case Nexpr:
             fixup(n->expr.idx);
@@ -253,7 +253,7 @@
     switch (n->type) {
         case Nfile:
         case Nuse:
-            die("Node %s not allowed here\n", nodestr(n->type));
+            die("Node %s not allowed here\n", nodestr[n->type]);
             break;
         case Nexpr:
             r->expr.op = n->expr.op;