@@ -119,21 +119,46 @@ impl<'borrow_code_lifetime> VM<'borrow_code_lifetime> {
119119 break ;
120120 }
121121 }
122+ self . dump ( ) ;
122123 }
123124 fn step ( & mut self ) -> i32 {
125+
124126 let compiler = Compiler :: new ( ) ;
125127 if self . codes [ self . pc ] == compiler. compile_single ( "OP_0" ) { self . op_pushnumber ( 0 ) ; }
126128 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_1" ) { self . op_pushnumber ( 1 ) ; }
127129 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_2" ) { self . op_pushnumber ( 2 ) ; }
130+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_3" ) { self . op_pushnumber ( 3 ) ; }
131+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_4" ) { self . op_pushnumber ( 4 ) ; }
132+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_5" ) { self . op_pushnumber ( 5 ) ; }
133+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_6" ) { self . op_pushnumber ( 6 ) ; }
134+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_7" ) { self . op_pushnumber ( 7 ) ; }
135+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_8" ) { self . op_pushnumber ( 8 ) ; }
136+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_9" ) { self . op_pushnumber ( 9 ) ; }
137+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_10" ) { self . op_pushnumber ( 10 ) ; }
138+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_11" ) { self . op_pushnumber ( 11 ) ; }
139+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_12" ) { self . op_pushnumber ( 12 ) ; }
140+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_13" ) { self . op_pushnumber ( 13 ) ; }
141+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_14" ) { self . op_pushnumber ( 14 ) ; }
142+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_15" ) { self . op_pushnumber ( 15 ) ; }
143+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_16" ) { self . op_pushnumber ( 16 ) ; }
128144 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_NOP" ) { self . op_nop ( ) ; }
129145 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_DUP" ) { self . op_dup ( ) ; }
130146 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_IF" ) { self . op_if ( ) ; }
131147 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_ENDIF" ) { return 1 ; }
132148 else if self . codes [ self . pc ] == compiler. compile_single ( "OP_ELSE" ) { return 1 ; }
133- else { panic ! ( "[VM] The opcode is not implemented yet," ) ; }
149+ else { panic ! ( "[VM] The opcode {:#x} is not implemented yet," , self . codes [ self . pc ] ) ; }
134150
135151 return 0 ;
136152 }
153+ fn run_nothing ( & mut self ) {
154+ loop {
155+ let compiler = Compiler :: new ( ) ;
156+ if self . codes [ self . pc ] == compiler. compile_single ( "OP_IF" ) { self . op_if ( ) ; }
157+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_ENDIF" ) { break ; }
158+ else if self . codes [ self . pc ] == compiler. compile_single ( "OP_ELSE" ) { break ; }
159+ else { self . pc += 1 ; }
160+ }
161+ }
137162 fn op_pushnumber ( & mut self , num : i32 ) {
138163 self . stack . push ( num) ;
139164 self . pc += 1 ;
@@ -154,41 +179,54 @@ impl<'borrow_code_lifetime> VM<'borrow_code_lifetime> {
154179 }
155180 fn op_if ( & mut self ) {
156181
157- self . pc += 1 ;
158-
159182 let bool = self . stack . pop ( ) ;
160- if bool. unwrap ( ) == 0 { // run from OP_ELSE to OP_END
183+ if bool. unwrap ( ) != 0 { // run from OP_IF to OP_ELSE
161184
162- let mut if_vm = VM :: new ( self . codes , self . stack , self . pc ) ;
185+ // run from next to OP_IF until OP_ELSE or OP_END
186+ let mut if_vm = VM :: new ( self . codes , self . stack , self . pc + 1 ) ;
163187 if_vm. run ( ) ;
164188
165- if self . codes [ self . pc ] == Compiler :: new ( ) . compile_single ( "OP_ELSE" ) {
189+ // check weither OP_ELSE or OP_END
190+ if if_vm. codes [ if_vm. pc ] == Compiler :: new ( ) . compile_single ( "OP_ELSE" ) {
191+ if_vm. pc += 1 ; // first opcode next to OP_ELSE
166192 if_vm. run_nothing ( ) ; // skip from OP_ELSE to OP_ENDIF
167193 }
194+ self . pc = if_vm. pc + 1 ; // get pc at next to OP_END or OP_ELSE
168195
169- } else { // run from OP_IF to OP_ELSE
196+ } else { // run from OP_ELSE to OP_END
170197
171- let mut if_vm = VM :: new ( self . codes , self . stack , self . pc ) ;
172- if_vm. run ( ) ;
198+ // skip from next to OP_IF until OP_ELSE or OP_END
199+ let mut if_vm = VM :: new ( self . codes , self . stack , self . pc + 1 ) ;
200+ if_vm. run_nothing ( ) ;
173201
174- if self . codes [ self . pc ] == Compiler :: new ( ) . compile_single ( "OP_ELSE" ) {
175- let mut if_vm = VM :: new ( self . codes , self . stack , self . pc ) ;
176- if_vm. run_nothing ( ) ; // skip from OP_IF to OP_ELSE
202+ // check weither OP_ELSE or OP_END
203+ if if_vm. codes [ if_vm. pc ] == Compiler :: new ( ) . compile_single ( "OP_ELSE" ) {
204+ if_vm. pc += 1 ; // first opcode next to OP_ELSE
205+ if_vm. run ( ) ; // skip from OP_IF to OP_ELSE
177206 }
207+ self . pc = if_vm. pc + 1 ; // get pc at next to OP_END or OP_ELSE
178208 }
179209
180- //let = self.codes[self.pc - 2];
181- let mut if_code: Vec < i32 > = vec ! [ ] ;
182- let mut else_code: Vec < i32 > = vec ! [ ] ;
183-
184- panic ! ( "debug" ) ;
210+ //panic!("debug");
185211 }
186212}
187213
188214fn main ( ) {
189215
190216 let compiler = Compiler :: new ( ) ;
191- let bytecode = compiler. compile ( vec ! [ "OP_IF" , "OP_1" , "OP_IF" , "OP_2" , "OP_ELSE" , "OP_1" , "OP_ENDIF" , "OP_ELSE" , "OP_3" , "OP_ENDIF" , "OP_1" ] ) ;
217+ let bytecode = compiler. compile ( vec ! [
218+ "OP_1" ,
219+ "OP_IF" ,
220+ "OP_0" ,
221+ "OP_IF" ,
222+ "OP_2" ,
223+ "OP_ELSE" ,
224+ "OP_3" ,
225+ "OP_ENDIF" ,
226+ "OP_ELSE" ,
227+ "OP_4" ,
228+ "OP_ENDIF" ,
229+ "OP_5" ] ) ;
192230
193231 let mut stack: Vec < i32 > = vec ! [ ] ;
194232 let mut vm = VM :: new ( & bytecode, & mut stack, 0 ) ;
0 commit comments