diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ea87646e60b..90e1c7db91a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -81,8 +81,8 @@ pub enum SyntaxExtension { // An IdentTT is a macro that has an // identifier in between the name of the // macro and the argument. Currently, - // the only examples of this are - // macro_rules! and proto! + // the only examples of this is + // macro_rules! // perhaps macro_rules! will lose its odd special identifier argument, // and this can go away also @@ -197,8 +197,6 @@ pub fn syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(intern(&"module_path"), builtin_normal_tt( ext::source_util::expand_mod)); - syntax_expanders.insert(intern(&"proto"), - builtin_item_tt(ext::pipes::expand_proto)); syntax_expanders.insert(intern(&"asm"), builtin_normal_tt(ext::asm::expand_asm)); syntax_expanders.insert( diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs deleted file mode 100644 index eb8b01c427d..00000000000 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Functions for building ASTs, without having to fuss with spans. -// -// To start with, it will be use dummy spans, but it might someday do -// something smarter. - -use ast::ident; -use ast; -use codemap::span; - -use std::vec; - -// Transitional reexports so qquote can find the paths it is looking for -mod syntax { - pub use ext; - pub use parse; -} - -pub fn path(ids: ~[ident], span: span) -> ast::Path { - ast::Path { span: span, - global: false, - idents: ids, - rp: None, - types: ~[] } -} - -pub fn path_global(ids: ~[ident], span: span) -> ast::Path { - ast::Path { span: span, - global: true, - idents: ids, - rp: None, - types: ~[] } -} - -pub trait append_types { - fn add_ty(&self, ty: ast::Ty) -> ast::Path; - fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path; -} - -impl append_types for ast::Path { - fn add_ty(&self, ty: ast::Ty) -> ast::Path { - ast::Path { - types: vec::append_one(self.types.clone(), ty), - .. (*self).clone() - } - } - - fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path { - ast::Path { - types: vec::append(self.types.clone(), tys), - .. (*self).clone() - } - } -} diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs deleted file mode 100644 index adf10215cb5..00000000000 --- a/src/libsyntax/ext/pipes/check.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// Correctness for protocols - -/* - -This section of code makes sure the protocol is likely to generate -correct code. The correctness criteria include: - - * No protocols transition to states that don't exist. - * Messages step to states with the right number of type parameters. - -In addition, this serves as a lint pass. Lint warns for the following -things. - - * States with no messages, it's better to step to !. - -It would also be nice to warn about unreachable states, but the -visitor infrastructure for protocols doesn't currently work well for -that. - -*/ - -use ast; -use codemap::span; -use ext::base::ExtCtxt; -use ext::pipes::proto::{state, protocol, next_state}; -use ext::pipes::proto; - -impl proto::visitor<(), (), ()> for @ExtCtxt { - fn visit_proto(&self, _proto: protocol, _states: &[()]) { } - - fn visit_state(&self, state: state, _m: &[()]) { - let messages = &*state.messages; - if messages.len() == 0 { - self.span_warn( - state.span, // use a real span! - fmt!("state %s contains no messages, \ - consider stepping to a terminal state instead", - state.name)) - } - } - - fn visit_message(&self, name: @str, _span: span, _tys: &[ast::Ty], - this: state, next: Option) { - match next { - Some(ref next_state) => { - let proto = this.proto; - if !proto.has_state(next_state.state) { - // This should be a span fatal, but then we need to - // track span information. - self.span_err( - proto.get_state(next_state.state).span, - fmt!("message %s steps to undefined state, %s", - name, next_state.state)); - } - else { - let next = proto.get_state(next_state.state); - - if next.generics.ty_params.len() != next_state.tys.len() { - self.span_err( - next.span, // use a real span - fmt!("message %s target (%s) \ - needs %u type parameters, but got %u", - name, next.name, - next.generics.ty_params.len(), - next_state.tys.len())); - } - } - } - None => () - } - } -} diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs deleted file mode 100644 index b080a730f3e..00000000000 --- a/src/libsyntax/ext/pipes/liveness.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* - -Liveness analysis for protocols. This is useful for a lot of possible -optimizations. - -This analysis computes the "co-live" relationship between -states. Co-live is defined inductively as follows. - -1. u is co-live with v if u can transition to v in one message. - -2. u is co-live with v if there exists a w such that u and w are -co-live, w and v are co-live, and u and w have the same direction. - -This relationship approximates when it is safe to store two states in -the same memory location. If there is no u such u is co-live with -itself, then the protocol is bounded. - -(These assertions could use proofs) - -In addition, this analysis does reachability, to warn when we have -useless states. - -The algorithm is a fixpoint computation. For each state, we initialize -a bitvector containing whether it is co-live with each other state. At -first we use rule (1) above to set each vector. Then we iterate -updating the states using rule (2) until there are no changes. - -*/ - -use ext::base::ExtCtxt; -use ext::pipes::proto::{protocol_}; - -use extra::bitv::Bitv; - -pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) { - debug!("initializing colive analysis"); - let num_states = proto.num_states(); - let mut colive: ~[~Bitv] = do proto.states.iter().transform() |state| { - let mut bv = ~Bitv::new(num_states, false); - for state.reachable |s| { - bv.set(s.id, true); - } - bv - }.collect(); - - let mut i = 0; - let mut changed = true; - while changed { - changed = false; - debug!("colive iteration %?", i); - let mut new_colive = ~[]; - foreach (i, this_colive) in colive.iter().enumerate() { - let mut result = this_colive.clone(); - let this = proto.get_state_by_id(i); - for this_colive.ones |j| { - let next = proto.get_state_by_id(j); - if this.dir == next.dir { - changed = result.union(colive[j]) || changed; - } - } - new_colive.push(result) - } - colive = new_colive; - i += 1; - } - - debug!("colive analysis complete"); - - // Determine if we're bounded - let mut self_live = ~[]; - foreach (i, bv) in colive.iter().enumerate() { - if bv.get(i) { - self_live.push(proto.get_state_by_id(i)) - } - } - - if self_live.len() > 0 { - let states = self_live.map(|s| s.name).connect(" "); - - debug!("protocol %s is unbounded due to loops involving: %s", - proto.name, - states); - - // Someday this will be configurable with a warning - //cx.span_warn(empty_span(), - // fmt!("protocol %s is unbounded due to loops \ - // involving these states: %s", - // *proto.name, - // states)); - - proto.bounded = Some(false); - } else { - debug!("protocol %s is bounded. yay!", proto.name); - proto.bounded = Some(true); - } -} diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs deleted file mode 100644 index b8a0da8fe8f..00000000000 --- a/src/libsyntax/ext/pipes/mod.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! Implementation of proto! extension. - -This is frequently called the pipe compiler. It handles code such as... - -~~~ -proto! pingpong ( - ping: send { - ping -> pong - } - pong: recv { - pong -> ping - } -) -~~~ - -There are several components: - - * The parser (libsyntax/ext/pipes/parse_proto.rs) - * Responsible for building an AST from a protocol specification. - - * The checker (libsyntax/ext/pipes/check.rs) - * Basic correctness checking for protocols (i.e. no undefined states, etc.) - - * The analyzer (libsyntax/ext/pipes/liveness.rs) - * Determines whether the protocol is bounded or unbounded. - - * The compiler (libsynatx/ext/pipes/pipec.rs) - * Generates a Rust AST from the protocol AST and the results of analysis. - -There is more documentation in each of the files referenced above. - -FIXME (#3072) - This is still incomplete. - -*/ - -use ast; -use codemap::span; -use ext::base; -use ext::base::ExtCtxt; -use ext::pipes::parse_proto::proto_parser; -use ext::pipes::pipec::gen_init; -use ext::pipes::proto::visit; -use parse::lexer::{new_tt_reader, reader}; -use parse::parser::Parser; - -pub mod ast_builder; -pub mod parse_proto; -pub mod pipec; -pub mod proto; -pub mod check; -pub mod liveness; - - -pub fn expand_proto(cx: @ExtCtxt, _sp: span, id: ast::ident, - tt: ~[ast::token_tree]) -> base::MacResult { - let sess = cx.parse_sess(); - let cfg = cx.cfg(); - let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic, - None, - tt.clone()); - let rdr = tt_rdr as @reader; - let rust_parser = Parser(sess, cfg, rdr.dup()); - - let proto = rust_parser.parse_proto(cx.str_of(id)); - - // check for errors - visit(proto, cx); - - // do analysis - liveness::analyze(proto, cx); - - // compile - base::MRItem(proto.compile(cx)) -} diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs deleted file mode 100644 index e5219721594..00000000000 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Parsing pipes protocols from token trees. - -use ast_util; -use ext::pipes::proto::*; -use parse::common::SeqSep; -use parse::parser; -use parse::token; -use parse::token::{interner_get}; - -pub trait proto_parser { - fn parse_proto(&self, id: @str) -> protocol; - fn parse_state(&self, proto: protocol); - fn parse_message(&self, state: state); -} - -impl proto_parser for parser::Parser { - fn parse_proto(&self, id: @str) -> protocol { - let proto = protocol(id, *self.span); - - self.parse_seq_to_before_end( - &token::EOF, - SeqSep { - sep: None, - trailing_sep_allowed: false, - }, - |this| this.parse_state(proto) - ); - - return proto; - } - - fn parse_state(&self, proto: protocol) { - let id = self.parse_ident(); - let name = interner_get(id.name); - - self.expect(&token::COLON); - let dir = match (*self.token).clone() { - token::IDENT(n, _) => interner_get(n.name), - _ => fail!() - }; - self.bump(); - let dir = match dir.as_slice() { - "send" => send, - "recv" => recv, - _ => fail!() - }; - - let generics = if *self.token == token::LT { - self.parse_generics() - } else { - ast_util::empty_generics() - }; - - let state = proto.add_state_poly(name, id, dir, generics); - - // parse the messages - self.parse_unspanned_seq( - &token::LBRACE, - &token::RBRACE, - SeqSep { - sep: Some(token::COMMA), - trailing_sep_allowed: true, - }, - |this| this.parse_message(state) - ); - } - - fn parse_message(&self, state: state) { - let mname = interner_get(self.parse_ident().name); - - let args = if *self.token == token::LPAREN { - self.parse_unspanned_seq( - &token::LPAREN, - &token::RPAREN, - SeqSep { - sep: Some(token::COMMA), - trailing_sep_allowed: true, - }, - |p| p.parse_ty(false) - ) - } - else { ~[] }; - - self.expect(&token::RARROW); - - let next = match *self.token { - token::IDENT(_, _) => { - let name = interner_get(self.parse_ident().name); - let ntys = if *self.token == token::LT { - self.parse_unspanned_seq( - &token::LT, - &token::GT, - SeqSep { - sep: Some(token::COMMA), - trailing_sep_allowed: true, - }, - |p| p.parse_ty(false) - ) - } - else { ~[] }; - Some(next_state {state: name, tys: ntys}) - } - token::NOT => { - // -> ! - self.bump(); - None - } - _ => self.fatal("invalid next state") - }; - - state.add_message(mname, *self.span, args, next); - - } -} diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs deleted file mode 100644 index 02aef13a3a8..00000000000 --- a/src/libsyntax/ext/pipes/pipec.rs +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// A protocol compiler for Rust. - -use ast; -use codemap::{dummy_sp, spanned}; -use ext::base::ExtCtxt; -use ext::build::AstBuilder; -use ext::pipes::ast_builder::{append_types, path}; -use ext::pipes::ast_builder::{path_global}; -use ext::pipes::proto::*; -use ext::quote::rt::*; -use opt_vec; -use opt_vec::OptVec; - -use std::vec; - -pub trait gen_send { - fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item; - fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty; -} - -pub trait to_type_decls { - fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item]; - fn to_endpoint_decls(&self, cx: @ExtCtxt, - dir: direction) -> ~[@ast::item]; -} - -pub trait gen_init { - fn gen_init(&self, cx: @ExtCtxt) -> @ast::item; - fn compile(&self, cx: @ExtCtxt) -> @ast::item; - fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty; - fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item; - fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr; - fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr; -} - -impl gen_send for message { - fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item { - debug!("pipec: gen_send"); - let name = self.name(); - - match *self { - message(ref _id, span, ref tys, this, Some(ref next_state)) => { - debug!("pipec: next state exists"); - let next = this.proto.get_state(next_state.state); - assert!(next_state.tys.len() == - next.generics.ty_params.len()); - let arg_names = vec::from_fn(tys.len(), |i| cx.ident_of("x_"+i.to_str())); - let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| - cx.arg(span, (*n).clone(), (*t).clone())).collect(); - - let pipe_ty = cx.ty_path( - path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params)), None); - let args_ast = vec::append( - ~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)], - args_ast); - - let mut body = ~"{\n"; - body.push_str(fmt!("use super::%s;\n", name)); - body.push_str("let mut pipe = pipe;\n"); - - if this.proto.is_bounded() { - let (sp, rp) = match (this.dir, next.dir) { - (send, send) => (~"c", ~"s"), - (send, recv) => (~"s", ~"c"), - (recv, send) => (~"s", ~"c"), - (recv, recv) => (~"c", ~"s") - }; - - body.push_str("let mut b = pipe.reuse_buffer();\n"); - body.push_str(fmt!("let %s = ::std::pipes::SendPacketBuffered(\ - &mut (b.buffer.data.%s));\n", - sp, - next.name)); - body.push_str(fmt!("let %s = ::std::pipes::RecvPacketBuffered(\ - &mut (b.buffer.data.%s));\n", - rp, - next.name)); - } - else { - let pat = match (this.dir, next.dir) { - (send, send) => "(s, c)", - (send, recv) => "(c, s)", - (recv, send) => "(c, s)", - (recv, recv) => "(s, c)" - }; - - body.push_str(fmt!("let %s = ::std::pipes::entangle();\n", pat)); - } - body.push_str(fmt!("let message = %s(%s);\n", - name, - vec::append_one(arg_names.map(|x| cx.str_of(*x)), @"s") - .connect(", "))); - - if !try { - body.push_str(fmt!("::std::pipes::send(pipe, message);\n")); - // return the new channel - body.push_str("c }"); - } - else { - body.push_str(fmt!("if ::std::pipes::send(pipe, message) {\n \ - ::std::pipes::rt::make_some(c) \ - } else { ::std::pipes::rt::make_none() } }")); - } - - let body = cx.parse_expr(body.to_managed()); - - let mut rty = cx.ty_path(path(~[next.data_name()], - span) - .add_tys(next_state.tys.clone()), None); - if try { - rty = cx.ty_option(rty); - } - - let name = if try {cx.ident_of(~"try_" + name)} else {cx.ident_of(name)}; - - cx.item_fn_poly(dummy_sp(), - name, - args_ast, - rty, - self.get_generics(), - cx.blk_expr(body)) - } - - message(ref _id, span, ref tys, this, None) => { - debug!("pipec: no next state"); - let arg_names = vec::from_fn(tys.len(), |i| "x_" + i.to_str()); - - let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) - .transform(|(n, t)| - cx.arg(span, cx.ident_of(*n), (*t).clone())).collect(); - - let args_ast = vec::append( - ~[cx.arg(span, - cx.ident_of("pipe"), - cx.ty_path( - path(~[this.data_name()], span) - .add_tys(cx.ty_vars( - &this.generics.ty_params)), None))], - args_ast); - - let message_args = if arg_names.len() == 0 { - ~"" - } - else { - ~"(" + arg_names.map(|x| (*x).clone()).connect(", ") + ")" - }; - - let mut body = ~"{ "; - body.push_str(fmt!("use super::%s;\n", name)); - body.push_str(fmt!("let message = %s%s;\n", name, message_args)); - - if !try { - body.push_str(fmt!("::std::pipes::send(pipe, message);\n")); - body.push_str(" }"); - } else { - body.push_str(fmt!("if ::std::pipes::send(pipe, message) \ - { \ - ::std::pipes::rt::make_some(()) \ - } else { \ - ::std::pipes::rt::make_none() \ - } }")); - } - - let body = cx.parse_expr(body.to_managed()); - - let name = if try {cx.ident_of(~"try_" + name)} else {cx.ident_of(name)}; - - cx.item_fn_poly(dummy_sp(), - name, - args_ast, - if try { - cx.ty_option(cx.ty_nil()) - } else { - cx.ty_nil() - }, - self.get_generics(), - cx.blk_expr(body)) - } - } - } - - fn to_ty(&mut self, cx: @ExtCtxt) -> ast::Ty { - cx.ty_path(path(~[cx.ident_of(self.name())], self.span()) - .add_tys(cx.ty_vars(&self.get_generics().ty_params)), None) - } -} - -impl to_type_decls for state { - fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item] { - debug!("pipec: to_type_decls"); - // This compiles into two different type declarations. Say the - // state is called ping. This will generate both `ping` and - // `ping_message`. The first contains data that the user cares - // about. The second is the same thing, but extended with a - // next packet pointer, which is used under the covers. - - let name = self.data_name(); - - let mut items_msg = ~[]; - - foreach m in self.messages.iter() { - let message(name, span, tys, this, next) = (*m).clone(); - - let tys = match next { - Some(ref next_state) => { - let next = this.proto.get_state((next_state.state)); - let next_name = cx.str_of(next.data_name()); - - let dir = match this.dir { - send => "server", - recv => "client" - }; - - vec::append_one(tys, - cx.ty_path( - path(~[cx.ident_of(dir), - cx.ident_of(next_name)], span) - .add_tys(next_state.tys.clone()), None)) - } - None => tys - }; - - let v = cx.variant(span, cx.ident_of(name), tys); - - items_msg.push(v); - } - - ~[ - cx.item_enum_poly( - self.span, - name, - ast::enum_def { variants: items_msg }, - cx.strip_bounds(&self.generics) - ) - ] - } - - fn to_endpoint_decls(&self, cx: @ExtCtxt, - dir: direction) -> ~[@ast::item] { - debug!("pipec: to_endpoint_decls"); - let dir = match dir { - send => (*self).dir, - recv => (*self).dir.reverse() - }; - let mut items = ~[]; - - { - foreach m in self.messages.mut_iter() { - if dir == send { - items.push(m.gen_send(cx, true)); - items.push(m.gen_send(cx, false)); - } - } - } - - if !self.proto.is_bounded() { - items.push( - cx.item_ty_poly( - self.span, - self.data_name(), - cx.ty_path( - path_global(~[cx.ident_of("std"), - cx.ident_of("pipes"), - cx.ident_of(dir.to_str() + "Packet")], - dummy_sp()) - .add_ty(cx.ty_path( - path(~[cx.ident_of("super"), - self.data_name()], - dummy_sp()) - .add_tys(cx.ty_vars( - &self.generics.ty_params)), None)), None), - cx.strip_bounds(&self.generics))); - } - else { - items.push( - cx.item_ty_poly( - self.span, - self.data_name(), - cx.ty_path( - path_global(~[cx.ident_of("std"), - cx.ident_of("pipes"), - cx.ident_of(dir.to_str() - + "PacketBuffered")], - dummy_sp()) - .add_tys(~[cx.ty_path( - path(~[cx.ident_of("super"), - self.data_name()], - dummy_sp()) - .add_tys(cx.ty_vars_global( - &self.generics.ty_params)), None), - self.proto.buffer_ty_path(cx)]), None), - cx.strip_bounds(&self.generics))); - }; - items - } -} - -impl gen_init for protocol { - fn gen_init(&self, cx: @ExtCtxt) -> @ast::item { - let ext_cx = cx; - - debug!("gen_init"); - let start_state = self.states[0]; - - let body = if !self.is_bounded() { - quote_expr!( ::std::pipes::entangle() ) - } - else { - self.gen_init_bounded(ext_cx) - }; - - cx.parse_item(fmt!("pub fn init%s() -> (server::%s, client::%s)\ - { pub use std::pipes::HasBuffer; %s }", - start_state.generics.to_source(), - start_state.to_ty(cx).to_source(), - start_state.to_ty(cx).to_source(), - body.to_source()).to_managed()) - } - - fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr { - ext_cx.expr_struct( - dummy_sp(), - path(~[ext_cx.ident_of("__Buffer")], - dummy_sp()), - self.states.iter().transform(|s| { - let fty = s.to_ty(ext_cx); - ext_cx.field_imm(dummy_sp(), - ext_cx.ident_of(s.name), - quote_expr!( - ::std::pipes::mk_packet::<$fty>() - )) - }).collect()) - } - - fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr { - debug!("gen_init_bounded"); - let buffer_fields = self.gen_buffer_init(ext_cx); - let buffer = quote_expr!(~::std::pipes::Buffer { - header: ::std::pipes::BufferHeader(), - data: $buffer_fields, - }); - - let entangle_body = ext_cx.expr_blk( - ext_cx.blk( - dummy_sp(), - self.states.iter().transform( - |s| ext_cx.parse_stmt( - fmt!("data.%s.set_buffer(buffer)", - s.name).to_managed())).collect(), - Some(ext_cx.parse_expr(fmt!( - "::std::ptr::to_mut_unsafe_ptr(&mut (data.%s))", - self.states[0].name).to_managed())))); - - quote_expr!({ - let buffer = $buffer; - do ::std::pipes::entangle_buffer(buffer) |buffer, data| { - $entangle_body - } - }) - } - - fn buffer_ty_path(&self, cx: @ExtCtxt) -> ast::Ty { - let mut params: OptVec = opt_vec::Empty; - foreach s in self.states.iter() { - foreach tp in s.generics.ty_params.iter() { - match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push((*tp).clone()), - _ => () - } - } - } - - cx.ty_path(path(~[cx.ident_of("super"), - cx.ident_of("__Buffer")], - self.span) - .add_tys(cx.ty_vars_global(¶ms)), None) - } - - fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { - let ext_cx = cx; - let mut params: OptVec = opt_vec::Empty; - let fields = do self.states.iter().transform |s| { - foreach tp in s.generics.ty_params.iter() { - match params.iter().find_(|tpp| tp.ident == tpp.ident) { - None => params.push((*tp).clone()), - _ => () - } - } - - let ty = s.to_ty(cx); - let fty = quote_ty!( ::std::pipes::Packet<$ty> ); - - @spanned { - node: ast::struct_field_ { - kind: ast::named_field(cx.ident_of(s.name), - ast::inherited), - id: cx.next_id(), - ty: fty, - attrs: ~[], - }, - span: dummy_sp() - } - }.collect(); - - let generics = Generics { - lifetimes: opt_vec::Empty, - ty_params: params - }; - - cx.item_struct_poly( - dummy_sp(), - cx.ident_of("__Buffer"), - ast::struct_def { - fields: fields, - ctor_id: None - }, - cx.strip_bounds(&generics)) - } - - fn compile(&self, cx: @ExtCtxt) -> @ast::item { - let mut items = ~[self.gen_init(cx)]; - let mut client_states = ~[]; - let mut server_states = ~[]; - - foreach s in self.states.iter() { - items.push_all_move(s.to_type_decls(cx)); - - client_states.push_all_move(s.to_endpoint_decls(cx, send)); - server_states.push_all_move(s.to_endpoint_decls(cx, recv)); - } - - if self.is_bounded() { - items.push(self.gen_buffer_type(cx)) - } - - items.push(cx.item_mod(self.span, - cx.ident_of("client"), - ~[], ~[], - client_states)); - items.push(cx.item_mod(self.span, - cx.ident_of("server"), - ~[], ~[], - server_states)); - - // XXX: Would be nice if our generated code didn't violate - // Rust coding conventions - let allows = cx.attribute( - self.span, - cx.meta_list(self.span, - @"allow", - ~[cx.meta_word(self.span, @"non_camel_case_types"), - cx.meta_word(self.span, @"unused_mut")])); - cx.item_mod(self.span, cx.ident_of(self.name), ~[allows], ~[], items) - } -} diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs deleted file mode 100644 index 5d2ebb68b8a..00000000000 --- a/src/libsyntax/ext/pipes/proto.rs +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast; -use codemap::span; -use ext::base::ExtCtxt; -use ext::build::AstBuilder; -use ext::pipes::ast_builder::{append_types, path}; - -#[deriving(Eq)] -pub enum direction { send, recv } - -impl ToStr for direction { - fn to_str(&self) -> ~str { - match *self { - send => ~"Send", - recv => ~"Recv" - } - } -} - -impl direction { - pub fn reverse(&self) -> direction { - match *self { - send => recv, - recv => send - } - } -} - -#[deriving(Clone)] -pub struct next_state { - state: @str, - tys: ~[ast::Ty], -} - -// name, span, data, current state, next state -#[deriving(Clone)] -pub struct message(@str, span, ~[ast::Ty], state, Option); - -impl message { - pub fn name(&mut self) -> @str { - match *self { - message(id, _, _, _, _) => id - } - } - - pub fn span(&mut self) -> span { - match *self { - message(_, span, _, _, _) => span - } - } - - /// Return the type parameters actually used by this message - pub fn get_generics(&self) -> ast::Generics { - match *self { - message(_, _, _, this, _) => this.generics.clone() - } - } -} - -pub type state = @state_; - -pub struct state_ { - id: uint, - name: @str, - ident: ast::ident, - span: span, - dir: direction, - generics: ast::Generics, - messages: @mut ~[message], - proto: protocol -} - -impl state_ { - pub fn add_message(@self, - name: @str, - span: span, - data: ~[ast::Ty], - next: Option) { - self.messages.push(message(name, span, data, self, - next)); - } - - pub fn filename(&self) -> ~str { - self.proto.filename() - } - - pub fn data_name(&self) -> ast::ident { - self.ident - } - - /// Returns the type that is used for the messages. - pub fn to_ty(&self, cx: @ExtCtxt) -> ast::Ty { - cx.ty_path - (path(~[cx.ident_of(self.name)],self.span).add_tys( - cx.ty_vars(&self.generics.ty_params)), None) - } - - /// Iterate over the states that can be reached in one message - /// from this state. - pub fn reachable(&self, f: &fn(state) -> bool) -> bool { - foreach m in self.messages.iter() { - match *m { - message(_, _, _, _, Some(next_state { state: ref id, _ })) => { - let state = self.proto.get_state((*id)); - if !f(state) { return false; } - } - _ => () - } - } - return true; - } -} - -pub type protocol = @mut protocol_; - -pub fn protocol(name: @str, span: span) -> protocol { - @mut protocol_(name, span) -} - -pub fn protocol_(name: @str, span: span) -> protocol_ { - protocol_ { - name: name, - span: span, - states: @mut ~[], - bounded: None - } -} - -pub struct protocol_ { - name: @str, - span: span, - states: @mut ~[state], - - bounded: Option, -} - -impl protocol_ { - /// Get a state. - pub fn get_state(&self, name: &str) -> state { - let mut i = self.states.iter(); - *i.find_(|i| name == i.name).get() - } - - pub fn get_state_by_id(&self, id: uint) -> state { self.states[id] } - - pub fn has_state(&self, name: &str) -> bool { - self.states.iter().find_(|i| name == i.name).is_some() - } - - pub fn filename(&self) -> ~str { - ~"proto://" + self.name - } - - pub fn num_states(&self) -> uint { - let states = &mut *self.states; - states.len() - } - - pub fn has_ty_params(&self) -> bool { - foreach s in self.states.iter() { - if s.generics.ty_params.len() > 0 { - return true; - } - } - false - } - - pub fn is_bounded(&self) -> bool { - let bounded = self.bounded.get(); - bounded - } -} - -impl protocol_ { - pub fn add_state_poly(@mut self, - name: @str, - ident: ast::ident, - dir: direction, - generics: ast::Generics) - -> state { - let messages = @mut ~[]; - let states = &mut *self.states; - - let state = @state_ { - id: states.len(), - name: name, - ident: ident, - span: self.span, - dir: dir, - generics: generics, - messages: messages, - proto: self - }; - - states.push(state); - state - } -} - -pub trait visitor { - fn visit_proto(&self, proto: protocol, st: &[Tstate]) -> Tproto; - fn visit_state(&self, state: state, m: &[Tmessage]) -> Tstate; - fn visit_message(&self, name: @str, spane: span, tys: &[ast::Ty], - this: state, next: Option) -> Tmessage; -} - -pub fn visit>( - proto: protocol, visitor: V) -> Tproto { - - let states: ~[Tstate] = do proto.states.iter().transform |&s| { - let messages: ~[Tmessage] = do s.messages.iter().transform |m| { - let message(name, span, tys, this, next) = (*m).clone(); - visitor.visit_message(name, span, tys, this, next) - }.collect(); - visitor.visit_state(s, messages) - }.collect(); - visitor.visit_proto(proto, states) -} diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index bcfd898dc6f..4e7b0612e64 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -683,7 +683,7 @@ fn expand_tts(cx: @ExtCtxt, // the site the string literal occurred, which was in a source file // _other_ than the one the user has control over. For example, an // error in a quote from the protocol compiler, invoked in user code - // using proto! for example, will be attributed to the pipec.rs file in + // using macro_rules! for example, will be attributed to the macro_rules.rs file in // libsyntax, which the user might not even have source to (unless they // happen to have a compiler on hand). Over all, the phase distinction // just makes quotes "hard to attribute". Possibly this could be fixed diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index ae2aa6ae738..f39351bf91f 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -78,7 +78,5 @@ pub mod ext { pub mod auto_encode; pub mod source_util; - pub mod pipes; - pub mod trace_macros; } diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs deleted file mode 100644 index 27cd34c5199..00000000000 --- a/src/test/bench/msgsend-ring-pipes.rs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This test creates a bunch of tasks that simultaneously send to each -// other in a ring. The messages should all be basically -// independent. It's designed to hammer the global kernel lock, so -// that things will look really good once we get that lock out of the -// message path. - -// This version uses automatically compiled channel contracts. - -extern mod extra; - -use extra::future; -use extra::time; -use std::cell::Cell; -use std::io; -use std::os; -use std::pipes::recv; -use std::uint; -use std::util; - -proto! ring ( - num:send { - num(uint) -> num - } -) - -fn thread_ring(i: uint, - count: uint, - num_chan: ring::client::num, - num_port: ring::server::num) { - let mut num_chan = Some(num_chan); - let mut num_port = Some(num_port); - // Send/Receive lots of messages. - for uint::range(0, count) |j| { - //error!("task %?, iter %?", i, j); - let num_chan2 = util::replace(&mut num_chan, None); - let num_port2 = util::replace(&mut num_port, None); - num_chan = Some(ring::client::num(num_chan2.unwrap(), i * j)); - let port = num_port2.unwrap(); - match recv(port) { - ring::num(_n, p) => { - //log(error, _n); - num_port = Some(p); - } - } - }; -} - -fn main() { - let args = os::args(); - let args = if os::getenv("RUST_BENCH").is_some() { - ~[~"", ~"100", ~"10000"] - } else if args.len() <= 1u { - ~[~"", ~"100", ~"1000"] - } else { - args.clone() - }; - - let num_tasks = uint::from_str(args[1]).get(); - let msg_per_task = uint::from_str(args[2]).get(); - - let (num_port, num_chan) = ring::init(); - let num_chan = Cell::new(num_chan); - - let start = time::precise_time_s(); - - // create the ring - let mut futures = ~[]; - - for uint::range(1u, num_tasks) |i| { - //error!("spawning %?", i); - let (num_port, new_chan) = ring::init(); - let num_chan2 = Cell::new(num_chan.take()); - let num_port = Cell::new(num_port); - let new_future = do future::spawn || { - let num_chan = num_chan2.take(); - let num_port1 = num_port.take(); - thread_ring(i, msg_per_task, num_chan, num_port1) - }; - futures.push(new_future); - num_chan.put_back(new_chan); - }; - - // do our iteration - thread_ring(0, msg_per_task, num_chan.take(), num_port); - - // synchronize - foreach f in futures.mut_iter() { - let _ = f.get(); - } - - let stop = time::precise_time_s(); - - // all done, report stats. - let num_msgs = num_tasks * msg_per_task; - let elapsed = (stop - start); - let rate = (num_msgs as float) / elapsed; - - printfln!("Sent %? messages in %? seconds", num_msgs, elapsed); - printfln!(" %? messages / second", rate); - printfln!(" %? μs / message", 1000000. / rate); -} diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs deleted file mode 100644 index b11daeef12f..00000000000 --- a/src/test/bench/pingpong.rs +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Compare bounded and unbounded protocol performance. - -// xfail-pretty - -extern mod extra; - -use extra::time::precise_time_s; -use std::cell::Cell; -use std::io; -use std::os; -use std::pipes::*; -use std::task; - -proto! pingpong ( - ping: send { - ping -> pong - } - - pong: recv { - pong -> ping - } -) - -proto! pingpong_unbounded ( - ping: send { - ping -> pong - } - - pong: recv { - pong -> ping - } - - you_will_never_catch_me: send { - never_ever_ever -> you_will_never_catch_me - } -) - -// This stuff should go in libcore::pipes -macro_rules! move_it ( - { $x:expr } => { let t = *ptr::to_unsafe_ptr(&($x)); t } -) - -macro_rules! follow ( - { - $($message:path($($x: ident),+) -> $next:ident $e:expr)+ - } => ( - |m| match m { - $(Some($message($($x,)* next)) => { - let $next = next; - $e })+ - _ => { fail!() } - } - ); - - { - $($message:path -> $next:ident $e:expr)+ - } => ( - |m| match m { - $(Some($message(next)) => { - let $next = next; - $e })+ - _ => { fail!() } - } - ) -) - - -/** Spawn a task to provide a service. - -It takes an initialization function that produces a send and receive -endpoint. The send endpoint is returned to the caller and the receive -endpoint is passed to the new task. - -*/ -pub fn spawn_service( - init: extern fn() -> (RecvPacketBuffered, - SendPacketBuffered), - service: ~fn(v: RecvPacketBuffered)) - -> SendPacketBuffered { - let (server, client) = init(); - - // This is some nasty gymnastics required to safely move the pipe - // into a new task. - let server = Cell::new(server); - do task::spawn { - service(server.take()); - } - - client -} - -/** Like `spawn_service_recv`, but for protocols that start in the -receive state. - -*/ -pub fn spawn_service_recv( - init: extern fn() -> (SendPacketBuffered, - RecvPacketBuffered), - service: ~fn(v: SendPacketBuffered)) - -> RecvPacketBuffered { - let (server, client) = init(); - - // This is some nasty gymnastics required to safely move the pipe - // into a new task. - let server = Cell::new(server); - do task::spawn { - service(server.take()) - } - - client -} - -fn switch(endp: std::pipes::RecvPacketBuffered, - f: &fn(v: Option) -> U) - -> U { - f(std::pipes::try_recv(endp)) -} - -// Here's the benchmark - -fn bounded(count: uint) { - use pingpong::*; - - let mut ch = do spawn_service(init) |ch| { - let mut count = count; - let mut ch = ch; - while count > 0 { - ch = switch(ch, follow! ( - ping -> next { server::pong(next) } - )); - - count -= 1; - } - }; - - let mut count = count; - while count > 0 { - let ch_ = client::ping(ch); - - ch = switch(ch_, follow! ( - pong -> next { next } - )); - - count -= 1; - } -} - -fn unbounded(count: uint) { - use pingpong_unbounded::*; - - let mut ch = do spawn_service(init) |ch| { - let mut count = count; - let mut ch = ch; - while count > 0 { - ch = switch(ch, follow! ( - ping -> next { server::pong(next) } - )); - - count -= 1; - } - }; - - let mut count = count; - while count > 0 { - let ch_ = client::ping(ch); - - ch = switch(ch_, follow! ( - pong -> next { next } - )); - - count -= 1; - } -} - -fn timeit(f: &fn()) -> float { - let start = precise_time_s(); - f(); - let stop = precise_time_s(); - stop - start -} - -fn main() { - let count = if os::getenv("RUST_BENCH").is_some() { - 250000 - } else { - 100 - }; - let bounded = do timeit { bounded(count) }; - let unbounded = do timeit { unbounded(count) }; - - printfln!("count: %?\n", count); - printfln!("bounded: %? s\t(%? μs/message)", - bounded, bounded * 1000000. / (count as float)); - printfln!("unbounded: %? s\t(%? μs/message)", - unbounded, unbounded * 1000000. / (count as float)); - - printfln!("\n\ - bounded is %?%% faster", - (unbounded - bounded) / bounded * 100.); -} diff --git a/src/test/run-pass/issue-2834.rs b/src/test/run-pass/issue-2834.rs deleted file mode 100644 index b0ddccf2894..00000000000 --- a/src/test/run-pass/issue-2834.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test case for issue #2843. -// - -proto! streamp ( - open:send { - data(T) -> open - } -) - -fn rendezvous() { - let (s, c) = streamp::init(); - let streams: ~[streamp::client::open] = ~[c]; - - error!("%?", streams[0]); -} - -pub fn main() { - //os::getenv("FOO"); - rendezvous(); -} diff --git a/src/test/run-pass/issue-2930.rs b/src/test/run-pass/issue-2930.rs deleted file mode 100644 index 10a19d62bd9..00000000000 --- a/src/test/run-pass/issue-2930.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -proto! stream ( - Stream:send { - send(T) -> Stream - } -) - -pub fn main() { - let (_bp, bc) = stream::init(); - - stream::client::send(bc, ~"abc"); -} diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs deleted file mode 100644 index 11c43b93901..00000000000 --- a/src/test/run-pass/pipe-bank-proto.rs +++ /dev/null @@ -1,115 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// An example of the bank protocol from eholk's blog post. -// -// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/ - -use std::pipes; -use std::pipes::try_recv; -use std::ptr; - -pub type username = ~str; -pub type password = ~str; -pub type money = float; -pub type amount = float; - -proto! bank ( - login:send { - login(::username, ::password) -> login_response - } - - login_response:recv { - ok -> connected, - invalid -> login - } - - connected:send { - deposit(::money) -> connected, - withdrawal(::amount) -> withdrawal_response - } - - withdrawal_response:recv { - money(::money) -> connected, - insufficient_funds -> connected - } -) - -fn switch(endp: pipes::RecvPacket, - f: &fn(v: Option) -> U) -> U { - f(pipes::try_recv(endp)) -} - -macro_rules! follow ( - { - $($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+ - } => ( - |m| match m { - $(Some($message($($($x,)+)* next)) => { - let $next = next; - $e })+ - _ => { fail!() } - } - ); -) - -fn client_follow(bank: bank::client::login) { - use bank::*; - - let bank = client::login(bank, ~"theincredibleholk", ~"1234"); - let bank = switch(bank, follow! ( - ok -> connected { connected } - invalid -> _next { fail!("bank closed the connected") } - )); - - let bank = client::deposit(bank, 100.00); - let bank = client::withdrawal(bank, 50.00); - switch(bank, follow! ( - money(m) -> _next { - println(~"Yay! I got money!"); - } - insufficient_funds -> _next { - fail!("someone stole my money") - } - )); -} - -fn bank_client(bank: bank::client::login) { - use bank::*; - - let bank = client::login(bank, ~"theincredibleholk", ~"1234"); - let bank = match try_recv(bank) { - Some(ok(connected)) => { - connected - } - Some(invalid(_)) => { fail!("login unsuccessful") } - None => { fail!("bank closed the connection") } - }; - - let bank = client::deposit(bank, 100.00); - let bank = client::withdrawal(bank, 50.00); - match try_recv(bank) { - Some(money(*)) => { - println(~"Yay! I got money!"); - } - Some(insufficient_funds(_)) => { - fail!("someone stole my money") - } - None => { - fail!("bank closed the connection") - } - } -} - -pub fn main() { -} diff --git a/src/test/run-pass/pipe-detect-term.rs b/src/test/run-pass/pipe-detect-term.rs deleted file mode 100644 index 42cd4081eda..00000000000 --- a/src/test/run-pass/pipe-detect-term.rs +++ /dev/null @@ -1,60 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Make sure that we can detect when one end of the pipe is closed. - -// xfail-win32 -// xfail-test needs sleep - -extern mod extra; -use extra::timer::sleep; -use extra::uv; - -use std::cell::Cell; -use std::pipes::{try_recv, recv}; -use std::task; - -proto! oneshot ( - waiting:send { - signal -> ! - } -) - -pub fn main() { - let iotask = &uv::global_loop::get(); - - let (port, chan) = oneshot::init(); - let port = Cell::new(port); - do spawn { - match try_recv(port.take()) { - Some(*) => { fail!() } - None => { } - } - } - - sleep(iotask, 100); - - task::spawn_unlinked(failtest); -} - -// Make sure the right thing happens during failure. -fn failtest() { - let (p, c) = oneshot::init(); - - do task::spawn_with(c) |_c| { - fail!(); - } - - error!("%?", recv(p)); - // make sure we get killed if we missed it in the receive. - loop { task::yield() } -} diff --git a/src/test/run-pass/pipe-peek.rs b/src/test/run-pass/pipe-peek.rs deleted file mode 100644 index a61aad2e55c..00000000000 --- a/src/test/run-pass/pipe-peek.rs +++ /dev/null @@ -1,31 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::pipes; - -proto! oneshot ( - waiting:send { - signal -> ! - } -) - -pub fn main() { - let (p, c) = oneshot::init(); - let mut p = p; - let mut c = c; - - assert!(!pipes::peek(&mut p)); - - oneshot::client::signal(c); - - assert!(pipes::peek(&mut p)); -} diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs deleted file mode 100644 index ab17607c4d7..00000000000 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ /dev/null @@ -1,126 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Ping-pong is a bounded protocol. This is place where I can -// experiment with what code the compiler should generate for bounded -// protocols. - -use std::cell::Cell; -use std::task; - -// This was generated initially by the pipe compiler, but it's been -// modified in hopefully straightforward ways. - -mod pingpong { - use std::pipes; - use std::pipes::*; - use std::ptr; - - pub struct Packets { - ping: Packet, - pong: Packet, - } - - pub fn init() -> (server::ping, client::ping) { - let buffer = ~Buffer { - header: BufferHeader(), - data: Packets { - ping: mk_packet::(), - pong: mk_packet::() - } - }; - do pipes::entangle_buffer(buffer) |buffer, data| { - data.ping.set_buffer(buffer); - data.pong.set_buffer(buffer); - ptr::to_mut_unsafe_ptr(&mut (data.ping)) - } - } - pub struct ping(server::pong); - pub struct pong(client::ping); - pub mod client { - use std::pipes; - use std::pipes::*; - use std::ptr; - - pub fn ping(mut pipe: ping) -> pong { - { - let mut b = pipe.reuse_buffer(); - let s = SendPacketBuffered(&mut b.buffer.data.pong); - let c = RecvPacketBuffered(&mut b.buffer.data.pong); - let message = ::pingpong::ping(s); - send(pipe, message); - c - } - } - pub type ping = pipes::SendPacketBuffered<::pingpong::ping, - ::pingpong::Packets>; - pub type pong = pipes::RecvPacketBuffered<::pingpong::pong, - ::pingpong::Packets>; - } - pub mod server { - use std::pipes; - use std::pipes::*; - use std::ptr; - - pub type ping = pipes::RecvPacketBuffered<::pingpong::ping, - ::pingpong::Packets>; - pub fn pong(mut pipe: pong) -> ping { - { - let mut b = pipe.reuse_buffer(); - let s = SendPacketBuffered(&mut b.buffer.data.ping); - let c = RecvPacketBuffered(&mut b.buffer.data.ping); - let message = ::pingpong::pong(s); - send(pipe, message); - c - } - } - pub type pong = pipes::SendPacketBuffered<::pingpong::pong, - ::pingpong::Packets>; - } -} - -mod test { - use std::pipes::recv; - use pingpong::{ping, pong}; - - pub fn client(chan: ::pingpong::client::ping) { - use pingpong::client; - - let chan = client::ping(chan); return; - error!("Sent ping"); - let pong(_chan) = recv(chan); - error!("Received pong"); - } - - pub fn server(chan: ::pingpong::server::ping) { - use pingpong::server; - - let ping(chan) = recv(chan); return; - error!("Received ping"); - let _chan = server::pong(chan); - error!("Sent pong"); - } -} - -pub fn main() { - let (server_, client_) = ::pingpong::init(); - let client_ = Cell::new(client_); - let server_ = Cell::new(server_); - do task::spawn { - let client__ = client_.take(); - test::client(client__); - }; - do task::spawn { - let server__ = server_.take(); - test::server(server__); - }; -} diff --git a/src/test/run-pass/pipe-pingpong-proto.rs b/src/test/run-pass/pipe-pingpong-proto.rs deleted file mode 100644 index a4268f9456b..00000000000 --- a/src/test/run-pass/pipe-pingpong-proto.rs +++ /dev/null @@ -1,65 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// An example to make sure the protocol parsing syntax extension works. - -use std::cell::Cell; -use std::option; -use std::task; - -proto! pingpong ( - ping:send { - ping -> pong - } - - pong:recv { - pong -> ping - } -) - -mod test { - use std::pipes::recv; - use pingpong::{ping, pong}; - - pub fn client(chan: ::pingpong::client::ping) { - use pingpong::client; - - let chan = client::ping(chan); - error!(~"Sent ping"); - let pong(_chan) = recv(chan); - error!(~"Received pong"); - } - - pub fn server(chan: ::pingpong::server::ping) { - use pingpong::server; - - let ping(chan) = recv(chan); - error!(~"Received ping"); - let _chan = server::pong(chan); - error!(~"Sent pong"); - } -} - -pub fn main() { - let (server_, client_) = pingpong::init(); - let client_ = Cell::new(client_); - let server_ = Cell::new(server_); - - do task::spawn { - let client__ = client_.take(); - test::client(client__); - }; - do task::spawn { - let server__ = server_.take(); - test::server(server__); - }; -} diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs deleted file mode 100644 index 65e0537dfb7..00000000000 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ /dev/null @@ -1,179 +0,0 @@ -// xfail-fast -// xfail-test - -// XFAIL'd because this is going to be revamped, and it's not compatible as -// written with the new mutability rules. - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Examples from Eric's internship final presentation. -// -// Code is easier to write in emacs, and it's good to be sure all the -// code samples compile (or not) as they should. - -use double_buffer::client::*; -use double_buffer::give_buffer; -use std::comm::Selectable; - -macro_rules! select_if ( - { - $index:expr, - $count:expr, - $port:path => [ - $($message:path$(($($x: ident),+))dont_type_this* - -> $next:ident $e:expr),+ - ], - $( $ports:path => [ - $($messages:path$(($($xs: ident),+))dont_type_this* - -> $nexts:ident $es:expr),+ - ], )* - } => { - if $index == $count { - match std::pipes::try_recv($port) { - $(Some($message($($($x,)+)* next)) => { - let $next = next; - $e - })+ - _ => fail!() - } - } else { - select_if!( - $index, - $count + 1, - $( $ports => [ - $($messages$(($($xs),+))dont_type_this* - -> $nexts $es),+ - ], )* - ) - } - }; - - { - $index:expr, - $count:expr, - } => { - fail!() - } -) - -macro_rules! select ( - { - $( $port:path => { - $($message:path$(($($x: ident),+))dont_type_this* - -> $next:ident $e:expr),+ - } )+ - } => ({ - let index = std::comm::selecti([$(($port).header()),+]); - select_if!(index, 0, $( $port => [ - $($message$(($($x),+))dont_type_this* -> $next $e),+ - ], )+) - }) -) - -// Types and protocols -pub struct Buffer { - foo: (), - -} - -impl Drop for Buffer { - fn drop(&self) {} -} - -proto! double_buffer ( - acquire:send { - request -> wait_buffer - } - - wait_buffer:recv { - give_buffer(::Buffer) -> release - } - - release:send { - release(::Buffer) -> acquire - } -) - -// Code examples -fn render(_buffer: &Buffer) { - // A dummy function. -} - -fn draw_frame(+channel: double_buffer::client::acquire) { - let channel = request(channel); - select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - release(channel, buffer) - } - } - ); -} - -fn draw_two_frames(+channel: double_buffer::client::acquire) { - let channel = request(channel); - let channel = select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - release(channel, buffer) - } - } - ); - let channel = request(channel); - select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - release(channel, buffer) - } - } - ); -} - -#[cfg(bad1)] -fn draw_two_frames_bad1(+channel: double_buffer::client::acquire) { - let channel = request(channel); - select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - } - } - ); - let channel = request(channel); - select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - release(channel, buffer) - } - } - ); -} - -#[cfg(bad2)] -fn draw_two_frames_bad2(+channel: double_buffer::client::acquire) { - let channel = request(channel); - select! ( - channel => { - give_buffer(buffer) -> channel { - render(&buffer); - release(channel, buffer); - render(&buffer); - release(channel, buffer); - } - } - ); -} - -pub fn main() { } diff --git a/src/test/run-pass/pipe-select-macro.rs b/src/test/run-pass/pipe-select-macro.rs deleted file mode 100644 index cb126017247..00000000000 --- a/src/test/run-pass/pipe-select-macro.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// FIXME #7303: xfail-test - -// Protocols -proto! foo ( - foo:recv { - do_foo -> foo - } -) - -proto! bar ( - bar:recv { - do_bar(int) -> barbar, - do_baz(bool) -> bazbar, - } - - barbar:send { - rebarbar -> bar, - } - - bazbar:send { - rebazbar -> bar - } -) - -fn macros() { - include!("select-macro.rs"); -} - -// Code -fn test(+foo: foo::client::foo, +bar: bar::client::bar) { - use bar::do_baz; - - select! ( - foo => { - foo::do_foo -> _next { - } - } - - bar => { - bar::do_bar(x) -> _next { - info!("%?", x) - }, - - do_baz(b) -> _next { - if b { info!("true") } else { info!("false") } - } - } - ) -} - -pub fn main() { -} diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs deleted file mode 100644 index d9e887fcee8..00000000000 --- a/src/test/run-pass/pipe-select.rs +++ /dev/null @@ -1,134 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-pretty -// xfail-win32 -// xfail-test needs sleep - -extern mod extra; -use extra::timer::sleep; -use extra::uv; - -use std::cell::Cell; -use std::pipes::*; -use std::pipes; -use std::task; - -proto! oneshot ( - waiting:send { - signal -> ! - } -) - -proto! stream ( - Stream:send { - send(T) -> Stream - } -) - -pub fn spawn_service( - init: extern fn() -> (RecvPacketBuffered, - SendPacketBuffered), - service: ~fn(v: RecvPacketBuffered)) - -> SendPacketBuffered { - let (server, client) = init(); - - // This is some nasty gymnastics required to safely move the pipe - // into a new task. - let server = Cell::new(server); - do task::spawn { - service(server.take()); - } - - client -} - -pub fn main() { - use oneshot::client::*; - use stream::client::*; - - let iotask = &uv::global_loop::get(); - - let c = spawn_service(stream::init, |p| { - error!("waiting for pipes"); - let stream::send(x, p) = recv(p); - error!("got pipes"); - let (left, right) : (oneshot::server::waiting, - oneshot::server::waiting) - = x; - error!("selecting"); - let (i, _, _) = select(~[left, right]); - error!("selected"); - assert_eq!(i, 0); - - error!("waiting for pipes"); - let stream::send(x, _) = recv(p); - error!("got pipes"); - let (left, right) : (oneshot::server::waiting, - oneshot::server::waiting) - = x; - error!("selecting"); - let (i, m, _) = select(~[left, right]); - error!("selected %?", i); - if m.is_some() { - assert_eq!(i, 1); - } - }); - - let (p1, c1) = oneshot::init(); - let (p2, _c2) = oneshot::init(); - - let c = send(c, (p1, p2)); - - sleep(iotask, 100); - - signal(c1); - - let (p1, _c1) = oneshot::init(); - let (p2, c2) = oneshot::init(); - - send(c, (p1, p2)); - - sleep(iotask, 100); - - signal(c2); - - test_select2(); -} - -fn test_select2() { - let (ap, ac) = stream::init(); - let (bp, bc) = stream::init(); - - stream::client::send(ac, 42); - - match pipes::select2(ap, bp) { - Left(*) => { } - Right(*) => { fail!() } - } - - stream::client::send(bc, ~"abc"); - - error!("done with first select2"); - - let (ap, ac) = stream::init(); - let (bp, bc) = stream::init(); - - stream::client::send(bc, ~"abc"); - - match pipes::select2(ap, bp) { - Left(*) => { fail!() } - Right(*) => { } - } - - stream::client::send(ac, 42); -} diff --git a/src/test/run-pass/pipe-sleep.rs b/src/test/run-pass/pipe-sleep.rs deleted file mode 100644 index 4475a16a63b..00000000000 --- a/src/test/run-pass/pipe-sleep.rs +++ /dev/null @@ -1,65 +0,0 @@ -// xfail-fast - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-test needs sleep -// xfail-win32 #7999 - -extern mod extra; - -use extra::timer::sleep; -use extra::uv; -use std::cell::Cell; -use std::pipes::*; -use std::pipes; -use std::task; - -proto! oneshot ( - waiting:send { - signal -> ! - } -) - - -/** Spawn a task to provide a service. - -It takes an initialization function that produces a send and receive -endpoint. The send endpoint is returned to the caller and the receive -endpoint is passed to the new task. - -*/ -pub fn spawn_service( - init: extern fn() -> (RecvPacketBuffered, - SendPacketBuffered), - service: ~fn(v: RecvPacketBuffered)) - -> SendPacketBuffered { - let (server, client) = init(); - - // This is some nasty gymnastics required to safely move the pipe - // into a new task. - let server = Cell::new(server); - do task::spawn { - service(server.take()); - } - - client -} - -pub fn main() { - use oneshot::client::*; - - let c = spawn_service(oneshot::init, |p| { recv(p); }); - - let iotask = &uv::global_loop::get(); - sleep(iotask, 500); - - signal(c); -}