The Go Programming Language

Text file src/cmd/gc/print.c

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	#include "go.h"
     6	
     7	enum
     8	{
     9		PFIXME = 0,
    10	};
    11	
    12	void
    13	exprlistfmt(Fmt *f, NodeList *l)
    14	{
    15		for(; l; l=l->next) {
    16			exprfmt(f, l->n, 0);
    17			if(l->next)
    18				fmtprint(f, ", ");
    19		}
    20	}
    21	
    22	void
    23	exprfmt(Fmt *f, Node *n, int prec)
    24	{
    25		int nprec;
    26		char *p;
    27	
    28		nprec = 0;
    29		if(n == nil) {
    30			fmtprint(f, "<nil>");
    31			return;
    32		}
    33		
    34		if(n->implicit) {
    35			exprfmt(f, n->left, prec);
    36			return;
    37		}
    38	
    39		switch(n->op) {
    40		case OAPPEND:
    41		case ONAME:
    42		case ONONAME:
    43		case OPACK:
    44		case OLITERAL:
    45		case ODOT:
    46		case ODOTPTR:
    47		case ODOTINTER:
    48		case ODOTMETH:
    49		case ODOTTYPE:
    50		case ODOTTYPE2:
    51		case OXDOT:
    52		case OARRAYBYTESTR:
    53		case OCAP:
    54		case OCLOSE:
    55		case OCOPY:
    56		case OLEN:
    57		case OMAKE:
    58		case ONEW:
    59		case OPANIC:
    60		case OPRINT:
    61		case OPRINTN:
    62		case OCALL:
    63		case OCALLMETH:
    64		case OCALLINTER:
    65		case OCALLFUNC:
    66		case OCONV:
    67		case OCONVNOP:
    68		case OMAKESLICE:
    69		case ORUNESTR:
    70		case OADDR:
    71		case OCOM:
    72		case OIND:
    73		case OMINUS:
    74		case ONOT:
    75		case OPLUS:
    76		case ORECV:
    77		case OCONVIFACE:
    78		case OTPAREN:
    79		case OINDEX:
    80		case OINDEXMAP:
    81		case OPAREN:
    82			nprec = 7;
    83			break;
    84	
    85		case OMUL:
    86		case ODIV:
    87		case OMOD:
    88		case OLSH:
    89		case ORSH:
    90		case OAND:
    91		case OANDNOT:
    92			nprec = 6;
    93			break;
    94	
    95		case OADD:
    96		case OSUB:
    97		case OOR:
    98		case OXOR:
    99			nprec = 5;
   100			break;
   101	
   102		case OEQ:
   103		case OLT:
   104		case OLE:
   105		case OGE:
   106		case OGT:
   107		case ONE:
   108			nprec = 4;
   109			break;
   110	
   111		case OSEND:
   112			nprec = 3;
   113			break;
   114	
   115		case OANDAND:
   116			nprec = 2;
   117			break;
   118	
   119		case OOROR:
   120			nprec = 1;
   121			break;
   122		
   123		case OTYPE:
   124			if(n->sym != S)
   125				nprec = 7;
   126			break;
   127		}
   128	
   129		if(prec > nprec)
   130			fmtprint(f, "(");
   131	
   132		switch(n->op) {
   133		default:
   134		bad:
   135			fmtprint(f, "(node %O)", n->op);
   136			break;
   137	
   138		case OPAREN:
   139			fmtprint(f, "(%#N)", n->left);
   140			break;
   141	
   142		case OREGISTER:
   143			fmtprint(f, "%R", n->val.u.reg);
   144			break;
   145	
   146		case OLITERAL:
   147			if(n->sym != S) {
   148				fmtprint(f, "%S", n->sym);
   149				break;
   150			}
   151			switch(n->val.ctype) {
   152			default:
   153				goto bad;
   154			case CTINT:
   155				fmtprint(f, "%B", n->val.u.xval);
   156				break;
   157			case CTBOOL:
   158				if(n->val.u.bval)
   159					fmtprint(f, "true");
   160				else
   161					fmtprint(f, "false");
   162				break;
   163			case CTCPLX:
   164				fmtprint(f, "%.17g+%.17gi",
   165					mpgetflt(&n->val.u.cval->real),
   166					mpgetflt(&n->val.u.cval->imag));
   167				break;
   168			case CTFLT:
   169				fmtprint(f, "%.17g", mpgetflt(n->val.u.fval));
   170				break;
   171			case CTSTR:
   172				fmtprint(f, "\"%Z\"", n->val.u.sval);
   173				break;
   174			case CTNIL:
   175				fmtprint(f, "nil");
   176				break;
   177			}
   178			break;
   179	
   180		case ONAME:
   181		case OPACK:
   182		case ONONAME:
   183			fmtprint(f, "%S", n->sym);
   184			break;
   185	
   186		case OTYPE:
   187			if(n->type == T && n->sym != S) {
   188				fmtprint(f, "%S", n->sym);
   189				break;
   190			}
   191			fmtprint(f, "%T", n->type);
   192			break;
   193	
   194		case OTARRAY:
   195			fmtprint(f, "[]");
   196			exprfmt(f, n->left, PFIXME);
   197			break;
   198		
   199		case OTPAREN:
   200			fmtprint(f, "(");
   201			exprfmt(f, n->left, 0);
   202			fmtprint(f, ")");
   203			break;
   204	
   205		case OTMAP:
   206			fmtprint(f, "map[");
   207			exprfmt(f, n->left, 0);
   208			fmtprint(f, "] ");
   209			exprfmt(f, n->right, 0);
   210			break;
   211	
   212		case OTCHAN:
   213			if(n->etype == Crecv)
   214				fmtprint(f, "<-");
   215			fmtprint(f, "chan");
   216			if(n->etype == Csend) {
   217				fmtprint(f, "<- ");
   218				exprfmt(f, n->left, 0);
   219			} else {
   220				fmtprint(f, " ");
   221				if(n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv) {
   222					fmtprint(f, "(");
   223					exprfmt(f, n->left, 0);
   224					fmtprint(f, ")");
   225				} else
   226					exprfmt(f, n->left, 0);
   227			}
   228			break;
   229	
   230		case OTSTRUCT:
   231			fmtprint(f, "<struct>");
   232			break;
   233	
   234		case OTINTER:
   235			fmtprint(f, "<inter>");
   236			break;
   237	
   238		case OTFUNC:
   239			fmtprint(f, "<func>");
   240			break;
   241	
   242		case OAS:
   243			exprfmt(f, n->left, 0);
   244			fmtprint(f, " = ");
   245			exprfmt(f, n->right, 0);
   246			break;
   247	
   248		case OASOP:
   249			exprfmt(f, n->left, 0);
   250			fmtprint(f, " %#O= ", n->etype);
   251			exprfmt(f, n->right, 0);
   252			break;
   253	
   254		case OAS2:
   255		case OAS2DOTTYPE:
   256		case OAS2FUNC:
   257		case OAS2MAPR:
   258		case OAS2MAPW:
   259		case OAS2RECV:
   260			exprlistfmt(f, n->list);
   261			fmtprint(f, " = ");
   262			exprlistfmt(f, n->rlist);
   263			break;
   264	
   265		case OADD:
   266		case OANDAND:
   267		case OANDNOT:
   268		case ODIV:
   269		case OEQ:
   270		case OGE:
   271		case OGT:
   272		case OLE:
   273		case OLT:
   274		case OLSH:
   275		case OMOD:
   276		case OMUL:
   277		case ONE:
   278		case OOR:
   279		case OOROR:
   280		case ORSH:
   281		case OSEND:
   282		case OSUB:
   283		case OXOR:
   284			exprfmt(f, n->left, nprec);
   285			fmtprint(f, " %#O ", n->op);
   286			exprfmt(f, n->right, nprec+1);
   287			break;
   288	
   289		case OADDR:
   290		case OCOM:
   291		case OIND:
   292		case OMINUS:
   293		case ONOT:
   294		case OPLUS:
   295		case ORECV:
   296			fmtprint(f, "%#O", n->op);
   297			if((n->op == OMINUS || n->op == OPLUS) && n->left->op == n->op)
   298				fmtprint(f, " ");
   299			exprfmt(f, n->left, 0);
   300			break;
   301	
   302		case OCLOSURE:
   303			fmtprint(f, "func literal");
   304			break;
   305	
   306		case OCOMPLIT:
   307			fmtprint(f, "composite literal");
   308			break;
   309		
   310		case OARRAYLIT:
   311			if(isslice(n->type))
   312				fmtprint(f, "slice literal");
   313			else
   314				fmtprint(f, "array literal");
   315			break;
   316		
   317		case OMAPLIT:
   318			fmtprint(f, "map literal");
   319			break;
   320		
   321		case OSTRUCTLIT:
   322			fmtprint(f, "struct literal");
   323			break;
   324	
   325		case OXDOT:
   326		case ODOT:
   327		case ODOTPTR:
   328		case ODOTINTER:
   329		case ODOTMETH:
   330			exprfmt(f, n->left, 7);
   331			if(n->right == N || n->right->sym == S)
   332				fmtprint(f, ".<nil>");
   333			else {
   334				// skip leading type· in method name
   335				p = utfrrune(n->right->sym->name, 0xb7);
   336				if(p)
   337					p+=2;
   338				else
   339					p = n->right->sym->name;
   340				fmtprint(f, ".%s", p);
   341			}
   342			break;
   343	
   344		case ODOTTYPE:
   345		case ODOTTYPE2:
   346			exprfmt(f, n->left, 7);
   347			fmtprint(f, ".(");
   348			if(n->right != N)
   349				exprfmt(f, n->right, 0);
   350			else
   351				fmtprint(f, "%T", n->type);
   352			fmtprint(f, ")");
   353			break;
   354	
   355		case OINDEX:
   356		case OINDEXMAP:
   357			exprfmt(f, n->left, 7);
   358			fmtprint(f, "[");
   359			exprfmt(f, n->right, 0);
   360			fmtprint(f, "]");
   361			break;
   362	
   363		case OSLICE:
   364		case OSLICESTR:
   365		case OSLICEARR:
   366			exprfmt(f, n->left, 7);
   367			fmtprint(f, "[");
   368			if(n->right->left != N)
   369				exprfmt(f, n->right->left, 0);
   370			fmtprint(f, ":");
   371			if(n->right->right != N)
   372				exprfmt(f, n->right->right, 0);
   373			fmtprint(f, "]");
   374			break;
   375	
   376		case OCALL:
   377		case OCALLFUNC:
   378		case OCALLINTER:
   379		case OCALLMETH:
   380			exprfmt(f, n->left, 7);
   381			fmtprint(f, "(");
   382			exprlistfmt(f, n->list);
   383			if(n->isddd)
   384				fmtprint(f, "...");
   385			fmtprint(f, ")");
   386			break;
   387	
   388		case OCOMPLEX:
   389			fmtprint(f, "complex(");
   390			exprfmt(f, n->left, 0);
   391			fmtprint(f, ", ");
   392			exprfmt(f, n->right, 0);
   393			fmtprint(f, ")");
   394			break;
   395	
   396		case OREAL:
   397			fmtprint(f, "real(");
   398			exprfmt(f, n->left, 0);
   399			fmtprint(f, ")");
   400			break;
   401	
   402		case OIMAG:
   403			fmtprint(f, "imag(");
   404			exprfmt(f, n->left, 0);
   405			fmtprint(f, ")");
   406			break;
   407	
   408		case OCONV:
   409		case OCONVIFACE:
   410		case OCONVNOP:
   411		case OARRAYBYTESTR:
   412		case OSTRARRAYBYTE:
   413		case ORUNESTR:
   414			if(n->type == T || n->type->sym == S)
   415				fmtprint(f, "(%T)(", n->type);
   416			else
   417				fmtprint(f, "%T(", n->type);
   418			if(n->left == N)
   419				exprlistfmt(f, n->list);
   420			else
   421				exprfmt(f, n->left, 0);
   422			fmtprint(f, ")");
   423			break;
   424	
   425		case OAPPEND:
   426		case OCAP:
   427		case OCLOSE:
   428		case OLEN:
   429		case OCOPY:
   430		case OMAKE:
   431		case ONEW:
   432		case OPANIC:
   433		case OPRINT:
   434		case OPRINTN:
   435			fmtprint(f, "%#O(", n->op);
   436			if(n->left)
   437				exprfmt(f, n->left, 0);
   438			else
   439				exprlistfmt(f, n->list);
   440			fmtprint(f, ")");
   441			break;
   442	
   443		case OMAKESLICE:
   444			fmtprint(f, "make(%#T, ", n->type);
   445			exprfmt(f, n->left, 0);
   446			if(count(n->list) > 2) {
   447				fmtprint(f, ", ");
   448				exprfmt(f, n->right, 0);
   449			}
   450			fmtprint(f, ")");
   451			break;
   452	
   453		case OMAKEMAP:
   454		case OMAKECHAN:
   455			fmtprint(f, "make(%#T)", n->type);
   456			break;
   457	
   458		// Some statements
   459	
   460		case ODCL:
   461			fmtprint(f, "var %S %#T", n->left->sym, n->left->type);
   462			break;
   463	
   464		case ORETURN:
   465			fmtprint(f, "return ");
   466			exprlistfmt(f, n->list);
   467			break;
   468	
   469		case OPROC:
   470			fmtprint(f, "go %#N", n->left);
   471			break;
   472	
   473		case ODEFER:
   474			fmtprint(f, "defer %#N", n->left);
   475			break;
   476		}
   477	
   478		if(prec > nprec)
   479			fmtprint(f, ")");
   480	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.