mirror of
https://github.com/golang/go
synced 2024-10-14 11:53:56 +00:00
new chan syntax
SVN=127437
This commit is contained in:
parent
33101926f9
commit
ac048ce7f4
|
@ -22,7 +22,7 @@
|
|||
%token LFOR LIF LELSE LSWITCH LCASE LDEFAULT
|
||||
%token LBREAK LCONTINUE LGO LGOTO LRANGE
|
||||
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
|
||||
%token LLSH LRSH LINC LDEC
|
||||
%token LLSH LRSH LINC LDEC LSEND LRECV
|
||||
%token LNIL LTRUE LFALSE LIOTA
|
||||
%token LPANIC LPRINT LIGNORE
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
|||
|
||||
%left LOROR
|
||||
%left LANDAND
|
||||
%left LSEND LRECV
|
||||
%left LEQ LNE LLE LGE LLT LGT
|
||||
%left '+' '-' '|' '^'
|
||||
%left '*' '/' '%' '&' LLSH LRSH
|
||||
|
@ -599,6 +600,14 @@ expr:
|
|||
{
|
||||
$$ = nod(ORSH, $1, $3);
|
||||
}
|
||||
| expr LSEND expr
|
||||
{
|
||||
$$ = nod(OSEND, $1, $3);
|
||||
}
|
||||
| expr LRECV expr
|
||||
{
|
||||
$$ = nod(ORECV, $1, $3);
|
||||
}
|
||||
|
||||
uexpr:
|
||||
pexpr
|
||||
|
@ -631,14 +640,10 @@ uexpr:
|
|||
{
|
||||
$$ = nod(OCOM, $2, N);
|
||||
}
|
||||
| LLT uexpr
|
||||
| LRECV uexpr
|
||||
{
|
||||
$$ = nod(ORECV, $2, N);
|
||||
}
|
||||
| LGT uexpr
|
||||
{
|
||||
$$ = nod(OSEND, $2, N);
|
||||
}
|
||||
|
||||
pexpr:
|
||||
LLITERAL
|
||||
|
@ -907,22 +912,14 @@ chandir:
|
|||
{
|
||||
$$ = Cboth;
|
||||
}
|
||||
| LLT
|
||||
| LRECV
|
||||
{
|
||||
$$ = Crecv;
|
||||
}
|
||||
| LGT
|
||||
| LSEND
|
||||
{
|
||||
$$ = Csend;
|
||||
}
|
||||
| LLT LGT
|
||||
{
|
||||
$$ = Cboth;
|
||||
}
|
||||
| LGT LLT
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
|
||||
keyval:
|
||||
expr ':' expr
|
||||
|
@ -1027,6 +1024,7 @@ fnliteral:
|
|||
|
||||
$$ = newname(lookup(namebuf));
|
||||
addvar($$, $1, PEXTERN);
|
||||
dump("lit1", $$);
|
||||
|
||||
{
|
||||
Node *n;
|
||||
|
@ -1037,10 +1035,13 @@ fnliteral:
|
|||
n->nbody = $3;
|
||||
if(n->nbody == N)
|
||||
n->nbody = nod(ORETURN, N, N);
|
||||
dump("comp1", n);
|
||||
compile(n);
|
||||
dump("comp2", n);
|
||||
}
|
||||
|
||||
$$ = nod(OADDR, $$, N);
|
||||
dump("lit2", $$);
|
||||
}
|
||||
|
||||
fnbody:
|
||||
|
|
|
@ -480,6 +480,10 @@ l0:
|
|||
c = LDEC;
|
||||
goto lx;
|
||||
}
|
||||
if(c1 == '<') {
|
||||
c = LSEND;
|
||||
goto lx;
|
||||
}
|
||||
if(c1 == '=') {
|
||||
c = OSUB;
|
||||
goto asop;
|
||||
|
@ -519,6 +523,10 @@ l0:
|
|||
c = LLE;
|
||||
goto lx;
|
||||
}
|
||||
if(c1 == '-') {
|
||||
c = LRECV;
|
||||
goto lx;
|
||||
}
|
||||
c = LLT;
|
||||
break;
|
||||
|
||||
|
|
|
@ -45,9 +45,11 @@ func mapassign1(hmap *map[any]any, key any, val any);
|
|||
func mapassign2(hmap *map[any]any, key any, val any, pres bool);
|
||||
|
||||
func newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
|
||||
func chansend(hchan *chan any, elem any);
|
||||
func chanrecv1(hchan *chan any) (elem any);
|
||||
func chanrecv2(hchan *chan any) (elem any, pres bool);
|
||||
func chanrecv3(hchan *chan any) (elem any, pres bool);
|
||||
func chansend1(hchan *chan any, elem any);
|
||||
func chansend2(hchan *chan any, elem any) (pres bool);
|
||||
|
||||
func gosched();
|
||||
func goexit();
|
||||
|
@ -104,9 +106,11 @@ export
|
|||
|
||||
// chan
|
||||
newchan
|
||||
chansend
|
||||
chanrecv1
|
||||
chanrecv2
|
||||
chanrecv3
|
||||
chansend1
|
||||
chansend2
|
||||
|
||||
// go routines
|
||||
gosched
|
||||
|
|
|
@ -190,61 +190,75 @@ char* sysimport =
|
|||
"type sys._esys_094 (sys._esys_095 sys._osys_548 sys._isys_550)\n"
|
||||
"var !sys.newchan sys._esys_094\n"
|
||||
"type sys._esys_099 {}\n"
|
||||
"type sys._esys_100 {}\n"
|
||||
"type sys._esys_102 1 sys.any\n"
|
||||
"type sys._esys_101 *sys._esys_102\n"
|
||||
"type sys._isys_557 {hchan sys._esys_101 elem sys.any}\n"
|
||||
"type sys._esys_098 (sys._esys_099 sys._esys_100 sys._isys_557)\n"
|
||||
"var !sys.chansend sys._esys_098\n"
|
||||
"type sys._esys_104 {}\n"
|
||||
"type sys._osys_562 {elem sys.any}\n"
|
||||
"type sys._esys_106 1 sys.any\n"
|
||||
"type sys._esys_105 *sys._esys_106\n"
|
||||
"type sys._isys_564 {hchan sys._esys_105}\n"
|
||||
"type sys._esys_103 (sys._esys_104 sys._osys_562 sys._isys_564)\n"
|
||||
"var !sys.chanrecv1 sys._esys_103\n"
|
||||
"type sys._esys_108 {}\n"
|
||||
"type sys._osys_569 {elem sys.any pres sys.bool}\n"
|
||||
"type sys._esys_110 1 sys.any\n"
|
||||
"type sys._esys_109 *sys._esys_110\n"
|
||||
"type sys._isys_571 {hchan sys._esys_109}\n"
|
||||
"type sys._esys_107 (sys._esys_108 sys._osys_569 sys._isys_571)\n"
|
||||
"var !sys.chanrecv2 sys._esys_107\n"
|
||||
"type sys._osys_557 {elem sys.any}\n"
|
||||
"type sys._esys_101 1 sys.any\n"
|
||||
"type sys._esys_100 *sys._esys_101\n"
|
||||
"type sys._isys_559 {hchan sys._esys_100}\n"
|
||||
"type sys._esys_098 (sys._esys_099 sys._osys_557 sys._isys_559)\n"
|
||||
"var !sys.chanrecv1 sys._esys_098\n"
|
||||
"type sys._esys_103 {}\n"
|
||||
"type sys._osys_564 {elem sys.any pres sys.bool}\n"
|
||||
"type sys._esys_105 1 sys.any\n"
|
||||
"type sys._esys_104 *sys._esys_105\n"
|
||||
"type sys._isys_566 {hchan sys._esys_104}\n"
|
||||
"type sys._esys_102 (sys._esys_103 sys._osys_564 sys._isys_566)\n"
|
||||
"var !sys.chanrecv2 sys._esys_102\n"
|
||||
"type sys._esys_107 {}\n"
|
||||
"type sys._osys_572 {elem sys.any pres sys.bool}\n"
|
||||
"type sys._esys_109 1 sys.any\n"
|
||||
"type sys._esys_108 *sys._esys_109\n"
|
||||
"type sys._isys_574 {hchan sys._esys_108}\n"
|
||||
"type sys._esys_106 (sys._esys_107 sys._osys_572 sys._isys_574)\n"
|
||||
"var !sys.chanrecv3 sys._esys_106\n"
|
||||
"type sys._esys_111 {}\n"
|
||||
"type sys._esys_112 {}\n"
|
||||
"type sys._esys_113 {}\n"
|
||||
"type sys._esys_114 {}\n"
|
||||
"type sys._esys_111 (sys._esys_112 sys._esys_113 sys._esys_114)\n"
|
||||
"var !sys.gosched sys._esys_111\n"
|
||||
"type sys._esys_114 1 sys.any\n"
|
||||
"type sys._esys_113 *sys._esys_114\n"
|
||||
"type sys._isys_580 {hchan sys._esys_113 elem sys.any}\n"
|
||||
"type sys._esys_110 (sys._esys_111 sys._esys_112 sys._isys_580)\n"
|
||||
"var !sys.chansend1 sys._esys_110\n"
|
||||
"type sys._esys_116 {}\n"
|
||||
"type sys._esys_117 {}\n"
|
||||
"type sys._esys_118 {}\n"
|
||||
"type sys._esys_115 (sys._esys_116 sys._esys_117 sys._esys_118)\n"
|
||||
"var !sys.goexit sys._esys_115\n"
|
||||
"type sys._osys_585 {pres sys.bool}\n"
|
||||
"type sys._esys_118 1 sys.any\n"
|
||||
"type sys._esys_117 *sys._esys_118\n"
|
||||
"type sys._isys_587 {hchan sys._esys_117 elem sys.any}\n"
|
||||
"type sys._esys_115 (sys._esys_116 sys._osys_585 sys._isys_587)\n"
|
||||
"var !sys.chansend2 sys._esys_115\n"
|
||||
"type sys._esys_120 {}\n"
|
||||
"type sys._osys_582 {_esys_579 sys.string _esys_580 sys.bool}\n"
|
||||
"type sys._isys_584 {_esys_581 sys.string}\n"
|
||||
"type sys._esys_119 (sys._esys_120 sys._osys_582 sys._isys_584)\n"
|
||||
"var !sys.readfile sys._esys_119\n"
|
||||
"type sys._esys_121 {}\n"
|
||||
"type sys._esys_122 {}\n"
|
||||
"type sys._osys_591 {_esys_588 sys.bool}\n"
|
||||
"type sys._isys_593 {_esys_589 sys.string _esys_590 sys.string}\n"
|
||||
"type sys._esys_121 (sys._esys_122 sys._osys_591 sys._isys_593)\n"
|
||||
"var !sys.writefile sys._esys_121\n"
|
||||
"type sys._esys_119 (sys._esys_120 sys._esys_121 sys._esys_122)\n"
|
||||
"var !sys.gosched sys._esys_119\n"
|
||||
"type sys._esys_124 {}\n"
|
||||
"type sys._osys_603 {_esys_598 sys.int32 _esys_599 sys.int32}\n"
|
||||
"type sys._esys_125 *sys.uint8\n"
|
||||
"type sys._isys_605 {_esys_600 sys._esys_125 _esys_601 sys.int32 _esys_602 sys.int32}\n"
|
||||
"type sys._esys_123 (sys._esys_124 sys._osys_603 sys._isys_605)\n"
|
||||
"var !sys.bytestorune sys._esys_123\n"
|
||||
"type sys._esys_127 {}\n"
|
||||
"type sys._osys_616 {_esys_611 sys.int32 _esys_612 sys.int32}\n"
|
||||
"type sys._isys_618 {_esys_613 sys.string _esys_614 sys.int32 _esys_615 sys.int32}\n"
|
||||
"type sys._esys_126 (sys._esys_127 sys._osys_616 sys._isys_618)\n"
|
||||
"var !sys.stringtorune sys._esys_126\n"
|
||||
"type sys._esys_129 {}\n"
|
||||
"type sys._esys_125 {}\n"
|
||||
"type sys._esys_126 {}\n"
|
||||
"type sys._esys_123 (sys._esys_124 sys._esys_125 sys._esys_126)\n"
|
||||
"var !sys.goexit sys._esys_123\n"
|
||||
"type sys._esys_128 {}\n"
|
||||
"type sys._osys_598 {_esys_595 sys.string _esys_596 sys.bool}\n"
|
||||
"type sys._isys_600 {_esys_597 sys.string}\n"
|
||||
"type sys._esys_127 (sys._esys_128 sys._osys_598 sys._isys_600)\n"
|
||||
"var !sys.readfile sys._esys_127\n"
|
||||
"type sys._esys_130 {}\n"
|
||||
"type sys._isys_625 {_esys_624 sys.int32}\n"
|
||||
"type sys._esys_128 (sys._esys_129 sys._esys_130 sys._isys_625)\n"
|
||||
"var !sys.exit sys._esys_128\n"
|
||||
"type sys._osys_607 {_esys_604 sys.bool}\n"
|
||||
"type sys._isys_609 {_esys_605 sys.string _esys_606 sys.string}\n"
|
||||
"type sys._esys_129 (sys._esys_130 sys._osys_607 sys._isys_609)\n"
|
||||
"var !sys.writefile sys._esys_129\n"
|
||||
"type sys._esys_132 {}\n"
|
||||
"type sys._osys_619 {_esys_614 sys.int32 _esys_615 sys.int32}\n"
|
||||
"type sys._esys_133 *sys.uint8\n"
|
||||
"type sys._isys_621 {_esys_616 sys._esys_133 _esys_617 sys.int32 _esys_618 sys.int32}\n"
|
||||
"type sys._esys_131 (sys._esys_132 sys._osys_619 sys._isys_621)\n"
|
||||
"var !sys.bytestorune sys._esys_131\n"
|
||||
"type sys._esys_135 {}\n"
|
||||
"type sys._osys_632 {_esys_627 sys.int32 _esys_628 sys.int32}\n"
|
||||
"type sys._isys_634 {_esys_629 sys.string _esys_630 sys.int32 _esys_631 sys.int32}\n"
|
||||
"type sys._esys_134 (sys._esys_135 sys._osys_632 sys._isys_634)\n"
|
||||
"var !sys.stringtorune sys._esys_134\n"
|
||||
"type sys._esys_137 {}\n"
|
||||
"type sys._esys_138 {}\n"
|
||||
"type sys._isys_641 {_esys_640 sys.int32}\n"
|
||||
"type sys._esys_136 (sys._esys_137 sys._esys_138 sys._isys_641)\n"
|
||||
"var !sys.exit sys._esys_136\n"
|
||||
"))\n"
|
||||
;
|
||||
|
|
|
@ -278,6 +278,7 @@ loop:
|
|||
case ORECV:
|
||||
if(cl == 2 && cr == 1) {
|
||||
// a,b = <chan - chanrecv2
|
||||
walktype(r->left, Erv);
|
||||
if(!isptrto(r->left->type, TCHAN))
|
||||
break;
|
||||
l = chanop(n, top);
|
||||
|
@ -585,25 +586,24 @@ loop:
|
|||
goto ret;
|
||||
|
||||
case OSEND:
|
||||
if(top != Elv)
|
||||
if(top == Elv)
|
||||
goto nottop;
|
||||
walktype(n->left, Erv);
|
||||
t = n->left->type;
|
||||
if(!isptrto(t, TCHAN))
|
||||
goto badt;
|
||||
n->type = t->type->type;
|
||||
walktype(n->right, Erv);
|
||||
*n = *chanop(n, top);
|
||||
goto ret;
|
||||
|
||||
case ORECV:
|
||||
if(top != Erv)
|
||||
if(top == Elv)
|
||||
goto nottop;
|
||||
walktype(n->left, Erv);
|
||||
t = n->left->type;
|
||||
if(!isptrto(t, TCHAN))
|
||||
goto badt;
|
||||
n->type = t->type->type;
|
||||
|
||||
*n = *chanop(n, top);
|
||||
if(n->right == N) {
|
||||
walktype(n->left, Erv); // chan
|
||||
*n = *chanop(n, top); // returns e blocking
|
||||
goto ret;
|
||||
}
|
||||
walktype(n->left, Elv); // e
|
||||
walktype(n->right, Erv); // chan
|
||||
*n = *chanop(n, top); // returns bool non-blocking
|
||||
goto ret;
|
||||
|
||||
case OSLICE:
|
||||
|
@ -1396,7 +1396,7 @@ fixmap(Type *tm)
|
|||
}
|
||||
|
||||
if(t->etype != TMAP) {
|
||||
fatal("fixmap: %O not map");
|
||||
fatal("fixmap: %lT not map", tm);
|
||||
return T;
|
||||
}
|
||||
|
||||
|
@ -1423,7 +1423,7 @@ fixchan(Type *tm)
|
|||
}
|
||||
|
||||
if(t->etype != TCHAN) {
|
||||
fatal("fixchan: %O not map");
|
||||
fatal("fixchan: %lT not chan", tm);
|
||||
return T;
|
||||
}
|
||||
|
||||
|
@ -1703,31 +1703,32 @@ chanop(Node *n, int top)
|
|||
cl = listcount(n->left);
|
||||
cr = listcount(n->right);
|
||||
|
||||
if(cl == 2 && cr == 1 && n->right->op == ORECV)
|
||||
goto recv2;
|
||||
if(cl != 1 || cr != 1 || n->left->op != OSEND)
|
||||
if(cl != 2 || cr != 1 || n->right->op != ORECV)
|
||||
goto shape;
|
||||
|
||||
// chansend(hchan *chan any, elem any);
|
||||
// chanrecv2(hchan *chan any) (elem any, pres bool);
|
||||
|
||||
t = fixchan(n->left->left->type);
|
||||
t = fixchan(n->right->left->type);
|
||||
if(t == T)
|
||||
break;
|
||||
|
||||
a = n->right; // val
|
||||
a = n->right->left; // chan
|
||||
r = a;
|
||||
a = n->left->left; // chan
|
||||
r = nod(OLIST, a, r);
|
||||
|
||||
on = syslook("chansend", 1);
|
||||
on = syslook("chanrecv2", 1);
|
||||
|
||||
argtype(on, t->type); // any-1
|
||||
argtype(on, t->type); // any-2
|
||||
|
||||
r = nod(OCALL, on, r);
|
||||
walktype(r, Erv);
|
||||
n->right = r;
|
||||
r = n;
|
||||
walktype(r, Etop);
|
||||
break;
|
||||
|
||||
case ORECV:
|
||||
if(n->right != N)
|
||||
goto recv2;
|
||||
|
||||
// chanrecv1(hchan *chan any) (elem any);
|
||||
|
||||
t = fixchan(n->left->type);
|
||||
|
@ -1747,12 +1748,12 @@ chanop(Node *n, int top)
|
|||
|
||||
recv2:
|
||||
// chanrecv2(hchan *chan any) (elem any, pres bool);
|
||||
|
||||
t = fixchan(n->right->left->type);
|
||||
fatal("recv2 not yet");
|
||||
t = fixchan(n->right->type);
|
||||
if(t == T)
|
||||
break;
|
||||
|
||||
a = n->right->left; // chan
|
||||
a = n->right; // chan
|
||||
r = a;
|
||||
|
||||
on = syslook("chanrecv2", 1);
|
||||
|
@ -1764,6 +1765,48 @@ chanop(Node *n, int top)
|
|||
r = n;
|
||||
walktype(r, Etop);
|
||||
break;
|
||||
|
||||
case OSEND:
|
||||
t = fixchan(n->left->type);
|
||||
if(t == T)
|
||||
break;
|
||||
if(top != Etop)
|
||||
goto send2;
|
||||
|
||||
// chansend1(hchan *chan any, elem any);
|
||||
t = fixchan(n->left->type);
|
||||
if(t == T)
|
||||
break;
|
||||
|
||||
a = n->right; // e
|
||||
r = a;
|
||||
a = n->left; // chan
|
||||
r = nod(OLIST, a, r);
|
||||
|
||||
on = syslook("chansend1", 1);
|
||||
argtype(on, t->type); // any-1
|
||||
argtype(on, t->type); // any-2
|
||||
r = nod(OCALL, on, r);
|
||||
walktype(r, top);
|
||||
break;
|
||||
|
||||
send2:
|
||||
// chansend2(hchan *chan any, val any) (pres bool);
|
||||
t = fixchan(n->left->type);
|
||||
if(t == T)
|
||||
break;
|
||||
|
||||
a = n->right; // e
|
||||
r = a;
|
||||
a = n->left; // chan
|
||||
r = nod(OLIST, a, r);
|
||||
|
||||
on = syslook("chansend2", 1);
|
||||
argtype(on, t->type); // any-1
|
||||
argtype(on, t->type); // any-2
|
||||
r = nod(OCALL, on, r);
|
||||
walktype(r, top);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
|
||||
|
|
|
@ -93,9 +93,9 @@ sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
|
|||
|
||||
}
|
||||
|
||||
// chansend(hchan *chan any, elem any);
|
||||
// chansend1(hchan *chan any, elem any);
|
||||
void
|
||||
sys·chansend(Hchan* c, ...)
|
||||
sys·chansend1(Hchan* c, ...)
|
||||
{
|
||||
byte *ae;
|
||||
G *gr;
|
||||
|
@ -137,6 +137,49 @@ asynch:
|
|||
gr->status = Grunnable;
|
||||
}
|
||||
|
||||
// chansend2(hchan *chan any, elem any) (pres bool);
|
||||
void
|
||||
sys·chansend2(Hchan* c, ...)
|
||||
{
|
||||
byte *ae, *ap;
|
||||
G *gr;
|
||||
|
||||
ae = (byte*)&c + c->eo;
|
||||
ap = (byte*)&c + c->po;
|
||||
if(debug) {
|
||||
prints("chansend: chan=");
|
||||
sys·printpointer(c);
|
||||
prints("; elem=");
|
||||
c->elemalg->print(c->elemsize, ae);
|
||||
prints("\n");
|
||||
}
|
||||
if(c->dataqsiz > 0)
|
||||
goto asynch;
|
||||
|
||||
gr = dequeue(&c->recvq);
|
||||
if(gr != nil) {
|
||||
c->elemalg->copy(c->elemsize, gr->elem, ae);
|
||||
gr->status = Grunnable;
|
||||
*ap = true;
|
||||
return;
|
||||
}
|
||||
*ap = false;
|
||||
return;
|
||||
|
||||
asynch:
|
||||
if(c->qcount >= c->dataqsiz) {
|
||||
*ap = false;
|
||||
return;
|
||||
}
|
||||
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
|
||||
c->senddataq = c->senddataq->link;
|
||||
c->qcount++;
|
||||
gr = dequeue(&c->recvq);
|
||||
if(gr != nil)
|
||||
gr->status = Grunnable;
|
||||
*ap = true;
|
||||
}
|
||||
|
||||
// chanrecv1(hchan *chan any) (elem any);
|
||||
void
|
||||
sys·chanrecv1(Hchan* c, ...)
|
||||
|
|
|
@ -28,12 +28,12 @@ func Filter(in *chan<- int, out *chan-< int, prime int) {
|
|||
}
|
||||
|
||||
// The prime sieve: Daisy-chain Filter processes together.
|
||||
func Sieve() {
|
||||
func Sieve(primes *chan-< int) {
|
||||
ch := new(chan int); // Create a new channel.
|
||||
go Generate(ch); // Start Generate() as a subprocess.
|
||||
for {
|
||||
prime := <-ch;
|
||||
print prime, "\n";
|
||||
primes -< prime;
|
||||
ch1 := new(chan int);
|
||||
go Filter(ch, ch1, prime);
|
||||
ch = ch1
|
||||
|
|
Loading…
Reference in a new issue