@@ -31,7 +31,7 @@ mod syntax {
31
31
}
32
32
33
33
trait gen_send {
34
- fn gen_send ( cx : ext_ctxt ) -> @ast:: item ;
34
+ fn gen_send ( cx : ext_ctxt , try : bool ) -> @ast:: item ;
35
35
}
36
36
37
37
trait to_type_decls {
@@ -45,12 +45,12 @@ trait gen_init {
45
45
}
46
46
47
47
impl compile of gen_send for message {
48
- fn gen_send( cx : ext_ctxt ) -> @ast:: item {
48
+ fn gen_send( cx : ext_ctxt , try : bool ) -> @ast:: item {
49
49
debug ! { "pipec: gen_send" } ;
50
50
match self {
51
51
message( id, span, tys, this,
52
52
some ( { state : next, tys : next_tys} ) ) => {
53
- debug ! { "pipec: next state exists" } ;
53
+ debug ! ( "pipec: next state exists" ) ;
54
54
let next = this. proto . get_state ( next) ;
55
55
assert next_tys. len ( ) == next. ty_params . len ( ) ;
56
56
let arg_names = tys. mapi ( |i, _ty| @( ~"x_" + i. to_str ( ) ) ) ;
@@ -79,85 +79,119 @@ impl compile of gen_send for message {
79
79
} ;
80
80
81
81
body += ~"let b = pipe. reuse_buffer ( ) ; \n ";
82
- body += fmt ! { "let %s = pipes::send_packet_buffered(\
82
+ body += fmt ! ( "let %s = pipes::send_packet_buffered(\
83
83
ptr::addr_of(b.buffer.data.%s));\n ",
84
- sp, * next. name} ;
85
- body += fmt ! { "let %s = pipes::recv_packet_buffered(\
84
+ sp, * next. name) ;
85
+ body += fmt ! ( "let %s = pipes::recv_packet_buffered(\
86
86
ptr::addr_of(b.buffer.data.%s));\n ",
87
- rp, * next. name} ;
87
+ rp, * next. name) ;
88
88
}
89
89
else {
90
90
let pat = match ( this. dir , next. dir ) {
91
- ( send, send) => ~ "( c, s) ",
92
- ( send, recv) => ~ "( s, c) ",
93
- ( recv, send) => ~ "( s, c) ",
94
- ( recv, recv) => ~ "( c, s) "
91
+ ( send, send) => "(c, s)" ,
92
+ ( send, recv) => "(s, c)" ,
93
+ ( recv, send) => "(s, c)" ,
94
+ ( recv, recv) => "(c, s)"
95
95
} ;
96
96
97
- body += fmt ! { "let %s = pipes::entangle();\n " , pat} ;
97
+ body += fmt ! ( "let %s = pipes::entangle();\n " , pat) ;
98
98
}
99
- body += fmt!{ "let message = %s::%s(%s);\n " ,
99
+ body += fmt!( "let message = %s::%s(%s);\n " ,
100
100
* this. proto. name,
101
101
* self . name( ) ,
102
102
str :: connect( vec:: append_one( arg_names, @~"s")
103
103
.map(|x| *x),
104
- ~" , ")};
105
- body += fmt!{" pipes:: send( pipe, message) ; \n "} ;
106
- // return the new channel
107
- body += ~"c } ";
104
+ ~" , "));
105
+
106
+ if !try {
107
+ body += fmt!{" pipes:: send( pipe, message) ; \n "} ;
108
+ // return the new channel
109
+ body += ~"c } ";
110
+ }
111
+ else {
112
+ body += fmt!( "if pipes::send(pipe, message) {\n \
113
+ some(c) \
114
+ } else { none } }") ;
115
+ }
108
116
109
117
let body = cx. parse_expr( body) ;
110
118
111
- cx. item_fn_poly( self . name( ) ,
119
+ let mut rty = cx. ty_path_ast_builder( path( next. data_name( ) ,
120
+ span)
121
+ . add_tys( next_tys) ) ;
122
+ if try {
123
+ rty = cx. ty_option( rty) ;
124
+ }
125
+
126
+ let name = if try {
127
+ @( ~"try_" + *self.name())
128
+ }
129
+ else { self.name() };
130
+
131
+ cx.item_fn_poly(name,
112
132
args_ast,
113
- cx. ty_path_ast_builder( path( next. data_name( ) ,
114
- span)
115
- . add_tys( next_tys) ) ,
133
+ rty,
116
134
self.get_params(),
117
135
cx.expr_block(body))
118
136
}
119
137
120
- message( id, span, tys, this, none) => {
121
- debug!{ "pipec: no next state" } ;
122
- let arg_names = tys. mapi( |i, _ty| @( ~"x_" + i.to_str()));
138
+ message(id, span, tys, this, none) => {
139
+ debug!{" pipec: no next state"};
140
+ let arg_names = tys.mapi(|i, _ty| @(~" x_" + i.to_str()));
123
141
124
- let args_ast = (arg_names, tys).map(
125
- |n, t| cx.arg_mode(n, t, ast::by_copy)
126
- );
142
+ let args_ast = (arg_names, tys).map(
143
+ |n, t| cx.arg_mode(n, t, ast::by_copy)
144
+ );
127
145
128
- let args_ast = vec::append(
129
- ~[cx.arg_mode(@~" pipe",
130
- cx.ty_path_ast_builder(path(this.data_name(),
131
- span)
132
- .add_tys(cx.ty_vars(this.ty_params))),
133
- ast::by_copy)],
134
- args_ast);
146
+ let args_ast = vec::append(
147
+ ~[cx.arg_mode(@~" pipe",
148
+ cx.ty_path_ast_builder(
149
+ path(this.data_name(), span)
150
+ .add_tys(cx.ty_vars(this.ty_params))),
151
+ ast::by_copy)],
152
+ args_ast);
135
153
136
- let message_args = if arg_names.len() == 0 {
137
- ~" "
138
- }
139
- else {
140
- ~" ( " + str::connect(arg_names.map(|x| *x), ~" , ") + ~" ) "
141
- };
154
+ let message_args = if arg_names.len() == 0 {
155
+ ~" "
156
+ }
157
+ else {
158
+ ~" ( " + str::connect(arg_names.map(|x| *x), ~" , ") + ~" ) "
159
+ };
142
160
143
- let mut body = ~" { ";
144
- body += fmt!{" let message = %s:: %s%s; \n ",
145
- * this. proto. name,
146
- * self . name( ) ,
147
- message_args} ;
148
- body += fmt!{ "pipes::send(pipe, message);\n " } ;
149
- body += ~" } ";
161
+ let mut body = ~" { ";
162
+ body += fmt!{" let message = %s:: %s%s; \n ",
163
+ * this. proto. name,
164
+ * self . name( ) ,
165
+ message_args} ;
166
+
167
+ if !try {
168
+ body += fmt!{ "pipes::send(pipe, message);\n " } ;
169
+ body += ~" } ";
170
+ } else {
171
+ body += fmt!(" if pipes:: send( pipe, message) { \
172
+ some( ( ) ) \
173
+ } else { none } } ");
174
+ }
150
175
151
- let body = cx. parse_expr( body) ;
176
+ let body = cx.parse_expr(body);
152
177
153
- cx. item_fn_poly( self . name( ) ,
154
- args_ast,
155
- cx. ty_nil_ast_builder( ) ,
156
- self . get_params( ) ,
157
- cx. expr_block( body) )
178
+ let name = if try {
179
+ @(~" try_" + *self.name())
180
+ }
181
+ else { self.name() };
182
+
183
+ cx.item_fn_poly(name,
184
+ args_ast,
185
+ if try {
186
+ cx.ty_option(cx.ty_nil_ast_builder())
187
+ } else {
188
+ cx.ty_nil_ast_builder()
189
+ },
190
+ self.get_params(),
191
+ cx.expr_block(body))
192
+ }
158
193
}
159
194
}
160
- }
161
195
162
196
fn to_ty(cx: ext_ctxt) -> @ast::ty {
163
197
cx.ty_path_ast_builder(path(self.name(), self.span())
@@ -215,7 +249,8 @@ impl compile of to_type_decls for state {
215
249
let mut items = ~[];
216
250
for self.messages.each |m| {
217
251
if dir == send {
218
- vec::push(items, m.gen_send(cx))
252
+ vec::push(items, m.gen_send(cx, true));
253
+ vec::push(items, m.gen_send(cx, false));
219
254
}
220
255
}
221
256
0 commit comments