summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-01-06 13:29:51 -0800
committerOri Bernstein <ori@eigenstate.org>2015-01-06 13:29:51 -0800
commitc96b770a0aa93c1e7b99e5874808af85ddacc6a7 (patch)
treed60d4652014bc44186663f7afaea3338281124ae
parent468265b7b2719d783afc46ea5aa7c9ffa3142970 (diff)
downloadmc-c96b770a0aa93c1e7b99e5874808af85ddacc6a7.tar.gz
Improve error messages.
This involved lots of table changes.
-rw-r--r--6/gengas.c2
-rw-r--r--6/genp9.c2
-rw-r--r--6/isel.c8
-rw-r--r--6/simp.c4
-rw-r--r--mi/cfg.c2
-rw-r--r--mi/match.c6
-rw-r--r--parse/dump.c4
-rw-r--r--parse/infer.c77
-rw-r--r--parse/names.c47
-rw-r--r--parse/node.c2
-rw-r--r--parse/ops.def175
-rw-r--r--parse/parse.h23
-rw-r--r--parse/specialize.c4
13 files changed, 205 insertions, 151 deletions
diff --git a/6/gengas.c b/6/gengas.c
index 7b40856..9095314 100644
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -514,7 +514,7 @@ void gengas(Node *file, char *out)
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;
}
}
diff --git a/6/genp9.c b/6/genp9.c
index 7a591b9..3c21cfb 100644
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -533,7 +533,7 @@ void genp9(Node *file, char *out)
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;
}
}
diff --git a/6/isel.c b/6/isel.c
index 01bc81d..f2da224 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -102,11 +102,11 @@ static Loc *loc(Isel *s, Node *n)
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 @@ Loc *selexpr(Isel *s, Node *n)
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 @@ Loc *selexpr(Isel *s, Node *n)
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;
diff --git a/6/simp.c b/6/simp.c
index 7e62fec..b25f45b 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -277,7 +277,7 @@ static void append(Simp *s, Node *n)
static int ispure(Node *n)
{
- return ispureop[exprop(n)];
+ return opispure[exprop(n)];
}
static int isconstfn(Node *s)
@@ -822,7 +822,7 @@ static Node *lval(Simp *s, Node *n)
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;
diff --git a/mi/cfg.c b/mi/cfg.c
index 2a24dda..fc1cacf 100644
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -211,7 +211,7 @@ Cfg *mkcfg(Node *fn, Node **nl, size_t nn)
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);
diff --git a/mi/match.c b/mi/match.c
index be0e033..f80e40e 100644
--- a/mi/match.c
+++ b/mi/match.c
@@ -224,7 +224,7 @@ static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
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 @@ char *dtnodestr(Node *n)
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 @@ void dtdumpnode(Dtree *dt, FILE *f, int depth, int iswild)
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++)
diff --git a/parse/dump.c b/parse/dump.c
index 6303cd7..97299f5 100644
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -113,7 +113,7 @@ static void outnode(Node *n, FILE *fd, int depth)
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 @@ static void outnode(Node *n, FILE *fd, int depth)
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++)
diff --git a/parse/infer.c b/parse/infer.c
index bf20bc5..6fb5442 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -56,6 +56,42 @@ static void unbind(Inferstate *st, Node *n);
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 @@ static char *ctxstr(Inferstate *st, Node *n)
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 @@ static char *ctxstr(Inferstate *st, Node *n)
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 @@ static void settype(Inferstate *st, Node *n, Type *t)
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 @@ static Type *type(Inferstate *st, Node *n)
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 @@ static void infersub(Inferstate *st, Node *n, Type *ret, int *sawret, int *exprc
}
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 @@ static void inferexpr(Inferstate *st, Node *n, Type *ret, int *sawret)
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;
}
}
diff --git a/parse/names.c b/parse/names.c
index dddd649..3a0009d 100644
--- 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];
-}
diff --git a/parse/node.c b/parse/node.c
index 3a598ce..4bca3a6 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -374,7 +374,7 @@ Type *nodetype(Node *n)
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;
}
diff --git a/parse/ops.def b/parse/ops.def
index be7f8d7..fed7bd4 100644
--- 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)
+
diff --git a/parse/parse.h b/parse/parse.h
index cded5f1..7f9c98c 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -26,7 +26,15 @@ typedef struct Type Type;
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 Node **exportimpls;
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 @@ Type *tysearch(Type *t);
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);
diff --git a/parse/specialize.c b/parse/specialize.c
index eb736c5..5b1c340 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -158,7 +158,7 @@ static void fixup(Node *n)
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 @@ static Node *specializenode(Node *n, Htab *tsmap)
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;