Commit 4152b925 authored by Russ Cox's avatar Russ Cox

expression printer; %#N

R=ken
OCL=32419
CL=32419
parent 6b8ba5d8
......@@ -34,6 +34,7 @@ OFILES=\
align.$O\
gen.$O\
obj.$O\
print.$O\
$(LIB): $(OFILES)
ar rsc $(LIB) $(OFILES)
......
......@@ -816,6 +816,7 @@ int Oconv(Fmt*);
int Sconv(Fmt*);
int Tconv(Fmt*);
int Nconv(Fmt*);
void exprfmt(Fmt*, Node*, int);
int Wconv(Fmt*);
int Zconv(Fmt*);
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go.h"
enum
{
PFIXME = 0,
PCHAN = 0,
};
void
exprlistfmt(Fmt *f, NodeList *l)
{
for(; l; l=l->next) {
exprfmt(f, l->n, 0);
if(l->next)
fmtprint(f, ", ");
}
}
void
exprfmt(Fmt *f, Node *n, int prec)
{
int nprec;
nprec = 0;
if(n == nil) {
fmtprint(f, "<nil>");
return;
}
switch(n->op) {
case ONAME:
case ONONAME:
case OPACK:
case OLITERAL:
nprec = 7;
break;
case OMUL:
case ODIV:
case OMOD:
case OLSH:
case ORSH:
case OAND:
case OANDNOT:
nprec = 6;
break;
case OADD:
case OSUB:
case OOR:
case OXOR:
nprec = 5;
break;
case OEQ:
case OLT:
case OLE:
case OGE:
case OGT:
case ONE:
nprec = 4;
break;
case OSEND:
nprec = 3;
break;
case OANDAND:
nprec = 2;
break;
case OOROR:
nprec = 1;
break;
}
if(prec > nprec)
fmtprint(f, "(");
switch(n->op) {
default:
bad:
fmtprint(f, "(node %O)", n->op);
break;
case OLITERAL:
switch(n->val.ctype) {
default:
goto bad;
case CTINT:
fmtprint(f, "%B", n->val.u.xval);
break;
case CTBOOL:
if(n->val.u.bval)
fmtprint(f, "true");
else
fmtprint(f, "false");
break;
case CTFLT:
fmtprint(f, "%.17g", mpgetflt(n->val.u.fval));
break;
case CTSTR:
fmtprint(f, "\"%Z\"", n->val.u.sval);
break;
case CTNIL:
fmtprint(f, "nil");
break;
}
break;
case ONAME:
case OPACK:
case ONONAME:
fmtprint(f, "%S", n->sym);
break;
case OTYPE:
fmtprint(f, "%T", n->type);
break;
case OTARRAY:
fmtprint(f, "[]");
exprfmt(f, n->left, PFIXME);
break;
case OTMAP:
fmtprint(f, "map[");
exprfmt(f, n->left, 0);
fmtprint(f, "] ");
exprfmt(f, n->right, 0);
break;
case OTCHAN:
if(n->etype == Crecv)
fmtprint(f, "<-");
fmtprint(f, "chan");
if(n->etype == Csend) {
fmtprint(f, "<- ");
exprfmt(f, n->left, 0);
} else {
fmtprint(f, " ");
exprfmt(f, n->left, PCHAN);
}
break;
case OTSTRUCT:
fmtprint(f, "<struct>");
break;
case OTINTER:
fmtprint(f, "<inter>");
break;
case OTFUNC:
fmtprint(f, "<func>");
break;
case OADD:
case OANDAND:
case OANDNOT:
case ODIV:
case OEQ:
case OGE:
case OGT:
case OLE:
case OLT:
case OLSH:
case OMOD:
case OMUL:
case ONE:
case OOR:
case OOROR:
case ORSH:
case OSEND:
case OSUB:
case OXOR:
exprfmt(f, n->left, nprec);
fmtprint(f, " %#O ", n->op);
exprfmt(f, n->right, nprec+1);
break;
case OADDR:
case OCOM:
case OIND:
case OMINUS:
case ONOT:
case OPLUS:
case ORECV:
fmtprint(f, "%#O", n->op);
if((n->op == OMINUS || n->op == OPLUS) && n->left->op == n->op)
fmtprint(f, " ");
exprfmt(f, n->left, 0);
break;
case OCOMPOS:
fmtprint(f, "<compos>");
break;
case ODOT:
case ODOTINTER:
case ODOTMETH:
exprfmt(f, n->left, 7);
if(n->sym == S)
fmtprint(f, ".<nil>");
else
fmtprint(f, ".%s", n->sym->name);
break;
case ODOTTYPE:
exprfmt(f, n->left, 7);
fmtprint(f, ".(");
exprfmt(f, n->right, 0);
fmtprint(f, ")");
break;
case OINDEX:
exprfmt(f, n->left, 7);
fmtprint(f, "[");
exprfmt(f, n->right, 0);
fmtprint(f, "]");
break;
case OSLICE:
exprfmt(f, n->left, 7);
fmtprint(f, "[");
exprfmt(f, n->right->left, 0);
fmtprint(f, ":");
exprfmt(f, n->right->right, 0);
fmtprint(f, "]");
break;
case OCALL:
case OCALLINTER:
case OCALLMETH:
exprfmt(f, n->left, 7);
fmtprint(f, "(");
exprlistfmt(f, n->list);
fmtprint(f, ")");
break;
case OCONV:
fmtprint(f, "%T(", n->type);
exprfmt(f, n->left, 0);
fmtprint(f, ")");
break;
case OCAP:
case OCLOSE:
case OCLOSED:
case OLEN:
case OMAKE:
case ONEW:
case OPANIC:
case OPANICN:
case OPRINT:
case OPRINTN:
fmtprint(f, "%#O(", n->op);
if(n->left)
exprfmt(f, n->left, 0);
else
exprlistfmt(f, n->list);
fmtprint(f, ")");
break;
}
if(prec > nprec)
fmtprint(f, ")");
}
......@@ -732,6 +732,65 @@ opnames[] =
[OXXX] = "XXX",
};
static char*
goopnames[] =
{
[OADDR] = "&",
[OADD] = "+",
[OANDAND] = "&&",
[OANDNOT] = "&^",
[OAND] = "&",
[OAS] = "=",
[OAS2] = "=",
[OBREAK] = "break",
[OCAP] = "cap",
[OCASE] = "case",
[OCLOSED] = "closed",
[OCLOSE] = "close",
[OCOM] = "^",
[OCONTINUE] = "continue",
[ODEC] = "--",
[ODEFER] = "defer",
[ODIV] = "/",
[OEQ] = "==",
[OFALL] = "fallthrough",
[OFOR] = "for",
[OFUNC] = "func",
[OGE] = ">=",
[OGOTO] = "goto",
[OGT] = ">",
[OIF] = "if",
[OINC] = "++",
[OIND] = "*",
[OLEN] = "len",
[OLE] = "<=",
[OLSH] = "<<",
[OLT] = "<",
[OMAKE] = "make",
[OMINUS] = "-",
[OMOD] = "%",
[OMUL] = "*",
[ONEW] = "new",
[ONE] = "!=",
[ONOT] = "!",
[OOROR] = "||",
[OOR] = "|",
[OPANICN] = "panicln",
[OPANIC] = "panic",
[OPLUS] = "+",
[OPRINTN] = "println",
[OPRINT] = "print",
[ORANGE] = "range",
[ORECV] = "<-",
[ORETURN] = "return",
[ORSH] = ">>",
[OSELECT] = "select",
[OSEND] = "<-",
[OSUB] = "-",
[OSWITCH] = "switch",
[OXOR] = "^",
};
int
Oconv(Fmt *fp)
{
......@@ -739,6 +798,8 @@ Oconv(Fmt *fp)
int o;
o = va_arg(fp->args, int);
if((fp->flags & FmtSharp) && o >= 0 && o < nelem(goopnames) && goopnames[o] != nil)
return fmtstrcpy(fp, goopnames[o]);
if(o < 0 || o >= nelem(opnames) || opnames[o] == nil) {
snprint(buf, sizeof(buf), "O-%d", o);
return fmtstrcpy(fp, buf);
......@@ -1263,6 +1324,11 @@ Nconv(Fmt *fp)
fmtprint(fp, "<N>");
goto out;
}
if(fp->flags & FmtSharp) {
exprfmt(fp, n, 0);
goto out;
}
switch(n->op) {
default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment