@@ -25,6 +25,7 @@ enum Value {
2525 Float ( f64 ) ,
2626 String ( String ) ,
2727 Bool ( bool ) ,
28+ Range ( i64 , i64 ) ,
2829 Function {
2930 params : Vec < String > ,
3031 body : Vec < Pair < ' static , Rule > > ,
@@ -106,7 +107,7 @@ impl Interpreter {
106107 Value :: Float ( f) => f. to_string ( ) ,
107108 Value :: String ( s) => s,
108109 Value :: Bool ( b) => b. to_string ( ) ,
109- _ => bail ! ( "Cannot print function" ) ,
110+ _ => bail ! ( "Cannot print function or range " ) ,
110111 } ;
111112 if keyword == "println!" || keyword == "writeln" {
112113 println ! ( "{}" , output) ;
@@ -120,7 +121,8 @@ impl Interpreter {
120121 let mut inner = pair. into_inner ( ) ;
121122 let _if = inner. next ( ) ;
122123 let cond_pair = inner. next ( ) . unwrap ( ) ;
123- let cond = self . eval_as_bool ( self . eval_expr ( cond_pair) ?) ?;
124+ let value = self . eval_expr ( cond_pair) ?;
125+ let cond = self . eval_as_bool ( value) ?;
124126 let then_block = inner. next ( ) . unwrap ( ) ;
125127 let else_block_opt = inner. next ( ) ;
126128 if cond {
@@ -139,7 +141,8 @@ impl Interpreter {
139141 let count_opt = inner. next ( ) ;
140142 let block = inner. next ( ) . unwrap ( ) ;
141143 if let Some ( count_pair) = count_opt {
142- let count = self . eval_as_int ( self . eval_expr ( count_pair) ?) ? as usize ;
144+ let value = self . eval_expr ( count_pair) ?;
145+ let count = self . eval_as_int ( value) ? as usize ;
143146 for _ in 0 ..count {
144147 self . exec_block ( block. clone ( ) ) ?;
145148 }
@@ -152,7 +155,12 @@ impl Interpreter {
152155 "while" => {
153156 let cond_pair = inner. next ( ) . unwrap ( ) ;
154157 let block = inner. next ( ) . unwrap ( ) ;
155- while self . eval_as_bool ( self . eval_expr ( cond_pair. clone ( ) ) ?) ? {
158+ loop {
159+ let value = self . eval_expr ( cond_pair. clone ( ) ) ?;
160+ let cond = self . eval_as_bool ( value) ?;
161+ if !cond {
162+ break ;
163+ }
156164 self . exec_block ( block. clone ( ) ) ?;
157165 }
158166 }
@@ -161,17 +169,14 @@ impl Interpreter {
161169 let _in = inner. next ( ) ;
162170 let range_expr = inner. next ( ) . unwrap ( ) ;
163171 let block = inner. next ( ) . unwrap ( ) ;
164- let range_str = range_expr. as_str ( ) ;
165- if range_str. contains ( ".." ) {
166- let parts: Vec < & str > = range_str. split ( ".." ) . collect ( ) ;
167- let start = parts[ 0 ] . parse :: < i64 > ( ) . unwrap_or ( 0 ) ;
168- let end = parts[ 1 ] . parse :: < i64 > ( ) . unwrap_or ( 0 ) ;
172+ let range = self . eval_expr ( range_expr) ?;
173+ if let Value :: Range ( start, end) = range {
169174 for i in start..end {
170175 self . variables . insert ( ident. clone ( ) , Value :: Int ( i) ) ;
171176 self . exec_block ( block. clone ( ) ) ?;
172177 }
173178 } else {
174- bail ! ( "Unsupported for range" ) ;
179+ bail ! ( "For range must be a range" ) ;
175180 }
176181 }
177182 _ => bail ! ( "Unknown loop" ) ,
@@ -250,6 +255,16 @@ impl Interpreter {
250255
251256 fn eval_expr ( & mut self , pair : Pair < ' static , Rule > ) -> Result < Value > {
252257 match pair. as_rule ( ) {
258+ Rule :: range => {
259+ let mut inner = pair. into_inner ( ) ;
260+ let start_pair = inner. next ( ) . unwrap ( ) ;
261+ let end_pair = inner. next ( ) . unwrap ( ) ;
262+ let start_val = self . eval_expr ( start_pair) ?;
263+ let end_val = self . eval_expr ( end_pair) ?;
264+ let start = self . eval_as_int ( start_val) ?;
265+ let end = self . eval_as_int ( end_val) ?;
266+ Ok ( Value :: Range ( start, end) )
267+ }
253268 Rule :: logic_expr => self . eval_logic ( pair. into_inner ( ) ) ,
254269 Rule :: compare_expr => self . eval_compare ( pair. into_inner ( ) ) ,
255270 Rule :: arith_expr => self . eval_arith ( pair. into_inner ( ) ) ,
@@ -277,7 +292,8 @@ impl Interpreter {
277292 Rule :: unary => {
278293 let mut unary_inner = inner_pair. into_inner ( ) ;
279294 let op = unary_inner. next ( ) . unwrap ( ) . as_str ( ) ;
280- let factor = self . eval_expr ( unary_inner. next ( ) . unwrap ( ) ) ?;
295+ let factor_pair = unary_inner. next ( ) . unwrap ( ) ;
296+ let factor = self . eval_expr ( factor_pair) ?;
281297 match op {
282298 "-" => match factor {
283299 Value :: Int ( n) => Ok ( Value :: Int ( -n) ) ,
0 commit comments