Skip to content

Commit 09573ea

Browse files
committed
syntax: stage0-guard uses of #ast, rewrite as quote_foo! in stage1,2.
1 parent a6fcfd7 commit 09573ea

File tree

2 files changed

+122
-97
lines changed

2 files changed

+122
-97
lines changed

src/libsyntax/ext/pipes/ast_builder.rs

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use ast::{ident, node_id};
1717
use ast_util::{ident_to_path, respan, dummy_sp};
1818
use codemap::span;
1919
use ext::base::mk_ctxt;
20+
use quote::rt::*;
2021

2122
// Transitional reexports so qquote can find the paths it is looking for
2223
mod syntax {
@@ -121,6 +122,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
121122
span: dummy_sp()}
122123
}
123124

125+
#[cfg(stage0)]
124126
fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
125127
// If the quasiquoter could interpolate idents, this is all
126128
// we'd need.
@@ -142,6 +144,13 @@ impl ext_ctxt: ext_ctxt_ast_builder {
142144
span: dummy_sp()}]),
143145
span: dummy_sp()}, self.next_id()),
144146
span: dummy_sp()}
147+
}
148+
149+
#[cfg(stage1)]
150+
#[cfg(stage2)]
151+
fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
152+
let ext_cx = self;
153+
quote_stmt!( let $ident = $e; )
145154
}
146155

147156
fn field_imm(name: ident, e: @ast::expr) -> ast::field {

src/libsyntax/ext/pipes/pipec.rs

+113-97
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ use dvec::DVec;
1717
use ast::ident;
1818
use ast_util::dummy_sp;
1919
use util::interner;
20-
use print::pprust;
21-
use pprust::{item_to_str, ty_to_str};
22-
use ext::base::{mk_ctxt, ext_ctxt};
20+
use ext::base::ext_ctxt;
2321
use parse::*;
2422
use proto::*;
25-
23+
use quote::rt::*;
2624
use ast_builder::{append_types, path};
2725

2826
// Transitional reexports so qquote can find the paths it is looking for
@@ -303,6 +301,8 @@ impl state: to_type_decls {
303301
}
304302
305303
impl protocol: gen_init {
304+
305+
#[cfg(stage0)]
306306
fn gen_init(cx: ext_ctxt) -> @ast::item {
307307
let ext_cx = cx;
308308
@@ -341,6 +341,47 @@ impl protocol: gen_init {
341341
body.to_source(cx)))
342342
}
343343
344+
#[cfg(stage1)]
345+
#[cfg(stage2)]
346+
fn gen_init(cx: ext_ctxt) -> @ast::item {
347+
let ext_cx = cx;
348+
349+
debug!("gen_init");
350+
let start_state = self.states[0];
351+
352+
let body = if !self.is_bounded() {
353+
match start_state.dir {
354+
send => quote_expr!( pipes::entangle() ),
355+
recv => {
356+
quote_expr!({
357+
let (s, c) = pipes::entangle();
358+
(move c, move s)
359+
})
360+
}
361+
}
362+
}
363+
else {
364+
let body = self.gen_init_bounded(ext_cx);
365+
match start_state.dir {
366+
send => body,
367+
recv => {
368+
quote_expr!({
369+
let (s, c) = $body;
370+
(move c, move s)
371+
})
372+
}
373+
}
374+
};
375+
376+
cx.parse_item(fmt!("pub fn init%s() -> (client::%s, server::%s)\
377+
{ use pipes::HasBuffer; %s }",
378+
start_state.ty_params.to_source(cx),
379+
start_state.to_ty(cx).to_source(cx),
380+
start_state.to_ty(cx).to_source(cx),
381+
body.to_source(cx)))
382+
}
383+
384+
#[cfg(stage0)]
344385
fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
345386
ext_cx.rec(self.states.map_to_vec(|s| {
346387
let fty = s.to_ty(ext_cx);
@@ -349,10 +390,22 @@ impl protocol: gen_init {
349390
}))
350391
}
351392
393+
#[cfg(stage1)]
394+
#[cfg(stage2)]
395+
fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
396+
ext_cx.rec(self.states.map_to_vec(|s| {
397+
let fty = s.to_ty(ext_cx);
398+
ext_cx.field_imm(ext_cx.ident_of(s.name),
399+
quote_expr!(
400+
pipes::mk_packet::<$fty>()
401+
))
402+
}))
403+
}
404+
405+
#[cfg(stage0)]
352406
fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
353407
debug!("gen_init_bounded");
354408
let buffer_fields = self.gen_buffer_init(ext_cx);
355-
356409
let buffer = #ast {
357410
~{header: pipes::BufferHeader(),
358411
data: $(buffer_fields)}
@@ -376,6 +429,34 @@ impl protocol: gen_init {
376429
}}
377430
}
378431
432+
#[cfg(stage1)]
433+
#[cfg(stage2)]
434+
fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
435+
debug!("gen_init_bounded");
436+
let buffer_fields = self.gen_buffer_init(ext_cx);
437+
let buffer = quote_expr!(
438+
~{header: pipes::BufferHeader(),
439+
data: $buffer_fields}
440+
);
441+
442+
let entangle_body = ext_cx.block_expr(
443+
ext_cx.block(
444+
self.states.map_to_vec(
445+
|s| ext_cx.parse_stmt(
446+
fmt!("data.%s.set_buffer_(buffer)",
447+
s.name))),
448+
ext_cx.parse_expr(
449+
fmt!("ptr::addr_of(&(data.%s))",
450+
self.states[0].name))));
451+
452+
quote_expr!({
453+
let buffer = $buffer;
454+
do pipes::entangle_buffer(move buffer) |buffer, data| {
455+
$entangle_body
456+
}
457+
})
458+
}
459+
379460
fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
380461
let mut params: ~[ast::ty_param] = ~[];
381462
for (copy self.states).each |s| {
@@ -391,6 +472,7 @@ impl protocol: gen_init {
391472
.add_tys(cx.ty_vars(params)))
392473
}
393474
475+
#[cfg(stage0)]
394476
fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
395477
let ext_cx = cx;
396478
let mut params: ~[ast::ty_param] = ~[];
@@ -405,6 +487,32 @@ impl protocol: gen_init {
405487
let fty = #ast[ty] {
406488
pipes::Packet<$(ty)>
407489
};
490+
491+
cx.ty_field_imm(cx.ident_of(s.name), fty)
492+
};
493+
494+
cx.item_ty_poly(
495+
cx.ident_of(~"__Buffer"),
496+
dummy_sp(),
497+
cx.ty_rec(fields),
498+
params)
499+
}
500+
501+
#[cfg(stage1)]
502+
#[cfg(stage2)]
503+
fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
504+
let ext_cx = cx;
505+
let mut params: ~[ast::ty_param] = ~[];
506+
let fields = do (copy self.states).map_to_vec |s| {
507+
for s.ty_params.each |tp| {
508+
match params.find(|tpp| tp.ident == tpp.ident) {
509+
None => params.push(*tp),
510+
_ => ()
511+
}
512+
}
513+
let ty = s.to_ty(cx);
514+
let fty = quote_ty!( pipes::Packet<$ty> );
515+
408516
cx.ty_field_imm(cx.ident_of(s.name), fty)
409517
};
410518
@@ -420,7 +528,6 @@ impl protocol: gen_init {
420528
let mut client_states = ~[];
421529
let mut server_states = ~[];
422530
423-
// :(
424531
for (copy self.states).each |s| {
425532
items += s.to_type_decls(cx);
426533
@@ -441,95 +548,4 @@ impl protocol: gen_init {
441548

442549
cx.item_mod(cx.ident_of(self.name), self.span, items)
443550
}
444-
}
445-
446-
trait to_source {
447-
// Takes a thing and generates a string containing rust code for it.
448-
fn to_source(cx: ext_ctxt) -> ~str;
449-
}
450-
451-
impl @ast::item: to_source {
452-
fn to_source(cx: ext_ctxt) -> ~str {
453-
item_to_str(self, cx.parse_sess().interner)
454-
}
455-
}
456-
457-
impl ~[@ast::item]: to_source {
458-
fn to_source(cx: ext_ctxt) -> ~str {
459-
str::connect(self.map(|i| i.to_source(cx)), ~"\n\n")
460-
}
461-
}
462-
463-
impl @ast::Ty: to_source {
464-
fn to_source(cx: ext_ctxt) -> ~str {
465-
ty_to_str(self, cx.parse_sess().interner)
466-
}
467-
}
468-
469-
impl ~[@ast::Ty]: to_source {
470-
fn to_source(cx: ext_ctxt) -> ~str {
471-
str::connect(self.map(|i| i.to_source(cx)), ~", ")
472-
}
473-
}
474-
475-
impl ~[ast::ty_param]: to_source {
476-
fn to_source(cx: ext_ctxt) -> ~str {
477-
pprust::typarams_to_str(self, cx.parse_sess().interner)
478-
}
479-
}
480-
481-
impl @ast::expr: to_source {
482-
fn to_source(cx: ext_ctxt) -> ~str {
483-
pprust::expr_to_str(self, cx.parse_sess().interner)
484551
}
485-
}
486-
487-
trait ext_ctxt_parse_utils {
488-
fn parse_item(s: ~str) -> @ast::item;
489-
fn parse_expr(s: ~str) -> @ast::expr;
490-
fn parse_stmt(s: ~str) -> @ast::stmt;
491-
fn parse_tts(s: ~str) -> ~[ast::token_tree];
492-
}
493-
494-
impl ext_ctxt: ext_ctxt_parse_utils {
495-
fn parse_item(s: ~str) -> @ast::item {
496-
let res = parse::parse_item_from_source_str(
497-
~"***protocol expansion***",
498-
@(copy s),
499-
self.cfg(),
500-
~[],
501-
self.parse_sess());
502-
match res {
503-
Some(ast) => ast,
504-
None => {
505-
error!("Parse error with ```\n%s\n```", s);
506-
fail
507-
}
508-
}
509-
}
510-
511-
fn parse_stmt(s: ~str) -> @ast::stmt {
512-
parse::parse_stmt_from_source_str(
513-
~"***protocol expansion***",
514-
@(copy s),
515-
self.cfg(),
516-
~[],
517-
self.parse_sess())
518-
}
519-
520-
fn parse_expr(s: ~str) -> @ast::expr {
521-
parse::parse_expr_from_source_str(
522-
~"***protocol expansion***",
523-
@(copy s),
524-
self.cfg(),
525-
self.parse_sess())
526-
}
527-
528-
fn parse_tts(s: ~str) -> ~[ast::token_tree] {
529-
parse::parse_tts_from_source_str(
530-
~"***protocol expansion***",
531-
@(copy s),
532-
self.cfg(),
533-
self.parse_sess())
534-
}
535-
}

0 commit comments

Comments
 (0)