From: Russ Cox Date: Wed, 29 Jul 2009 18:51:34 +0000 (-0700) Subject: expression printer; %#N X-Git-Tag: weekly.2009-11-06~1033 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4152b925f97de964af1553784f3886d93da22aff;p=gostls13.git expression printer; %#N R=ken OCL=32419 CL=32419 --- diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile index 516542dbb0..697cca9409 100644 --- a/src/cmd/gc/Makefile +++ b/src/cmd/gc/Makefile @@ -34,6 +34,7 @@ OFILES=\ align.$O\ gen.$O\ obj.$O\ + print.$O\ $(LIB): $(OFILES) ar rsc $(LIB) $(OFILES) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index e7bac2da95..5190591dc3 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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 index 0000000000..fc96b3a2bf --- /dev/null +++ b/src/cmd/gc/print.c @@ -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, ""); + 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, ""); + break; + + case OTINTER: + fmtprint(f, ""); + break; + + case OTFUNC: + fmtprint(f, ""); + 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, ""); + break; + + case ODOT: + case ODOTINTER: + case ODOTMETH: + exprfmt(f, n->left, 7); + if(n->sym == S) + fmtprint(f, "."); + 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, ")"); +} diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 14a5fa7b5c..264cf8a836 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -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, ""); goto out; } + + if(fp->flags & FmtSharp) { + exprfmt(fp, n, 0); + goto out; + } switch(n->op) { default: