]> git.lizzy.rs Git - rust.git/commitdiff
syntax: stage0-guard uses of #ast, rewrite as quote_foo! in stage1,2.
authorGraydon Hoare <graydon@mozilla.com>
Fri, 7 Dec 2012 00:19:50 +0000 (16:19 -0800)
committerGraydon Hoare <graydon@mozilla.com>
Fri, 7 Dec 2012 19:21:14 +0000 (11:21 -0800)
src/libsyntax/ext/pipes/ast_builder.rs
src/libsyntax/ext/pipes/pipec.rs

index 7293438ca09429a4de5201c7770dfe6f79b104a1..7e5a267c00843ce1b5e170b0a034974a16065be2 100644 (file)
@@ -17,6 +17,7 @@
 use ast_util::{ident_to_path, respan, dummy_sp};
 use codemap::span;
 use ext::base::mk_ctxt;
+use quote::rt::*;
 
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
@@ -121,6 +122,7 @@ fn stmt_expr(e: @ast::expr) -> @ast::stmt {
           span: dummy_sp()}
     }
 
+    #[cfg(stage0)]
     fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
         // If the quasiquoter could interpolate idents, this is all
         // we'd need.
@@ -142,6 +144,13 @@ fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
               span: dummy_sp()}]),
                                span: dummy_sp()}, self.next_id()),
          span: dummy_sp()}
+     }
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
+        let ext_cx = self;
+        quote_stmt!( let $ident = $e; )
     }
 
     fn field_imm(name: ident, e: @ast::expr) -> ast::field {
index 1c4dd197105b6b639a9567f37116dbc46e337061..822480f0ad65e8add166a95cccdb458ec5f12cbe 100644 (file)
 use ast::ident;
 use ast_util::dummy_sp;
 use util::interner;
-use print::pprust;
-use pprust::{item_to_str, ty_to_str};
-use ext::base::{mk_ctxt, ext_ctxt};
+use ext::base::ext_ctxt;
 use parse::*;
 use proto::*;
-
+use quote::rt::*;
 use ast_builder::{append_types, path};
 
 // Transitional reexports so qquote can find the paths it is looking for
@@ -303,6 +301,8 @@ fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item] {
 }
 
 impl protocol: gen_init {
+
+    #[cfg(stage0)]
     fn gen_init(cx: ext_ctxt) -> @ast::item {
         let ext_cx = cx;
 
@@ -341,6 +341,47 @@ fn gen_init(cx: ext_ctxt) -> @ast::item {
                            body.to_source(cx)))
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn gen_init(cx: ext_ctxt) -> @ast::item {
+        let ext_cx = cx;
+
+        debug!("gen_init");
+        let start_state = self.states[0];
+
+        let body = if !self.is_bounded() {
+            match start_state.dir {
+              send => quote_expr!( pipes::entangle() ),
+              recv => {
+                quote_expr!({
+                    let (s, c) = pipes::entangle();
+                    (move c, move s)
+                })
+              }
+            }
+        }
+        else {
+            let body = self.gen_init_bounded(ext_cx);
+            match start_state.dir {
+              send => body,
+              recv => {
+                  quote_expr!({
+                      let (s, c) = $body;
+                      (move c, move s)
+                  })
+              }
+            }
+        };
+
+        cx.parse_item(fmt!("pub fn init%s() -> (client::%s, server::%s)\
+                            { use pipes::HasBuffer; %s }",
+                           start_state.ty_params.to_source(cx),
+                           start_state.to_ty(cx).to_source(cx),
+                           start_state.to_ty(cx).to_source(cx),
+                           body.to_source(cx)))
+    }
+
+    #[cfg(stage0)]
     fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
         ext_cx.rec(self.states.map_to_vec(|s| {
             let fty = s.to_ty(ext_cx);
@@ -349,10 +390,22 @@ fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
         }))
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
+        ext_cx.rec(self.states.map_to_vec(|s| {
+            let fty = s.to_ty(ext_cx);
+            ext_cx.field_imm(ext_cx.ident_of(s.name),
+                             quote_expr!(
+                                 pipes::mk_packet::<$fty>()
+                             ))
+        }))
+    }
+
+    #[cfg(stage0)]
     fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
         debug!("gen_init_bounded");
         let buffer_fields = self.gen_buffer_init(ext_cx);
-
         let buffer = #ast {
             ~{header: pipes::BufferHeader(),
               data: $(buffer_fields)}
@@ -376,6 +429,34 @@ fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
         }}
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
+        debug!("gen_init_bounded");
+        let buffer_fields = self.gen_buffer_init(ext_cx);
+        let buffer = quote_expr!(
+            ~{header: pipes::BufferHeader(),
+              data: $buffer_fields}
+        );
+
+        let entangle_body = ext_cx.block_expr(
+            ext_cx.block(
+                self.states.map_to_vec(
+                    |s| ext_cx.parse_stmt(
+                        fmt!("data.%s.set_buffer_(buffer)",
+                             s.name))),
+                ext_cx.parse_expr(
+                    fmt!("ptr::addr_of(&(data.%s))",
+                         self.states[0].name))));
+
+        quote_expr!({
+            let buffer = $buffer;
+            do pipes::entangle_buffer(move buffer) |buffer, data| {
+                $entangle_body
+            }
+        })
+    }
+
     fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
         let mut params: ~[ast::ty_param] = ~[];
         for (copy self.states).each |s| {
@@ -391,6 +472,7 @@ fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
                                .add_tys(cx.ty_vars(params)))
     }
 
+    #[cfg(stage0)]
     fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
         let ext_cx = cx;
         let mut params: ~[ast::ty_param] = ~[];
@@ -405,6 +487,32 @@ fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
             let fty = #ast[ty] {
                 pipes::Packet<$(ty)>
             };
+
+            cx.ty_field_imm(cx.ident_of(s.name), fty)
+        };
+
+        cx.item_ty_poly(
+            cx.ident_of(~"__Buffer"),
+            dummy_sp(),
+            cx.ty_rec(fields),
+            params)
+    }
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
+        let ext_cx = cx;
+        let mut params: ~[ast::ty_param] = ~[];
+        let fields = do (copy self.states).map_to_vec |s| {
+            for s.ty_params.each |tp| {
+                match params.find(|tpp| tp.ident == tpp.ident) {
+                  None => params.push(*tp),
+                  _ => ()
+                }
+            }
+            let ty = s.to_ty(cx);
+            let fty = quote_ty!( pipes::Packet<$ty> );
+
             cx.ty_field_imm(cx.ident_of(s.name), fty)
         };
 
@@ -420,7 +528,6 @@ fn compile(cx: ext_ctxt) -> @ast::item {
         let mut client_states = ~[];
         let mut server_states = ~[];
 
-        // :(
         for (copy self.states).each |s| {
             items += s.to_type_decls(cx);
 
@@ -441,95 +548,4 @@ fn compile(cx: ext_ctxt) -> @ast::item {
 
         cx.item_mod(cx.ident_of(self.name), self.span, items)
     }
-}
-
-trait to_source {
-    // Takes a thing and generates a string containing rust code for it.
-    fn to_source(cx: ext_ctxt) -> ~str;
-}
-
-impl @ast::item: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        item_to_str(self, cx.parse_sess().interner)
-    }
-}
-
-impl ~[@ast::item]: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        str::connect(self.map(|i| i.to_source(cx)), ~"\n\n")
-    }
-}
-
-impl @ast::Ty: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        ty_to_str(self, cx.parse_sess().interner)
-    }
-}
-
-impl ~[@ast::Ty]: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        str::connect(self.map(|i| i.to_source(cx)), ~", ")
-    }
-}
-
-impl ~[ast::ty_param]: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        pprust::typarams_to_str(self, cx.parse_sess().interner)
-    }
-}
-
-impl @ast::expr: to_source {
-    fn to_source(cx: ext_ctxt) -> ~str {
-        pprust::expr_to_str(self, cx.parse_sess().interner)
     }
-}
-
-trait ext_ctxt_parse_utils {
-    fn parse_item(s: ~str) -> @ast::item;
-    fn parse_expr(s: ~str) -> @ast::expr;
-    fn parse_stmt(s: ~str) -> @ast::stmt;
-    fn parse_tts(s: ~str) -> ~[ast::token_tree];
-}
-
-impl ext_ctxt: ext_ctxt_parse_utils {
-    fn parse_item(s: ~str) -> @ast::item {
-        let res = parse::parse_item_from_source_str(
-            ~"***protocol expansion***",
-            @(copy s),
-            self.cfg(),
-            ~[],
-            self.parse_sess());
-        match res {
-          Some(ast) => ast,
-          None => {
-            error!("Parse error with ```\n%s\n```", s);
-            fail
-          }
-        }
-    }
-
-    fn parse_stmt(s: ~str) -> @ast::stmt {
-        parse::parse_stmt_from_source_str(
-            ~"***protocol expansion***",
-            @(copy s),
-            self.cfg(),
-            ~[],
-            self.parse_sess())
-    }
-
-    fn parse_expr(s: ~str) -> @ast::expr {
-        parse::parse_expr_from_source_str(
-            ~"***protocol expansion***",
-            @(copy s),
-            self.cfg(),
-            self.parse_sess())
-    }
-
-    fn parse_tts(s: ~str) -> ~[ast::token_tree] {
-        parse::parse_tts_from_source_str(
-            ~"***protocol expansion***",
-            @(copy s),
-            self.cfg(),
-            self.parse_sess())
-    }
-}