@@ -40,15 +40,17 @@ impl methods for direction {
40
40
}
41
41
}
42
42
43
+ type next_state = option < { state: ident , tys : ~[ @ast:: ty ] } > ;
44
+
43
45
enum message {
44
- // name, data, current state, next state, next tys
45
- message( ident , ~[ @ast:: ty ] , state , ident , ~ [ @ast :: ty ] )
46
+ // name, data, current state, next state
47
+ message( ident , ~[ @ast:: ty ] , state , next_state )
46
48
}
47
49
48
50
impl methods for message {
49
51
fn name ( ) -> ident {
50
52
alt self {
51
- message( id, _, _, _, _ ) {
53
+ message( id, _, _, _) {
52
54
id
53
55
}
54
56
}
@@ -57,15 +59,17 @@ impl methods for message {
57
59
// Return the type parameters actually used by this message
58
60
fn get_params ( ) -> ~[ ast:: ty_param ] {
59
61
alt self {
60
- message( _, _, this, _, _ ) {
62
+ message( _, _, this, _) {
61
63
this. ty_params
62
64
}
63
65
}
64
66
}
65
67
66
68
fn gen_send ( cx : ext_ctxt ) -> @ast:: item {
69
+ #debug ( "pipec: gen_send" ) ;
67
70
alt self {
68
- message( id, tys, this, next, next_tys) {
71
+ message( id, tys, this, some ( { state: next, tys: next_tys} ) ) {
72
+ #debug ( "pipec: next state exists" ) ;
69
73
let next = this. proto . get_state ( next) ;
70
74
assert next_tys. len ( ) == next. ty_params . len ( ) ;
71
75
let arg_names = tys. mapi ( |i, _ty| @( ~"x_" + i. to_str ( ) ) ) ;
@@ -107,6 +111,45 @@ impl methods for message {
107
111
self . get_params ( ) ,
108
112
cx. expr_block ( body) )
109
113
}
114
+
115
+ message ( id, tys, this, none) {
116
+ #debug ( "pipec: no next state" ) ;
117
+ let arg_names = tys. mapi ( |i, _ty| @( ~"x_" + i. to_str ( ) ) ) ;
118
+
119
+ let args_ast = ( arg_names, tys) . map (
120
+ |n, t| cx. arg_mode ( n, t, ast:: by_copy)
121
+ ) ;
122
+
123
+ let args_ast = vec:: append (
124
+ ~[ cx. arg_mode ( @~"pipe",
125
+ cx. ty_path ( path ( this. data_name ( ) )
126
+ . add_tys ( cx. ty_vars ( this. ty_params ) ) ) ,
127
+ ast:: by_copy) ] ,
128
+ args_ast) ;
129
+
130
+ let message_args = if arg_names. len ( ) == 0 {
131
+ ~""
132
+ }
133
+ else {
134
+ ~"( " + str::connect(arg_names.map(|x| *x), ~" , ") + ~" ) "
135
+ } ;
136
+
137
+ let mut body = ~"{ ";
138
+ body += #fmt(" let message = %s:: %s%s; \n ",
139
+ * this. proto . name ,
140
+ * self . name ( ) ,
141
+ message_args) ;
142
+ body += #fmt ( "pipes::send(pipe, message);\n " ) ;
143
+ body += ~" } ";
144
+
145
+ let body = cx. parse_expr ( body) ;
146
+
147
+ cx. item_fn_poly ( self . name ( ) ,
148
+ args_ast,
149
+ cx. ty_nil ( ) ,
150
+ self . get_params ( ) ,
151
+ cx. expr_block ( body) )
152
+ }
110
153
}
111
154
}
112
155
}
@@ -122,9 +165,9 @@ enum state {
122
165
}
123
166
124
167
impl methods for state {
125
- fn add_message ( name : ident , +data : ~[ @ast:: ty ] , next : ident ,
126
- + next_tys : ~ [ @ast :: ty ] ) {
127
- self . messages . push ( message ( name , data , self , next , next_tys ) ) ;
168
+ fn add_message( name: ident, +data: ~[ @ast:: ty] , next: next_state ) {
169
+ self . messages . push ( message ( name , data , self ,
170
+ next ) ) ;
128
171
}
129
172
130
173
fn filename ( ) -> ~str {
@@ -140,6 +183,7 @@ impl methods for state {
140
183
}
141
184
142
185
fn to_type_decls ( cx : ext_ctxt ) -> ~[ @ast:: item ] {
186
+ #debug ( "pipec: to_type_decls" ) ;
143
187
// This compiles into two different type declarations. Say the
144
188
// state is called ping. This will generate both `ping` and
145
189
// `ping_message`. The first contains data that the user cares
@@ -151,22 +195,26 @@ impl methods for state {
151
195
let mut items_msg = ~[ ] ;
152
196
153
197
for self . messages. each |m| {
154
- let message( _, tys, this, next, next_tys) = m;
155
-
156
- let name = m. name ( ) ;
157
- let next = this. proto . get_state ( next) ;
158
- let next_name = next. data_name ( ) ;
159
-
160
- let dir = alt this. dir {
161
- send { @~"server" }
162
- recv { @~"client" }
198
+ let message( name, tys, this, next) = m;
199
+
200
+ let tys = alt next {
201
+ some( { state: next, tys: next_tys} ) {
202
+ let next = this. proto . get_state ( next) ;
203
+ let next_name = next. data_name ( ) ;
204
+
205
+ let dir = alt this. dir {
206
+ send { @~"server" }
207
+ recv { @~"client" }
208
+ } ;
209
+
210
+ vec:: append_one ( tys,
211
+ cx. ty_path ( ( dir + next_name)
212
+ . add_tys ( next_tys) ) )
213
+ }
214
+ none { tys }
163
215
} ;
164
216
165
- let v = cx. variant ( name,
166
- vec:: append_one (
167
- tys,
168
- cx. ty_path ( ( dir + next_name)
169
- . add_tys ( next_tys) ) ) ) ;
217
+ let v = cx. variant ( name, tys) ;
170
218
171
219
vec:: push ( items_msg, v) ;
172
220
}
@@ -175,6 +223,7 @@ impl methods for state {
175
223
}
176
224
177
225
fn to_endpoint_decls ( cx : ext_ctxt , dir : direction ) -> ~[ @ast:: item ] {
226
+ #debug ( "pipec: to_endpoint_decls" ) ;
178
227
let dir = alt dir {
179
228
send { ( * self ) . dir }
180
229
recv { ( * self ) . dir . reverse ( ) }
0 commit comments