1- // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+ // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
22// file at the top-level directory of this distribution and at
33// http://rust-lang.org/COPYRIGHT.
44//
88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- // chameneos
11+ #![ feature( phase) ]
12+ #[ phase( syntax) ] extern crate green;
1213
13- use std:: option;
14- use std:: os;
1514use std:: strbuf:: StrBuf ;
16- use std:: task;
15+ use std:: fmt;
16+
17+ green_start ! ( main)
1718
1819fn print_complements ( ) {
1920 let all = [ Blue , Red , Yellow ] ;
2021 for aa in all. iter ( ) {
2122 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) ) ;
2424 }
2525 }
2626}
2727
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+ }
2939
3040struct CreatureInfo {
3141 name : uint ,
32- color : color
42+ color : Color
3343}
3444
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 {
4446 let mut out = StrBuf :: new ( ) ;
4547 for col in set. iter ( ) {
4648 out. push_char ( ' ' ) ;
47- out. push_str ( show_color ( * col) ) ;
49+ out. push_str ( col. to_str ( ) ) ;
4850 }
4951 out
5052}
5153
5254fn show_digit ( nn : uint ) -> & ' static str {
5355 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" }
6466 _ => { fail ! ( "expected digits from 0 to 9..." ) }
6567 }
6668}
6769
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+ }
8583
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 ( ( ) )
8988 }
90- ret
9189}
9290
93- fn transform ( aa : color , bb : color ) -> color {
91+ fn transform ( aa : Color , bb : Color ) -> Color {
9492 match ( aa, bb) {
9593 ( Red , Red ) => { Red }
9694 ( Red , Yellow ) => { Blue }
@@ -106,23 +104,22 @@ fn transform(aa: color, bb: color) -> color {
106104
107105fn creature (
108106 name : uint ,
109- color : color ,
110- from_rendezvous : Receiver < Option < CreatureInfo > > ,
107+ mut color : Color ,
108+ from_rendezvous : Receiver < CreatureInfo > ,
111109 to_rendezvous : Sender < CreatureInfo > ,
112110 to_rendezvous_log : Sender < ~str >
113111) {
114- let mut color = color;
115112 let mut creatures_met = 0 ;
116113 let mut evil_clones_met = 0 ;
114+ let mut rendezvous = from_rendezvous. iter ( ) ;
117115
118116 loop {
119117 // ask for a pairing
120118 to_rendezvous. send ( CreatureInfo { name : name, color : color} ) ;
121- let resp = from_rendezvous. recv ( ) ;
122119
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) => {
126123 color = transform ( color, other_creature. color ) ;
127124
128125 // track some statistics
@@ -131,41 +128,35 @@ fn creature(
131128 evil_clones_met += 1 ;
132129 }
133130 }
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
141132 }
142133 }
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) ;
143137}
144138
145- fn rendezvous ( nn : uint , set : Vec < color > ) {
146-
139+ fn rendezvous ( nn : uint , set : Vec < Color > ) {
147140 // these ports will allow us to hear from the creatures
148141 let ( to_rendezvous, from_creatures) = channel :: < CreatureInfo > ( ) ;
149- let ( to_rendezvous_log, from_creatures_log) = channel :: < ~str > ( ) ;
150142
151143 // these channels will be passed to the creatures so they can talk to us
144+ let ( to_rendezvous_log, from_creatures_log) = channel :: < ~str > ( ) ;
152145
153146 // 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) | {
156149 // create each creature as a listener with a port, and
157150 // give us a channel to talk to each
158- let ii = ii;
159- let col = * col;
160151 let to_rendezvous = to_rendezvous. clone ( ) ;
161152 let to_rendezvous_log = to_rendezvous_log. clone ( ) ;
162153 let ( to_creature, from_rendezvous) = channel ( ) ;
163- task :: spawn ( proc ( ) {
154+ spawn ( proc ( ) {
164155 creature ( ii,
165156 col,
166157 from_rendezvous,
167- to_rendezvous. clone ( ) ,
168- to_rendezvous_log. clone ( ) ) ;
158+ to_rendezvous,
159+ to_rendezvous_log) ;
169160 } ) ;
170161 to_creature
171162 } ) . collect ( ) ;
@@ -174,55 +165,42 @@ fn rendezvous(nn: uint, set: Vec<color>) {
174165
175166 // set up meetings...
176167 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 ( ) ;
179170
180171 creatures_met += 2 ;
181172
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) ;
184175 }
185176
186177 // 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) ;
196179
197180 // print each color in the set
198181 println ! ( "{}" , show_color_list( set) ) ;
199182
200183 // 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) ;
203187 }
204188
205189 // print the total number of creatures met
206- println ! ( "{}" , show_number ( creatures_met) ) ;
190+ println ! ( "{}\n " , Number ( creatures_met) ) ;
207191}
208192
209193fn 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
215196 } else {
216- args. move_iter ( ) . collect ( )
197+ std :: os :: args ( ) . get ( 1 ) . and_then ( |arg| from_str ( * arg ) ) . unwrap_or ( 600 )
217198 } ;
218199
219- let nn = from_str :: < uint > ( * args. get ( 1 ) ) . unwrap ( ) ;
220-
221200 print_complements ( ) ;
222201 println ! ( "" ) ;
223202
224203 rendezvous ( nn, vec ! ( Blue , Red , Yellow ) ) ;
225- println ! ( "" ) ;
226204
227205 rendezvous ( nn,
228206 vec ! ( Blue , Red , Yellow , Red , Yellow , Blue , Red , Yellow , Red , Blue ) ) ;
0 commit comments