> I thought more about this. I don't think you want to put it in
> that section of the code. Instead, I think that much closer to
> the front end, when a function literal is starting, the thing to do
> is declare a fake phi variable and rewrite func(){...} into logically
> phi = func(){...} returning value phi (not possible in Go but
> possible in the internal representation). Then if the ... mentions
> phi it will be grabbed properly. Even inside the closure generation
> code, there is no name for the result of the func(){} expression,
> because the stub code is generated at run time.
I tried an approach similar to what is done to print/panic/etc. (diff
below), but now I see that the function I see during the walk (named
_f%d in walkclosure()) is not the one I want (for the code below the
typechecker and 8g -w say its signature for [func(n int) int] in the
code is [func(uintptr, n int) int]).
The variable approach is more sensible. I'm still somewhat confused as
to what the relations between given Node, its ->nname and ->ntype are
-- they seem to be used interchangeably to some extent. Do I
understand you correctly that what you suggest should be done about
the parsing time before the walk (so probably in closurehdr), or
should still all the rewrite happen in walkclosure? And how do I
implement the proposed code? By wrapping in another closure?
Thanks,
Oleg
In case the diff output comes garbled again:
http://rain.ifmo.ru/~olegfink/go-phi.diff
diff -r cb140bac9ab0 src/cmd/gc/go.h
--- a/src/cmd/gc/go.h Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/go.h Fri Nov 13 02:20:51 2009 +0300
@@ -360,6 +360,7 @@
ONOT, OCOM, OPLUS, OMINUS,
OOROR,
OPANIC, OPANICN, OPRINT, OPRINTN,
+ OPHI,
OSEND, OSENDNB,
OSLICE, OSLICEARR, OSLICESTR,
ORECV,
diff -r cb140bac9ab0 src/cmd/gc/lex.c
--- a/src/cmd/gc/lex.c Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/lex.c Fri Nov 13 02:20:51 2009 +0300
@@ -1252,6 +1252,7 @@
"panicln", LNAME, Txxx, OPANICN,
"print", LNAME, Txxx, OPRINT,
"println", LNAME, Txxx, OPRINTN,
+ "phi", LNAME, Txxx, OPHI,
"notwithstanding", LIGNORE, Txxx, OXXX,
"thetruthofthematter", LIGNORE, Txxx, OXXX,
diff -r cb140bac9ab0 src/cmd/gc/print.c
--- a/src/cmd/gc/print.c Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/print.c Fri Nov 13 02:20:51 2009 +0300
@@ -311,6 +311,7 @@
case OPANICN:
case OPRINT:
case OPRINTN:
+ case OPHI:
fmtprint(f, "%#O(", n->op);
if(n->left)
exprfmt(f, n->left, 0);
diff -r cb140bac9ab0 src/cmd/gc/subr.c
--- a/src/cmd/gc/subr.c Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/subr.c Fri Nov 13 02:20:51 2009 +0300
@@ -774,6 +774,7 @@
[OOR] = "|",
[OPANICN] = "panicln",
[OPANIC] = "panic",
+ [OPHI] = "phi",
[OPLUS] = "+",
[OPRINTN] = "println",
[OPRINT] = "print",
diff -r cb140bac9ab0 src/cmd/gc/typecheck.c
--- a/src/cmd/gc/typecheck.c Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/typecheck.c Fri Nov 13 02:20:51 2009 +0300
@@ -899,6 +899,11 @@
typechecklist(n->list, Erv);
goto ret;
+ case OPHI:
+ ok |= Erv;
+ typechecklist(n->list, Erv);
+ goto ret;
+
case OCLOSURE:
ok |= Erv;
typecheckclosure(n);
diff -r cb140bac9ab0 src/cmd/gc/walk.c
--- a/src/cmd/gc/walk.c Thu Nov 12 14:55:26 2009 -0800
+++ b/src/cmd/gc/walk.c Fri Nov 13 02:20:51 2009 +0300
@@ -5,6 +5,7 @@
#include "go.h"
static Node* walkprint(Node*, NodeList**);
+static Node* walkphi(Node*, NodeList**);
static Node* conv(Node*, Type*);
static Node* mapfn(char*, Type*);
static Node* makenewvar(Type*, NodeList**, Node**);
@@ -536,6 +537,11 @@
n = walkprint(n, init);
goto ret;
+ case OPHI:
+ walkexprlist(n->list, init);
+ n = walkphi(n, init);
+ goto ret;
+
case OLITERAL:
n->addable = 1;
goto ret;
@@ -1558,6 +1564,16 @@
return r;
}
+static Node*
+walkphi(Node *nn, NodeList **init)
+{
+ Node *n;
+ n = nod(OCALL, curfn, N);
+ n->list = nn->list;
+ typecheck(&n, Erv);
+ return n;
+}
+
Node*
callnew(Type *t)
{