Updating tests to use pipes.
This commit is contained in:
parent
fa4134611d
commit
7b03832c95
src
libcore
libsyntax/ext/pipes
test
@ -138,6 +138,15 @@ fn with<A,B>(future: future<A>, blk: fn(A) -> B) -> B {
|
||||
}
|
||||
|
||||
// The pipe protocol, generated by pipec
|
||||
/*
|
||||
proto! future_pipe {
|
||||
waiting:recv<T:send> {
|
||||
completed(T) -> terminated
|
||||
}
|
||||
|
||||
terminated { }
|
||||
}
|
||||
*/
|
||||
mod future_pipe {
|
||||
fn init<T: send>() -> (client::waiting<T>, server::waiting<T>) {
|
||||
{ let (s, c) = pipes::entangle(); (c, s) }
|
||||
|
@ -10,11 +10,10 @@ impl proto_parser for parser {
|
||||
fn parse_proto(id: ident) -> protocol {
|
||||
let proto = protocol(id);
|
||||
|
||||
self.expect(token::LBRACE);
|
||||
|
||||
while self.token != token::RBRACE {
|
||||
self.parse_state(proto);
|
||||
}
|
||||
self.parse_unspanned_seq(token::LBRACE,
|
||||
token::RBRACE,
|
||||
{sep: none, trailing_sep_allowed: false},
|
||||
|self| self.parse_state(proto));
|
||||
|
||||
ret proto;
|
||||
}
|
||||
@ -35,29 +34,44 @@ impl proto_parser for parser {
|
||||
_ { fail }
|
||||
};
|
||||
|
||||
let state = proto.add_state(id, dir);
|
||||
// TODO: add typarams too.
|
||||
|
||||
self.expect(token::LBRACE);
|
||||
|
||||
while self.token != token::RBRACE {
|
||||
let mname = self.parse_ident();
|
||||
|
||||
// TODO: parse data
|
||||
|
||||
self.expect(token::RARROW);
|
||||
|
||||
let next = self.parse_ident();
|
||||
// TODO: parse next types
|
||||
|
||||
state.add_message(mname, ~[], next, ~[]);
|
||||
|
||||
alt copy self.token {
|
||||
token::COMMA { self.bump() }
|
||||
token::RBRACE { }
|
||||
_ { fail }
|
||||
}
|
||||
let typarms = if self.token == token::LT {
|
||||
self.parse_ty_params()
|
||||
}
|
||||
self.bump();
|
||||
else { ~[] };
|
||||
|
||||
let state = proto.add_state_poly(id, dir, typarms);
|
||||
|
||||
// parse the messages
|
||||
self.parse_unspanned_seq(
|
||||
token::LBRACE, token::RBRACE,
|
||||
{sep: some(token::COMMA), trailing_sep_allowed: true},
|
||||
|self| {
|
||||
let mname = self.parse_ident();
|
||||
|
||||
let args = if self.token == token::LPAREN {
|
||||
self.parse_unspanned_seq(token::LPAREN,
|
||||
token::RPAREN,
|
||||
{sep: some(token::COMMA),
|
||||
trailing_sep_allowed: true},
|
||||
|p| p.parse_ty(false))
|
||||
}
|
||||
else { ~[] };
|
||||
|
||||
self.expect(token::RARROW);
|
||||
|
||||
let next = self.parse_ident();
|
||||
|
||||
let ntys = if self.token == token::LT {
|
||||
self.parse_unspanned_seq(token::LT,
|
||||
token::GT,
|
||||
{sep: some(token::COMMA),
|
||||
trailing_sep_allowed: true},
|
||||
|p| p.parse_ty(false))
|
||||
}
|
||||
else { ~[] };
|
||||
|
||||
state.add_message(mname, args, next, ntys);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
// that things will look really good once we get that lock out of the
|
||||
// message path.
|
||||
|
||||
// This version uses semi-automatically compiled channel contracts.
|
||||
// This version uses automatically compiled channel contracts.
|
||||
|
||||
// xfail-pretty
|
||||
|
||||
@ -13,40 +13,15 @@ import future::future;
|
||||
use std;
|
||||
import std::time;
|
||||
|
||||
import ring::server::recv;
|
||||
import pipes::recv;
|
||||
|
||||
// This module was generated by the pipe compiler.
|
||||
mod ring {
|
||||
fn init() -> (client::num, server::num) { pipes::entangle() }
|
||||
enum num { num(uint, server::num), }
|
||||
mod client {
|
||||
fn num(-pipe: num, x_0: uint) -> num {
|
||||
let (c, s) = pipes::entangle();
|
||||
let message = ring::num(x_0, s);
|
||||
pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
type num = pipes::send_packet<ring::num>;
|
||||
}
|
||||
mod server {
|
||||
impl recv for num {
|
||||
fn recv() -> extern fn(-num) -> ring::num {
|
||||
fn recv(-pipe: num) -> ring::num {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type num = pipes::recv_packet<ring::num>;
|
||||
proto! ring {
|
||||
num:send {
|
||||
num(uint) -> num
|
||||
}
|
||||
}
|
||||
|
||||
fn macros() {
|
||||
#macro[
|
||||
[#recv[chan],
|
||||
chan.recv()(chan)]
|
||||
];
|
||||
|
||||
#macro[
|
||||
[#move[x],
|
||||
unsafe { let y <- *ptr::addr_of(x); y }]
|
||||
@ -68,7 +43,7 @@ fn thread_ring(i: uint,
|
||||
num_port2 <-> num_port;
|
||||
num_chan = some(ring::client::num(option::unwrap(num_chan2), i * j));
|
||||
let port = option::unwrap(num_port2);
|
||||
alt (#recv(port)) {
|
||||
alt (option::unwrap(recv(port))) {
|
||||
ring::num(_n, p) {
|
||||
//log(error, _n);
|
||||
num_port = some(#move(p));
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
|
||||
The first test case using pipes. The idea is to break this into
|
||||
several stages for prototyping. Here's the plan:
|
||||
|
||||
1. Write an already-compiled protocol using existing ports and chans.
|
||||
|
||||
2. Take the already-compiled version and add the low-level
|
||||
synchronization code instead.
|
||||
|
||||
3. Write a syntax extension to compile the protocols.
|
||||
|
||||
At some point, we'll need to add support for select.
|
||||
|
||||
*/
|
||||
|
||||
mod pingpong {
|
||||
import newcomm::*;
|
||||
|
||||
type pingpong = ~mut option<(chan<()>, port<()>)>;
|
||||
|
||||
fn init() -> (client::ping, server::ping) {
|
||||
let cp = port();
|
||||
let sp = port();
|
||||
let cc = chan(sp);
|
||||
let sc = chan(cp);
|
||||
|
||||
let client = client::ping(~mut some((cc, cp)));
|
||||
let server = server::ping(~mut some((sc, sp)));
|
||||
|
||||
(client, server)
|
||||
}
|
||||
|
||||
mod client {
|
||||
enum ping = pingpong;
|
||||
enum pong = pingpong;
|
||||
|
||||
fn do_ping(-c: ping) -> pong {
|
||||
let mut op = none;
|
||||
op <-> **c;
|
||||
let (c, s) <- option::unwrap(op);
|
||||
c.send(());
|
||||
let p <- (c, s);
|
||||
pong(~mut some(p))
|
||||
}
|
||||
|
||||
fn do_pong(-c: pong) -> (ping, ()) {
|
||||
let mut op = none;
|
||||
op <-> **c;
|
||||
let (c, s) <- option::unwrap(op);
|
||||
let d = s.recv();
|
||||
let p <- (c, s);
|
||||
(ping(~mut some(p)), d)
|
||||
}
|
||||
}
|
||||
|
||||
mod server {
|
||||
enum ping = pingpong;
|
||||
enum pong = pingpong;
|
||||
|
||||
fn do_ping(-c: ping) -> (pong, ()) {
|
||||
let mut op = none;
|
||||
op <-> **c;
|
||||
let (c, s) <- option::unwrap(op);
|
||||
let d = s.recv();
|
||||
let p <- (c, s);
|
||||
(pong(~mut some(p)), d)
|
||||
}
|
||||
|
||||
fn do_pong(-c: pong) -> ping {
|
||||
let mut op = none;
|
||||
op <-> **c;
|
||||
let (c, s) <- option::unwrap(op);
|
||||
c.send(());
|
||||
let p <- (c, s);
|
||||
ping(~mut some(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn client(-chan: pingpong::client::ping) {
|
||||
let chan = pingpong::client::do_ping(chan);
|
||||
log(error, "Sent ping");
|
||||
let (_chan, _data) = pingpong::client::do_pong(chan);
|
||||
log(error, "Received pong");
|
||||
}
|
||||
|
||||
fn server(-chan: pingpong::server::ping) {
|
||||
let (chan, _data) = pingpong::server::do_ping(chan);
|
||||
log(error, "Received ping");
|
||||
let _chan = pingpong::server::do_pong(chan);
|
||||
log(error, "Sent pong");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (client_, server_) = pingpong::init();
|
||||
let client_ = ~mut some(client_);
|
||||
let server_ = ~mut some(server_);
|
||||
|
||||
do task::spawn |move client_| {
|
||||
let mut client__ = none;
|
||||
*client_ <-> client__;
|
||||
client(option::unwrap(client__));
|
||||
};
|
||||
do task::spawn |move server_| {
|
||||
let mut server_ˊ = none;
|
||||
*server_ <-> server_ˊ;
|
||||
server(option::unwrap(server_ˊ));
|
||||
};
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
The first test case using pipes. The idea is to break this into
|
||||
several stages for prototyping. Here's the plan:
|
||||
|
||||
1. Write an already-compiled protocol using existing ports and chans.
|
||||
|
||||
2. Take the already-compiled version and add the low-level
|
||||
synchronization code instead. (That's what this file attempts to do)
|
||||
|
||||
3. Write a syntax extension to compile the protocols.
|
||||
|
||||
At some point, we'll need to add support for select.
|
||||
|
||||
*/
|
||||
|
||||
mod pingpong {
|
||||
enum ping = *pipes::packet<pong>;
|
||||
enum pong = *pipes::packet<ping>;
|
||||
|
||||
fn init() -> (client::ping, server::ping) {
|
||||
pipes::entangle()
|
||||
}
|
||||
|
||||
mod client {
|
||||
type ping = pipes::send_packet<pingpong::ping>;
|
||||
type pong = pipes::recv_packet<pingpong::pong>;
|
||||
|
||||
fn do_ping(-c: ping) -> pong {
|
||||
let p = pipes::packet();
|
||||
|
||||
pipes::send(c, pingpong::ping(p));
|
||||
pipes::recv_packet(p)
|
||||
}
|
||||
|
||||
fn do_pong(-c: pong) -> (ping, ()) {
|
||||
let packet = pipes::recv(c);
|
||||
if packet == none {
|
||||
fail "sender closed the connection"
|
||||
}
|
||||
(pipes::send_packet(*option::unwrap(packet)), ())
|
||||
}
|
||||
}
|
||||
|
||||
mod server {
|
||||
type ping = pipes::recv_packet<pingpong::ping>;
|
||||
type pong = pipes::send_packet<pingpong::pong>;
|
||||
|
||||
fn do_ping(-c: ping) -> (pong, ()) {
|
||||
let packet = pipes::recv(c);
|
||||
if packet == none {
|
||||
fail "sender closed the connection"
|
||||
}
|
||||
(pipes::send_packet(*option::unwrap(packet)), ())
|
||||
}
|
||||
|
||||
fn do_pong(-c: pong) -> ping {
|
||||
let p = pipes::packet();
|
||||
pipes::send(c, pingpong::pong(p));
|
||||
pipes::recv_packet(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn client(-chan: pingpong::client::ping) {
|
||||
let chan = pingpong::client::do_ping(chan);
|
||||
log(error, "Sent ping");
|
||||
let (chan, _data) = pingpong::client::do_pong(chan);
|
||||
log(error, "Received pong");
|
||||
}
|
||||
|
||||
fn server(-chan: pingpong::server::ping) {
|
||||
let (chan, _data) = pingpong::server::do_ping(chan);
|
||||
log(error, "Received ping");
|
||||
let chan = pingpong::server::do_pong(chan);
|
||||
log(error, "Sent pong");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (client_, server_) = pingpong::init();
|
||||
let client_ = ~mut some(client_);
|
||||
let server_ = ~mut some(server_);
|
||||
|
||||
do task::spawn |move client_| {
|
||||
let mut client__ = none;
|
||||
*client_ <-> client__;
|
||||
client(option::unwrap(client__));
|
||||
};
|
||||
do task::spawn |move server_| {
|
||||
let mut server_ˊ = none;
|
||||
*server_ <-> server_ˊ;
|
||||
server(option::unwrap(server_ˊ));
|
||||
};
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
The first test case using pipes. The idea is to break this into
|
||||
several stages for prototyping. Here's the plan:
|
||||
|
||||
1. Write an already-compiled protocol using existing ports and chans.
|
||||
|
||||
2. Take the already-compiled version and add the low-level
|
||||
synchronization code instead.
|
||||
|
||||
3. Write a syntax extension to compile the protocols.
|
||||
|
||||
At some point, we'll need to add support for select.
|
||||
|
||||
This file does horrible things to pretend we have self-move.
|
||||
|
||||
*/
|
||||
|
||||
mod pingpong {
|
||||
enum ping { ping, }
|
||||
enum ping_message = *pipes::packet<pong_message>;
|
||||
enum pong { pong, }
|
||||
enum pong_message = *pipes::packet<ping_message>;
|
||||
|
||||
fn init() -> (client::ping, server::ping) {
|
||||
pipes::entangle()
|
||||
}
|
||||
|
||||
mod client {
|
||||
type ping = pipes::send_packet<pingpong::ping_message>;
|
||||
type pong = pipes::recv_packet<pingpong::pong_message>;
|
||||
}
|
||||
|
||||
impl abominable for client::ping {
|
||||
fn send() -> fn@(-client::ping, ping) -> client::pong {
|
||||
|pipe, data| {
|
||||
let p = pipes::packet();
|
||||
pipes::send(pipe, pingpong::ping_message(p));
|
||||
pipes::recv_packet(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl abominable for client::pong {
|
||||
fn recv() -> fn@(-client::pong) -> (client::ping, pong) {
|
||||
|pipe| {
|
||||
let packet = pipes::recv(pipe);
|
||||
if packet == none {
|
||||
fail "sender closed the connection"
|
||||
}
|
||||
let p : pong_message = option::unwrap(packet);
|
||||
(pipes::send_packet(*p), pong)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod server {
|
||||
type ping = pipes::recv_packet<pingpong::ping_message>;
|
||||
type pong = pipes::send_packet<pingpong::pong_message>;
|
||||
}
|
||||
|
||||
impl abominable for server::ping {
|
||||
fn recv() -> fn@(-server::ping) -> (server::pong, ping) {
|
||||
|pipe| {
|
||||
let packet = pipes::recv(pipe);
|
||||
if packet == none {
|
||||
fail "sender closed the connection"
|
||||
}
|
||||
let p : ping_message = option::unwrap(packet);
|
||||
(pipes::send_packet(*p), ping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl abominable for server::pong {
|
||||
fn send() -> fn@(-server::pong, pong) -> server::ping {
|
||||
|pipe, data| {
|
||||
let p = pipes::packet();
|
||||
pipes::send(pipe, pingpong::pong_message(p));
|
||||
pipes::recv_packet(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod test {
|
||||
import pingpong::{ping, pong, abominable};
|
||||
|
||||
fn macros() {
|
||||
#macro[
|
||||
[#send[chan, data],
|
||||
chan.send()(chan, data)]
|
||||
];
|
||||
#macro[
|
||||
[#recv[chan],
|
||||
chan.recv()(chan)]
|
||||
];
|
||||
}
|
||||
|
||||
fn client(-chan: pingpong::client::ping) {
|
||||
let chan = #send(chan, ping);
|
||||
log(error, "Sent ping");
|
||||
let (chan, _data) = #recv(chan);
|
||||
log(error, "Received pong");
|
||||
}
|
||||
|
||||
fn server(-chan: pingpong::server::ping) {
|
||||
let (chan, _data) = #recv(chan);
|
||||
log(error, "Received ping");
|
||||
let chan = #send(chan, pong);
|
||||
log(error, "Sent pong");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (client_, server_) = pingpong::init();
|
||||
let client_ = ~mut some(client_);
|
||||
let server_ = ~mut some(server_);
|
||||
|
||||
do task::spawn |move client_| {
|
||||
let mut client__ = none;
|
||||
*client_ <-> client__;
|
||||
test::client(option::unwrap(client__));
|
||||
};
|
||||
do task::spawn |move server_| {
|
||||
let mut server_ˊ = none;
|
||||
*server_ <-> server_ˊ;
|
||||
test::server(option::unwrap(server_ˊ));
|
||||
};
|
||||
}
|
@ -1,72 +1,22 @@
|
||||
// xfail-pretty
|
||||
|
||||
use std;
|
||||
import std::timer::sleep;
|
||||
import std::uv;
|
||||
|
||||
import pipes::{recv, select};
|
||||
|
||||
// Compiled by pipec
|
||||
mod oneshot {
|
||||
fn init() -> (client::waiting, server::waiting) { pipes::entangle() }
|
||||
enum waiting { signal(server::signaled), }
|
||||
enum signaled { }
|
||||
mod client {
|
||||
fn signal(-pipe: waiting) -> signaled {
|
||||
let (c, s) = pipes::entangle();
|
||||
let message = oneshot::signal(s);
|
||||
pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
type waiting = pipes::send_packet<oneshot::waiting>;
|
||||
type signaled = pipes::send_packet<oneshot::signaled>;
|
||||
}
|
||||
mod server {
|
||||
impl recv for waiting {
|
||||
fn recv() -> extern fn(-waiting) -> oneshot::waiting {
|
||||
fn recv(-pipe: waiting) -> oneshot::waiting {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type waiting = pipes::recv_packet<oneshot::waiting>;
|
||||
impl recv for signaled {
|
||||
fn recv() -> extern fn(-signaled) -> oneshot::signaled {
|
||||
fn recv(-pipe: signaled) -> oneshot::signaled {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type signaled = pipes::recv_packet<oneshot::signaled>;
|
||||
proto! oneshot {
|
||||
waiting:send {
|
||||
signal -> signaled
|
||||
}
|
||||
|
||||
signaled:send { }
|
||||
}
|
||||
|
||||
mod stream {
|
||||
fn init<T: send>() -> (client::stream<T>, server::stream<T>) {
|
||||
pipes::entangle()
|
||||
}
|
||||
enum stream<T: send> { send(T, server::stream<T>), }
|
||||
mod client {
|
||||
fn send<T: send>(+pipe: stream<T>, +x_0: T) -> stream<T> {
|
||||
{
|
||||
let (c, s) = pipes::entangle();
|
||||
let message = stream::send(x_0, s);
|
||||
pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
}
|
||||
type stream<T: send> = pipes::send_packet<stream::stream<T>>;
|
||||
}
|
||||
mod server {
|
||||
impl recv<T: send> for stream<T> {
|
||||
fn recv() -> extern fn(+stream<T>) -> stream::stream<T> {
|
||||
fn recv<T: send>(+pipe: stream<T>) -> stream::stream<T> {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type stream<T: send> = pipes::recv_packet<stream::stream<T>>;
|
||||
proto! stream {
|
||||
stream:send<T:send> {
|
||||
send(T) -> stream<T>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,54 +1,22 @@
|
||||
// xfail-pretty
|
||||
|
||||
use std;
|
||||
import std::timer::sleep;
|
||||
import std::uv;
|
||||
import pipes::recv;
|
||||
|
||||
// Compiled by pipec
|
||||
mod oneshot {
|
||||
fn init() -> (client::waiting, server::waiting) { pipes::entangle() }
|
||||
enum waiting { signal(server::signaled), }
|
||||
enum signaled { }
|
||||
mod client {
|
||||
fn signal(-pipe: waiting) -> signaled {
|
||||
let (c, s) = pipes::entangle();
|
||||
let message = oneshot::signal(s);
|
||||
pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
type waiting = pipes::send_packet<oneshot::waiting>;
|
||||
type signaled = pipes::send_packet<oneshot::signaled>;
|
||||
}
|
||||
mod server {
|
||||
impl recv for waiting {
|
||||
fn recv() -> extern fn(-waiting) -> oneshot::waiting {
|
||||
fn recv(-pipe: waiting) -> oneshot::waiting {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type waiting = pipes::recv_packet<oneshot::waiting>;
|
||||
impl recv for signaled {
|
||||
fn recv() -> extern fn(-signaled) -> oneshot::signaled {
|
||||
fn recv(-pipe: signaled) -> oneshot::signaled {
|
||||
option::unwrap(pipes::recv(pipe))
|
||||
}
|
||||
recv
|
||||
}
|
||||
}
|
||||
type signaled = pipes::recv_packet<oneshot::signaled>;
|
||||
proto! oneshot {
|
||||
waiting:send {
|
||||
signal -> signaled
|
||||
}
|
||||
|
||||
signaled:send { }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
import oneshot::client::*;
|
||||
import oneshot::server::recv;
|
||||
|
||||
#macro[
|
||||
[#recv[chan],
|
||||
chan.recv()(chan)]
|
||||
];
|
||||
|
||||
let c = pipes::spawn_service(oneshot::init, |p| { #recv(p); });
|
||||
let c = pipes::spawn_service(oneshot::init, |p| { recv(p); });
|
||||
|
||||
let iotask = uv::global_loop::get();
|
||||
sleep(iotask, 5000);
|
||||
|
Loading…
x
Reference in New Issue
Block a user