@@ -17,12 +17,10 @@ use dvec::DVec;
17
17
use ast:: ident;
18
18
use ast_util:: dummy_sp;
19
19
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;
23
21
use parse:: * ;
24
22
use proto:: * ;
25
-
23
+ use quote :: rt :: * ;
26
24
use ast_builder:: { append_types, path} ;
27
25
28
26
// Transitional reexports so qquote can find the paths it is looking for
@@ -303,6 +301,8 @@ impl state: to_type_decls {
303
301
}
304
302
305
303
impl protocol: gen_init {
304
+
305
+ #[cfg(stage0)]
306
306
fn gen_init(cx: ext_ctxt) -> @ast::item {
307
307
let ext_cx = cx;
308
308
@@ -341,6 +341,47 @@ impl protocol: gen_init {
341
341
body.to_source(cx)))
342
342
}
343
343
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)]
344
385
fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
345
386
ext_cx.rec(self.states.map_to_vec(|s| {
346
387
let fty = s.to_ty(ext_cx);
@@ -349,10 +390,22 @@ impl protocol: gen_init {
349
390
}))
350
391
}
351
392
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)]
352
406
fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
353
407
debug!(" gen_init_bounded");
354
408
let buffer_fields = self.gen_buffer_init(ext_cx);
355
-
356
409
let buffer = #ast {
357
410
~{header: pipes::BufferHeader(),
358
411
data: $(buffer_fields)}
@@ -376,6 +429,34 @@ impl protocol: gen_init {
376
429
}}
377
430
}
378
431
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
+
379
460
fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
380
461
let mut params: ~[ast::ty_param] = ~[];
381
462
for (copy self.states).each |s| {
@@ -391,6 +472,7 @@ impl protocol: gen_init {
391
472
.add_tys(cx.ty_vars(params)))
392
473
}
393
474
475
+ #[cfg(stage0)]
394
476
fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
395
477
let ext_cx = cx;
396
478
let mut params: ~[ast::ty_param] = ~[];
@@ -405,6 +487,32 @@ impl protocol: gen_init {
405
487
let fty = #ast[ty] {
406
488
pipes::Packet<$(ty)>
407
489
};
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
+
408
516
cx.ty_field_imm(cx.ident_of(s.name), fty)
409
517
};
410
518
@@ -420,7 +528,6 @@ impl protocol: gen_init {
420
528
let mut client_states = ~[];
421
529
let mut server_states = ~[];
422
530
423
- // :(
424
531
for (copy self.states).each |s| {
425
532
items += s.to_type_decls(cx);
426
533
@@ -441,95 +548,4 @@ impl protocol: gen_init {
441
548
442
549
cx. item_mod( cx. ident_of( self . name) , self . span, items)
443
550
}
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)
484
551
}
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