pingpong protocol parses, although I should probably rewrite this to use Paul's Early parser stuff.

This commit is contained in:
Eric Holk 2012-07-05 18:01:11 -07:00
parent 84434bc084
commit 6806aa0e66
4 changed files with 38 additions and 15 deletions

View File

@ -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<A> {
for self.each |i| {
if p(i) { ret some(i) }
}
ret none;
}
}

View File

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

View File

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

View File

@ -80,7 +80,8 @@ mod ext {
mod source_util;
mod pipes {
mod pipec;
mod ast_builder;
mod parse_proto;
mod pipec;
}
}