Updating tests to use pipes.

This commit is contained in:
Eric Holk 2012-07-05 23:14:27 -07:00
parent fa4134611d
commit 7b03832c95
8 changed files with 76 additions and 492 deletions

@ -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);