Commit ac048ce7 authored by Ken Thompson's avatar Ken Thompson

new chan syntax

SVN=127437
parent 33101926
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
%token LFOR LIF LELSE LSWITCH LCASE LDEFAULT %token LFOR LIF LELSE LSWITCH LCASE LDEFAULT
%token LBREAK LCONTINUE LGO LGOTO LRANGE %token LBREAK LCONTINUE LGO LGOTO LRANGE
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT %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 LNIL LTRUE LFALSE LIOTA
%token LPANIC LPRINT LIGNORE %token LPANIC LPRINT LIGNORE
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
%left LOROR %left LOROR
%left LANDAND %left LANDAND
%left LSEND LRECV
%left LEQ LNE LLE LGE LLT LGT %left LEQ LNE LLE LGE LLT LGT
%left '+' '-' '|' '^' %left '+' '-' '|' '^'
%left '*' '/' '%' '&' LLSH LRSH %left '*' '/' '%' '&' LLSH LRSH
...@@ -599,6 +600,14 @@ expr: ...@@ -599,6 +600,14 @@ expr:
{ {
$$ = nod(ORSH, $1, $3); $$ = nod(ORSH, $1, $3);
} }
| expr LSEND expr
{
$$ = nod(OSEND, $1, $3);
}
| expr LRECV expr
{
$$ = nod(ORECV, $1, $3);
}
uexpr: uexpr:
pexpr pexpr
...@@ -631,14 +640,10 @@ uexpr: ...@@ -631,14 +640,10 @@ uexpr:
{ {
$$ = nod(OCOM, $2, N); $$ = nod(OCOM, $2, N);
} }
| LLT uexpr | LRECV uexpr
{ {
$$ = nod(ORECV, $2, N); $$ = nod(ORECV, $2, N);
} }
| LGT uexpr
{
$$ = nod(OSEND, $2, N);
}
pexpr: pexpr:
LLITERAL LLITERAL
...@@ -907,22 +912,14 @@ chandir: ...@@ -907,22 +912,14 @@ chandir:
{ {
$$ = Cboth; $$ = Cboth;
} }
| LLT | LRECV
{ {
$$ = Crecv; $$ = Crecv;
} }
| LGT | LSEND
{ {
$$ = Csend; $$ = Csend;
} }
| LLT LGT
{
$$ = Cboth;
}
| LGT LLT
{
$$ = 0;
}
keyval: keyval:
expr ':' expr expr ':' expr
...@@ -1027,6 +1024,7 @@ fnliteral: ...@@ -1027,6 +1024,7 @@ fnliteral:
$$ = newname(lookup(namebuf)); $$ = newname(lookup(namebuf));
addvar($$, $1, PEXTERN); addvar($$, $1, PEXTERN);
dump("lit1", $$);
{ {
Node *n; Node *n;
...@@ -1037,10 +1035,13 @@ fnliteral: ...@@ -1037,10 +1035,13 @@ fnliteral:
n->nbody = $3; n->nbody = $3;
if(n->nbody == N) if(n->nbody == N)
n->nbody = nod(ORETURN, N, N); n->nbody = nod(ORETURN, N, N);
dump("comp1", n);
compile(n); compile(n);
dump("comp2", n);
} }
$$ = nod(OADDR, $$, N); $$ = nod(OADDR, $$, N);
dump("lit2", $$);
} }
fnbody: fnbody:
......
...@@ -480,6 +480,10 @@ l0: ...@@ -480,6 +480,10 @@ l0:
c = LDEC; c = LDEC;
goto lx; goto lx;
} }
if(c1 == '<') {
c = LSEND;
goto lx;
}
if(c1 == '=') { if(c1 == '=') {
c = OSUB; c = OSUB;
goto asop; goto asop;
...@@ -519,6 +523,10 @@ l0: ...@@ -519,6 +523,10 @@ l0:
c = LLE; c = LLE;
goto lx; goto lx;
} }
if(c1 == '-') {
c = LRECV;
goto lx;
}
c = LLT; c = LLT;
break; break;
......
...@@ -45,9 +45,11 @@ func mapassign1(hmap *map[any]any, key any, val any); ...@@ -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 mapassign2(hmap *map[any]any, key any, val any, pres bool);
func newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any); 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 chanrecv1(hchan *chan any) (elem any);
func chanrecv2(hchan *chan any) (elem any, pres bool); 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 gosched();
func goexit(); func goexit();
...@@ -104,9 +106,11 @@ export ...@@ -104,9 +106,11 @@ export
// chan // chan
newchan newchan
chansend
chanrecv1 chanrecv1
chanrecv2 chanrecv2
chanrecv3
chansend1
chansend2
// go routines // go routines
gosched gosched
......
...@@ -190,61 +190,75 @@ char* sysimport = ...@@ -190,61 +190,75 @@ char* sysimport =
"type sys._esys_094 (sys._esys_095 sys._osys_548 sys._isys_550)\n" "type sys._esys_094 (sys._esys_095 sys._osys_548 sys._isys_550)\n"
"var !sys.newchan sys._esys_094\n" "var !sys.newchan sys._esys_094\n"
"type sys._esys_099 {}\n" "type sys._esys_099 {}\n"
"type sys._esys_100 {}\n" "type sys._osys_557 {elem sys.any}\n"
"type sys._esys_102 1 sys.any\n" "type sys._esys_101 1 sys.any\n"
"type sys._esys_101 *sys._esys_102\n" "type sys._esys_100 *sys._esys_101\n"
"type sys._isys_557 {hchan sys._esys_101 elem sys.any}\n" "type sys._isys_559 {hchan sys._esys_100}\n"
"type sys._esys_098 (sys._esys_099 sys._esys_100 sys._isys_557)\n" "type sys._esys_098 (sys._esys_099 sys._osys_557 sys._isys_559)\n"
"var !sys.chansend sys._esys_098\n" "var !sys.chanrecv1 sys._esys_098\n"
"type sys._esys_104 {}\n" "type sys._esys_103 {}\n"
"type sys._osys_562 {elem sys.any}\n" "type sys._osys_564 {elem sys.any pres sys.bool}\n"
"type sys._esys_106 1 sys.any\n" "type sys._esys_105 1 sys.any\n"
"type sys._esys_105 *sys._esys_106\n" "type sys._esys_104 *sys._esys_105\n"
"type sys._isys_564 {hchan sys._esys_105}\n" "type sys._isys_566 {hchan sys._esys_104}\n"
"type sys._esys_103 (sys._esys_104 sys._osys_562 sys._isys_564)\n" "type sys._esys_102 (sys._esys_103 sys._osys_564 sys._isys_566)\n"
"var !sys.chanrecv1 sys._esys_103\n" "var !sys.chanrecv2 sys._esys_102\n"
"type sys._esys_108 {}\n" "type sys._esys_107 {}\n"
"type sys._osys_569 {elem sys.any pres sys.bool}\n" "type sys._osys_572 {elem sys.any pres sys.bool}\n"
"type sys._esys_110 1 sys.any\n" "type sys._esys_109 1 sys.any\n"
"type sys._esys_109 *sys._esys_110\n" "type sys._esys_108 *sys._esys_109\n"
"type sys._isys_571 {hchan sys._esys_109}\n" "type sys._isys_574 {hchan sys._esys_108}\n"
"type sys._esys_107 (sys._esys_108 sys._osys_569 sys._isys_571)\n" "type sys._esys_106 (sys._esys_107 sys._osys_572 sys._isys_574)\n"
"var !sys.chanrecv2 sys._esys_107\n" "var !sys.chanrecv3 sys._esys_106\n"
"type sys._esys_111 {}\n"
"type sys._esys_112 {}\n" "type sys._esys_112 {}\n"
"type sys._esys_113 {}\n" "type sys._esys_114 1 sys.any\n"
"type sys._esys_114 {}\n" "type sys._esys_113 *sys._esys_114\n"
"type sys._esys_111 (sys._esys_112 sys._esys_113 sys._esys_114)\n" "type sys._isys_580 {hchan sys._esys_113 elem sys.any}\n"
"var !sys.gosched sys._esys_111\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_116 {}\n"
"type sys._esys_117 {}\n" "type sys._osys_585 {pres sys.bool}\n"
"type sys._esys_118 {}\n" "type sys._esys_118 1 sys.any\n"
"type sys._esys_115 (sys._esys_116 sys._esys_117 sys._esys_118)\n" "type sys._esys_117 *sys._esys_118\n"
"var !sys.goexit sys._esys_115\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._esys_120 {}\n"
"type sys._osys_582 {_esys_579 sys.string _esys_580 sys.bool}\n" "type sys._esys_121 {}\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_122 {}\n" "type sys._esys_122 {}\n"
"type sys._osys_591 {_esys_588 sys.bool}\n" "type sys._esys_119 (sys._esys_120 sys._esys_121 sys._esys_122)\n"
"type sys._isys_593 {_esys_589 sys.string _esys_590 sys.string}\n" "var !sys.gosched sys._esys_119\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_124 {}\n" "type sys._esys_124 {}\n"
"type sys._osys_603 {_esys_598 sys.int32 _esys_599 sys.int32}\n" "type sys._esys_125 {}\n"
"type sys._esys_125 *sys.uint8\n" "type sys._esys_126 {}\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._esys_125 sys._esys_126)\n"
"type sys._esys_123 (sys._esys_124 sys._osys_603 sys._isys_605)\n" "var !sys.goexit sys._esys_123\n"
"var !sys.bytestorune sys._esys_123\n" "type sys._esys_128 {}\n"
"type sys._esys_127 {}\n" "type sys._osys_598 {_esys_595 sys.string _esys_596 sys.bool}\n"
"type sys._osys_616 {_esys_611 sys.int32 _esys_612 sys.int32}\n" "type sys._isys_600 {_esys_597 sys.string}\n"
"type sys._isys_618 {_esys_613 sys.string _esys_614 sys.int32 _esys_615 sys.int32}\n" "type sys._esys_127 (sys._esys_128 sys._osys_598 sys._isys_600)\n"
"type sys._esys_126 (sys._esys_127 sys._osys_616 sys._isys_618)\n" "var !sys.readfile sys._esys_127\n"
"var !sys.stringtorune sys._esys_126\n"
"type sys._esys_129 {}\n"
"type sys._esys_130 {}\n" "type sys._esys_130 {}\n"
"type sys._isys_625 {_esys_624 sys.int32}\n" "type sys._osys_607 {_esys_604 sys.bool}\n"
"type sys._esys_128 (sys._esys_129 sys._esys_130 sys._isys_625)\n" "type sys._isys_609 {_esys_605 sys.string _esys_606 sys.string}\n"
"var !sys.exit sys._esys_128\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" "))\n"
; ;
...@@ -278,6 +278,7 @@ loop: ...@@ -278,6 +278,7 @@ loop:
case ORECV: case ORECV:
if(cl == 2 && cr == 1) { if(cl == 2 && cr == 1) {
// a,b = <chan - chanrecv2 // a,b = <chan - chanrecv2
walktype(r->left, Erv);
if(!isptrto(r->left->type, TCHAN)) if(!isptrto(r->left->type, TCHAN))
break; break;
l = chanop(n, top); l = chanop(n, top);
...@@ -585,25 +586,24 @@ loop: ...@@ -585,25 +586,24 @@ loop:
goto ret; goto ret;
case OSEND: case OSEND:
if(top != Elv) if(top == Elv)
goto nottop; goto nottop;
walktype(n->left, Erv); walktype(n->left, Erv);
t = n->left->type; walktype(n->right, Erv);
if(!isptrto(t, TCHAN)) *n = *chanop(n, top);
goto badt;
n->type = t->type->type;
goto ret; goto ret;
case ORECV: case ORECV:
if(top != Erv) if(top == Elv)
goto nottop; goto nottop;
walktype(n->left, Erv); if(n->right == N) {
t = n->left->type; walktype(n->left, Erv); // chan
if(!isptrto(t, TCHAN)) *n = *chanop(n, top); // returns e blocking
goto badt; goto ret;
n->type = t->type->type; }
walktype(n->left, Elv); // e
*n = *chanop(n, top); walktype(n->right, Erv); // chan
*n = *chanop(n, top); // returns bool non-blocking
goto ret; goto ret;
case OSLICE: case OSLICE:
...@@ -1396,7 +1396,7 @@ fixmap(Type *tm) ...@@ -1396,7 +1396,7 @@ fixmap(Type *tm)
} }
if(t->etype != TMAP) { if(t->etype != TMAP) {
fatal("fixmap: %O not map"); fatal("fixmap: %lT not map", tm);
return T; return T;
} }
...@@ -1423,7 +1423,7 @@ fixchan(Type *tm) ...@@ -1423,7 +1423,7 @@ fixchan(Type *tm)
} }
if(t->etype != TCHAN) { if(t->etype != TCHAN) {
fatal("fixchan: %O not map"); fatal("fixchan: %lT not chan", tm);
return T; return T;
} }
...@@ -1703,31 +1703,32 @@ chanop(Node *n, int top) ...@@ -1703,31 +1703,32 @@ chanop(Node *n, int top)
cl = listcount(n->left); cl = listcount(n->left);
cr = listcount(n->right); cr = listcount(n->right);
if(cl == 2 && cr == 1 && n->right->op == ORECV) if(cl != 2 || cr != 1 || n->right->op != ORECV)
goto recv2;
if(cl != 1 || cr != 1 || n->left->op != OSEND)
goto shape; 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) if(t == T)
break; break;
a = n->right; // val a = n->right->left; // chan
r = a; 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-1
argtype(on, t->type); // any-2 argtype(on, t->type); // any-2
r = nod(OCALL, on, r); r = nod(OCALL, on, r);
walktype(r, Erv); n->right = r;
r = n;
walktype(r, Etop);
break; break;
case ORECV: case ORECV:
if(n->right != N)
goto recv2;
// chanrecv1(hchan *chan any) (elem any); // chanrecv1(hchan *chan any) (elem any);
t = fixchan(n->left->type); t = fixchan(n->left->type);
...@@ -1747,12 +1748,12 @@ chanop(Node *n, int top) ...@@ -1747,12 +1748,12 @@ chanop(Node *n, int top)
recv2: recv2:
// chanrecv2(hchan *chan any) (elem any, pres bool); // chanrecv2(hchan *chan any) (elem any, pres bool);
fatal("recv2 not yet");
t = fixchan(n->right->left->type); t = fixchan(n->right->type);
if(t == T) if(t == T)
break; break;
a = n->right->left; // chan a = n->right; // chan
r = a; r = a;
on = syslook("chanrecv2", 1); on = syslook("chanrecv2", 1);
...@@ -1764,6 +1765,48 @@ chanop(Node *n, int top) ...@@ -1764,6 +1765,48 @@ chanop(Node *n, int top)
r = n; r = n;
walktype(r, Etop); walktype(r, Etop);
break; 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; return r;
......
...@@ -93,9 +93,9 @@ sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint, ...@@ -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 void
sys·chansend(Hchan* c, ...) sys·chansend1(Hchan* c, ...)
{ {
byte *ae; byte *ae;
G *gr; G *gr;
...@@ -137,6 +137,49 @@ asynch: ...@@ -137,6 +137,49 @@ asynch:
gr->status = Grunnable; 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); // chanrecv1(hchan *chan any) (elem any);
void void
sys·chanrecv1(Hchan* c, ...) sys·chanrecv1(Hchan* c, ...)
......
...@@ -28,12 +28,12 @@ func Filter(in *chan<- int, out *chan-< int, prime int) { ...@@ -28,12 +28,12 @@ func Filter(in *chan<- int, out *chan-< int, prime int) {
} }
// The prime sieve: Daisy-chain Filter processes together. // The prime sieve: Daisy-chain Filter processes together.
func Sieve() { func Sieve(primes *chan-< int) {
ch := new(chan int); // Create a new channel. ch := new(chan int); // Create a new channel.
go Generate(ch); // Start Generate() as a subprocess. go Generate(ch); // Start Generate() as a subprocess.
for { for {
prime := <-ch; prime := <-ch;
print prime, "\n"; primes -< prime;
ch1 := new(chan int); ch1 := new(chan int);
go Filter(ch, ch1, prime); go Filter(ch, ch1, prime);
ch = ch1 ch = ch1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment