]> Cypherpunks repositories - gostls13.git/commitdiff
expression printer; %#N
authorRuss Cox <rsc@golang.org>
Wed, 29 Jul 2009 18:51:34 +0000 (11:51 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 29 Jul 2009 18:51:34 +0000 (11:51 -0700)
R=ken
OCL=32419
CL=32419

src/cmd/gc/Makefile
src/cmd/gc/go.h
src/cmd/gc/print.c [new file with mode: 0644]
src/cmd/gc/subr.c

index 516542dbb008bec6ed6a1ec4ac6252f11a36480b..697cca9409f00dfbd272baedc00ca1523f26435a 100644 (file)
@@ -34,6 +34,7 @@ OFILES=\
        align.$O\
        gen.$O\
        obj.$O\
+       print.$O\
 
 $(LIB): $(OFILES)
        ar rsc $(LIB) $(OFILES)
index e7bac2da95109c283acee9cb5a39ed8f4382583a..5190591dc368b221ebe358f79a5a7b9b42906295 100644 (file)
@@ -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*);
 
diff --git a/src/cmd/gc/print.c b/src/cmd/gc/print.c
new file mode 100644 (file)
index 0000000..fc96b3a
--- /dev/null
@@ -0,0 +1,272 @@
+// 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, ")");
+}
index 14a5fa7b5c9f8fd0031a63719af42a6a97383b5e..264cf8a836bae677192637d269284b4a0034486d 100644 (file)
@@ -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: