1
- // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- // chameneos
11
+ #![ feature( phase) ]
12
+ #[ phase( syntax) ] extern crate green;
12
13
13
- use std:: option;
14
- use std:: os;
15
14
use std:: strbuf:: StrBuf ;
16
- use std:: task;
15
+ use std:: fmt;
16
+
17
+ green_start ! ( main)
17
18
18
19
fn print_complements ( ) {
19
20
let all = [ Blue , Red , Yellow ] ;
20
21
for aa in all. iter ( ) {
21
22
for bb in all. iter ( ) {
22
- println ! ( "{} + {} -> {}" , show_color( * aa) , show_color( * bb) ,
23
- show_color( transform( * aa, * bb) ) ) ;
23
+ println ! ( "{} + {} -> {}" , * aa, * bb, transform( * aa, * bb) ) ;
24
24
}
25
25
}
26
26
}
27
27
28
- enum color { Red , Yellow , Blue }
28
+ enum Color { Red , Yellow , Blue }
29
+ impl fmt:: Show for Color {
30
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
31
+ let str = match * self {
32
+ Red => "red" ,
33
+ Yellow => "yellow" ,
34
+ Blue => "blue" ,
35
+ } ;
36
+ f. buf . write ( str. as_bytes ( ) )
37
+ }
38
+ }
29
39
30
40
struct CreatureInfo {
31
41
name : uint ,
32
- color : color
42
+ color : Color
33
43
}
34
44
35
- fn show_color ( cc : color ) -> & ' static str {
36
- match cc {
37
- Red => "red" ,
38
- Yellow => "yellow" ,
39
- Blue => "blue"
40
- }
41
- }
42
-
43
- fn show_color_list ( set : Vec < color > ) -> StrBuf {
45
+ fn show_color_list ( set : Vec < Color > ) -> StrBuf {
44
46
let mut out = StrBuf :: new ( ) ;
45
47
for col in set. iter ( ) {
46
48
out. push_char ( ' ' ) ;
47
- out. push_str ( show_color ( * col) ) ;
49
+ out. push_str ( col. to_str ( ) ) ;
48
50
}
49
51
out
50
52
}
51
53
52
54
fn show_digit ( nn : uint ) -> & ' static str {
53
55
match nn {
54
- 0 => { "zero" }
55
- 1 => { "one" }
56
- 2 => { "two" }
57
- 3 => { "three" }
58
- 4 => { "four" }
59
- 5 => { "five" }
60
- 6 => { "six" }
61
- 7 => { "seven" }
62
- 8 => { "eight" }
63
- 9 => { "nine" }
56
+ 0 => { " zero" }
57
+ 1 => { " one" }
58
+ 2 => { " two" }
59
+ 3 => { " three" }
60
+ 4 => { " four" }
61
+ 5 => { " five" }
62
+ 6 => { " six" }
63
+ 7 => { " seven" }
64
+ 8 => { " eight" }
65
+ 9 => { " nine" }
64
66
_ => { fail ! ( "expected digits from 0 to 9..." ) }
65
67
}
66
68
}
67
69
68
- fn show_number ( nn : uint ) -> StrBuf {
69
- let mut out = vec ! [ ] ;
70
- let mut num = nn;
71
- let mut dig;
72
- let mut len = 0 ;
73
- if num == 0 { out. push ( show_digit ( 0 ) ) } ;
74
-
75
- while num != 0 {
76
- dig = num % 10 ;
77
- num = num / 10 ;
78
- out. push ( " " ) ;
79
- let s = show_digit ( dig) ;
80
- out. push ( s) ;
81
- len += 1 + s. len ( ) ;
82
- }
83
- len += 1 ;
84
- out. push ( " " ) ;
70
+ struct Number ( uint ) ;
71
+ impl fmt:: Show for Number {
72
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
73
+ let mut out = vec ! [ ] ;
74
+ let Number ( mut num) = * self ;
75
+ if num == 0 { out. push ( show_digit ( 0 ) ) } ;
76
+
77
+ while num != 0 {
78
+ let dig = num % 10 ;
79
+ num = num / 10 ;
80
+ let s = show_digit ( dig) ;
81
+ out. push ( s) ;
82
+ }
85
83
86
- let mut ret = StrBuf :: with_capacity ( len) ;
87
- for s in out. iter ( ) . rev ( ) {
88
- ret. push_str ( * s) ;
84
+ for s in out. iter ( ) . rev ( ) {
85
+ try!( f. buf . write ( s. as_bytes ( ) ) ) ;
86
+ }
87
+ Ok ( ( ) )
89
88
}
90
- ret
91
89
}
92
90
93
- fn transform ( aa : color , bb : color ) -> color {
91
+ fn transform ( aa : Color , bb : Color ) -> Color {
94
92
match ( aa, bb) {
95
93
( Red , Red ) => { Red }
96
94
( Red , Yellow ) => { Blue }
@@ -106,23 +104,22 @@ fn transform(aa: color, bb: color) -> color {
106
104
107
105
fn creature (
108
106
name : uint ,
109
- color : color ,
110
- from_rendezvous : Receiver < Option < CreatureInfo > > ,
107
+ mut color : Color ,
108
+ from_rendezvous : Receiver < CreatureInfo > ,
111
109
to_rendezvous : Sender < CreatureInfo > ,
112
110
to_rendezvous_log : Sender < ~str >
113
111
) {
114
- let mut color = color;
115
112
let mut creatures_met = 0 ;
116
113
let mut evil_clones_met = 0 ;
114
+ let mut rendezvous = from_rendezvous. iter ( ) ;
117
115
118
116
loop {
119
117
// ask for a pairing
120
118
to_rendezvous. send ( CreatureInfo { name : name, color : color} ) ;
121
- let resp = from_rendezvous. recv ( ) ;
122
119
123
- // log and change, or print and quit
124
- match resp {
125
- option :: Some ( other_creature) => {
120
+ // log and change, or quit
121
+ match rendezvous . next ( ) {
122
+ Some ( other_creature) => {
126
123
color = transform ( color, other_creature. color ) ;
127
124
128
125
// track some statistics
@@ -131,41 +128,35 @@ fn creature(
131
128
evil_clones_met += 1 ;
132
129
}
133
130
}
134
- option:: None => {
135
- // log creatures met and evil clones of self
136
- let report = format ! ( "{} {}" ,
137
- creatures_met, show_number( evil_clones_met) . as_slice( ) ) ;
138
- to_rendezvous_log. send ( report) ;
139
- break ;
140
- }
131
+ None => break
141
132
}
142
133
}
134
+ // log creatures met and evil clones of self
135
+ let report = format ! ( "{}{}" , creatures_met, Number ( evil_clones_met) ) ;
136
+ to_rendezvous_log. send ( report) ;
143
137
}
144
138
145
- fn rendezvous ( nn : uint , set : Vec < color > ) {
146
-
139
+ fn rendezvous ( nn : uint , set : Vec < Color > ) {
147
140
// these ports will allow us to hear from the creatures
148
141
let ( to_rendezvous, from_creatures) = channel :: < CreatureInfo > ( ) ;
149
- let ( to_rendezvous_log, from_creatures_log) = channel :: < ~str > ( ) ;
150
142
151
143
// these channels will be passed to the creatures so they can talk to us
144
+ let ( to_rendezvous_log, from_creatures_log) = channel :: < ~str > ( ) ;
152
145
153
146
// these channels will allow us to talk to each creature by 'name'/index
154
- let mut to_creature: Vec < Sender < Option < CreatureInfo > > > =
155
- set. iter ( ) . enumerate ( ) . map ( |( ii, col) | {
147
+ let mut to_creature: Vec < Sender < CreatureInfo > > =
148
+ set. iter ( ) . enumerate ( ) . map ( |( ii, & col) | {
156
149
// create each creature as a listener with a port, and
157
150
// give us a channel to talk to each
158
- let ii = ii;
159
- let col = * col;
160
151
let to_rendezvous = to_rendezvous. clone ( ) ;
161
152
let to_rendezvous_log = to_rendezvous_log. clone ( ) ;
162
153
let ( to_creature, from_rendezvous) = channel ( ) ;
163
- task :: spawn ( proc ( ) {
154
+ spawn ( proc ( ) {
164
155
creature ( ii,
165
156
col,
166
157
from_rendezvous,
167
- to_rendezvous. clone ( ) ,
168
- to_rendezvous_log. clone ( ) ) ;
158
+ to_rendezvous,
159
+ to_rendezvous_log) ;
169
160
} ) ;
170
161
to_creature
171
162
} ) . collect ( ) ;
@@ -174,55 +165,42 @@ fn rendezvous(nn: uint, set: Vec<color>) {
174
165
175
166
// set up meetings...
176
167
for _ in range ( 0 , nn) {
177
- let mut fst_creature: CreatureInfo = from_creatures. recv ( ) ;
178
- let mut snd_creature: CreatureInfo = from_creatures. recv ( ) ;
168
+ let fst_creature = from_creatures. recv ( ) ;
169
+ let snd_creature = from_creatures. recv ( ) ;
179
170
180
171
creatures_met += 2 ;
181
172
182
- to_creature. get_mut ( fst_creature. name ) . send ( Some ( snd_creature) ) ;
183
- to_creature. get_mut ( snd_creature. name ) . send ( Some ( fst_creature) ) ;
173
+ to_creature. get_mut ( fst_creature. name ) . send ( snd_creature) ;
174
+ to_creature. get_mut ( snd_creature. name ) . send ( fst_creature) ;
184
175
}
185
176
186
177
// tell each creature to stop
187
- for to_one in to_creature. iter ( ) {
188
- to_one. send ( None ) ;
189
- }
190
-
191
- // save each creature's meeting stats
192
- let mut report = Vec :: new ( ) ;
193
- for _to_one in to_creature. iter ( ) {
194
- report. push ( from_creatures_log. recv ( ) ) ;
195
- }
178
+ drop ( to_creature) ;
196
179
197
180
// print each color in the set
198
181
println ! ( "{}" , show_color_list( set) ) ;
199
182
200
183
// print each creature's stats
201
- for rep in report. iter ( ) {
202
- println ! ( "{}" , * rep) ;
184
+ drop ( to_rendezvous_log) ;
185
+ for rep in from_creatures_log. iter ( ) {
186
+ println ! ( "{}" , rep) ;
203
187
}
204
188
205
189
// print the total number of creatures met
206
- println ! ( "{}" , show_number ( creatures_met) ) ;
190
+ println ! ( "{}\n " , Number ( creatures_met) ) ;
207
191
}
208
192
209
193
fn main ( ) {
210
- let args = os:: args ( ) ;
211
- let args = if os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
212
- vec ! ( "" . to_owned( ) , "200000" . to_owned( ) )
213
- } else if args. len ( ) <= 1 u {
214
- vec ! ( "" . to_owned( ) , "600" . to_owned( ) )
194
+ let nn = if std:: os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
195
+ 200000
215
196
} else {
216
- args. move_iter ( ) . collect ( )
197
+ std :: os :: args ( ) . get ( 1 ) . and_then ( |arg| from_str ( * arg ) ) . unwrap_or ( 600 )
217
198
} ;
218
199
219
- let nn = from_str :: < uint > ( * args. get ( 1 ) ) . unwrap ( ) ;
220
-
221
200
print_complements ( ) ;
222
201
println ! ( "" ) ;
223
202
224
203
rendezvous ( nn, vec ! ( Blue , Red , Yellow ) ) ;
225
- println ! ( "" ) ;
226
204
227
205
rendezvous ( nn,
228
206
vec ! ( Blue , Red , Yellow , Red , Yellow , Blue , Red , Yellow , Red , Blue ) ) ;
0 commit comments