From 7b03832c958826b27ea77df91f2d2ac276bb7411 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 5 Jul 2012 23:14:27 -0700 Subject: [PATCH] Updating tests to use pipes. --- src/libcore/future.rs | 9 ++ src/libsyntax/ext/pipes/parse_proto.rs | 70 ++++++---- ...ing-contracts.rs => msgsend-ring-pipes.rs} | 37 +---- src/test/run-pass/pipe-manual-1.rs | 110 --------------- src/test/run-pass/pipe-manual-2.rs | 93 ------------- src/test/run-pass/pipe-manual-3.rs | 129 ------------------ src/test/run-pass/pipe-select.rs | 70 ++-------- src/test/run-pass/pipe-sleep.rs | 50 ++----- 8 files changed, 76 insertions(+), 492 deletions(-) rename src/test/bench/{msgsend-ring-contracts.rs => msgsend-ring-pipes.rs} (75%) delete mode 100644 src/test/run-pass/pipe-manual-1.rs delete mode 100644 src/test/run-pass/pipe-manual-2.rs delete mode 100644 src/test/run-pass/pipe-manual-3.rs diff --git a/src/libcore/future.rs b/src/libcore/future.rs index 8bc46de26b29..bf3c30a573b8 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -138,6 +138,15 @@ fn with(future: future, blk: fn(A) -> B) -> B { } // The pipe protocol, generated by pipec +/* +proto! future_pipe { + waiting:recv { + completed(T) -> terminated + } + + terminated { } +} +*/ mod future_pipe { fn init() -> (client::waiting, server::waiting) { { let (s, c) = pipes::entangle(); (c, s) } diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index 919960f4c82e..abf19825fdd2 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -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); + + }); } } diff --git a/src/test/bench/msgsend-ring-contracts.rs b/src/test/bench/msgsend-ring-pipes.rs similarity index 75% rename from src/test/bench/msgsend-ring-contracts.rs rename to src/test/bench/msgsend-ring-pipes.rs index 9ad3025d33ae..2eb630d64274 100644 --- a/src/test/bench/msgsend-ring-contracts.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -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; - } - 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; +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)); diff --git a/src/test/run-pass/pipe-manual-1.rs b/src/test/run-pass/pipe-manual-1.rs deleted file mode 100644 index 7efedfe6418c..000000000000 --- a/src/test/run-pass/pipe-manual-1.rs +++ /dev/null @@ -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_ˊ)); - }; -} diff --git a/src/test/run-pass/pipe-manual-2.rs b/src/test/run-pass/pipe-manual-2.rs deleted file mode 100644 index 0803bbfe5317..000000000000 --- a/src/test/run-pass/pipe-manual-2.rs +++ /dev/null @@ -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; - enum pong = *pipes::packet; - - fn init() -> (client::ping, server::ping) { - pipes::entangle() - } - - mod client { - type ping = pipes::send_packet; - type pong = pipes::recv_packet; - - 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; - type pong = pipes::send_packet; - - 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_ˊ)); - }; -} diff --git a/src/test/run-pass/pipe-manual-3.rs b/src/test/run-pass/pipe-manual-3.rs deleted file mode 100644 index 9f05038aadc6..000000000000 --- a/src/test/run-pass/pipe-manual-3.rs +++ /dev/null @@ -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; - enum pong { pong, } - enum pong_message = *pipes::packet; - - fn init() -> (client::ping, server::ping) { - pipes::entangle() - } - - mod client { - type ping = pipes::send_packet; - type pong = pipes::recv_packet; - } - - 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; - type pong = pipes::send_packet; - } - - 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_ˊ)); - }; -} diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs index 163cfa954884..af01e568ffd4 100644 --- a/src/test/run-pass/pipe-select.rs +++ b/src/test/run-pass/pipe-select.rs @@ -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; - type signaled = pipes::send_packet; - } - 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; - 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; +proto! oneshot { + waiting:send { + signal -> signaled } + + signaled:send { } } -mod stream { - fn init() -> (client::stream, server::stream) { - pipes::entangle() - } - enum stream { send(T, server::stream), } - mod client { - fn send(+pipe: stream, +x_0: T) -> stream { - { - let (c, s) = pipes::entangle(); - let message = stream::send(x_0, s); - pipes::send(pipe, message); - c - } - } - type stream = pipes::send_packet>; - } - mod server { - impl recv for stream { - fn recv() -> extern fn(+stream) -> stream::stream { - fn recv(+pipe: stream) -> stream::stream { - option::unwrap(pipes::recv(pipe)) - } - recv - } - } - type stream = pipes::recv_packet>; +proto! stream { + stream:send { + send(T) -> stream } } diff --git a/src/test/run-pass/pipe-sleep.rs b/src/test/run-pass/pipe-sleep.rs index 932a4f9a4322..c4b44ff0be72 100644 --- a/src/test/run-pass/pipe-sleep.rs +++ b/src/test/run-pass/pipe-sleep.rs @@ -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; - type signaled = pipes::send_packet; - } - 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; - 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; +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);