diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs index 1fae52b4afe..02c32a1bf0d 100644 --- a/src/libcore/iter-trait.rs +++ b/src/libcore/iter-trait.rs @@ -35,4 +35,11 @@ fn to_vec() -> ~[A] { iter::to_vec(self) } fn min() -> A { iter::min(self) } fn max() -> A { iter::max(self) } + + fn find(p: fn(A) -> bool) -> option { + for self.each |i| { + if p(i) { ret some(i) } + } + ret none; + } } diff --git a/src/libsyntax/ext/pipes.rs b/src/libsyntax/ext/pipes.rs index 5a84d764b9f..ce9b0b0a2cf 100644 --- a/src/libsyntax/ext/pipes.rs +++ b/src/libsyntax/ext/pipes.rs @@ -1,17 +1,27 @@ import codemap::span; import ext::base::ext_ctxt; +import ast::tt_delim; +import parse::lexer::{new_tt_reader, reader, tt_reader_as_reader}; +import parse::parser::{parser, SOURCE_FILE}; +import parse::common::parser_common; + +import pipes::parse_proto::proto_parser; import pipes::pipec::*; -fn expand_proto(cx: ext_ctxt, span: span, id: ast::ident, tt: ast::token_tree) +fn expand_proto(cx: ext_ctxt, _sp: span, id: ast::ident, tt: ast::token_tree) -> @ast::item { - let proto = protocol(id); - let ping = proto.add_state(@"ping", send); - let pong = proto.add_state(@"pong", recv); + let sess = cx.parse_sess(); + let cfg = cx.cfg(); + let body_core = alt tt { tt_delim(tts) { tts } _ {fail}}; + let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic, + cx.parse_sess().interner, body_core); + let rdr = tt_rdr as reader; + let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE); + + let proto = rust_parser.parse_proto(id); - ping.add_message(@"ping", []/~, pong, ~[]); - pong.add_message(@"pong", []/~, ping, ~[]); proto.compile(cx) } \ No newline at end of file diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 4ad4eef636b..e9dfffcd543 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -12,7 +12,7 @@ import pprust::{item_to_str, ty_to_str}; import ext::base::{mk_ctxt, ext_ctxt}; import parse; -import parse::{parse_item_from_source_str}; +import parse::*; import ast_builder::ast_builder; import ast_builder::methods; @@ -42,7 +42,7 @@ fn reverse() -> direction { enum message { // name, data, current state, next state, next tys - message(ident, ~[@ast::ty], state, state, ~[@ast::ty]) + message(ident, ~[@ast::ty], state, ident, ~[@ast::ty]) } impl methods for message { @@ -89,11 +89,10 @@ fn get_params() -> ~[ast::ty_param] { fn gen_send(cx: ext_ctxt) -> @ast::item { alt self { message(id, tys, this, next, next_tys) { + let next = this.proto.get_state(next); + assert next_tys.len() == next.ty_params.len(); let arg_names = tys.mapi(|i, _ty| @("x_" + i.to_str())); - let args = (arg_names, tys).map(|n, t| - *n + ": " + t.to_source()); - let args_ast = (arg_names, tys).map( |n, t| cx.arg_mode(n, t, ast::by_copy) ); @@ -146,9 +145,8 @@ enum state { } impl methods for state { - fn add_message(name: ident, +data: ~[@ast::ty], next: state, + fn add_message(name: ident, +data: ~[@ast::ty], next: ident, +next_tys: ~[@ast::ty]) { - assert next_tys.len() == next.ty_params.len(); self.messages.push(message(name, data, self, next, next_tys)); } @@ -179,6 +177,7 @@ fn to_type_decls(cx: ext_ctxt) -> [@ast::item]/~ { let message(_, tys, this, next, next_tys) = m; let name = m.name(); + let next = this.proto.get_state(next); let next_name = next.data_name(); let dir = alt this.dir { @@ -239,6 +238,11 @@ fn add_state(name: ident, dir: direction) -> state { self.add_state_poly(name, dir, ~[]) } + /// Get or create a state. + fn get_state(name: ident) -> state { + self.states.find(|i| i.name == name).get() + } + fn add_state_poly(name: ident, dir: direction, +ty_params: ~[ast::ty_param]) -> state { let messages = dvec(); @@ -291,7 +295,8 @@ fn compile(cx: ext_ctxt) -> @ast::item { let mut client_states = ~[]; let mut server_states = ~[]; - for self.states.each |s| { + // :( + for (copy self.states).each |s| { items += s.to_type_decls(cx); client_states += s.to_endpoint_decls(cx, send); diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 852c815e9fe..7c453cc96e4 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -80,7 +80,8 @@ mod ext { mod source_util; mod pipes { - mod pipec; mod ast_builder; + mod parse_proto; + mod pipec; } }